Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (59 commits)
  V4L/DVB (7219): zoran: Fix namespace conflicts with Zoran 'GPIO_MAX' enum
  V4L/DVB (7205): tuner-xc2028 depends on FW_LOADER
  V4L/DVB (7201): cx88-mpeg: Fix race condition in variable access
  V4L/DVB (7200): Fix FM firmware loading
  V4L/DVB (7198): V4L, include ioctl.h in videodev headers
  V4L/DVB (7197): bttv: Fix overlay divide error
  V4L/DVB (7195): xc5000: fix build error when built as module
  V4L/DVB (7194): cx88-mpeg: Allow concurrent access to cx88-mpeg devices
  V4L/DVB (7193): tveeprom: Add proper tuner mapping for hauppauge eeprom id 133
  V4L/DVB (7192): Adds support for Genius TVGo A11MCE
  V4L/DVB (7189): autosuspend support
  V4L/DVB (7188): radio-si470x version 1.0.6
  V4L/DVB (7186): tda10086: make the 22kHz tone for DISEQC a config option
  V4L/DVB (7183): radio-si470x: fix build warning
  V4L/DVB (7180): em28xx: add URB_NO_TRANSFER_DMA_MAP, since urb->transfer_dma is set
  V4L/DVB (7179): Allow more than one em28xx board
  V4L/DVB (7164): em28xx-alsa: Add a missing mutex
  V4L/DVB (7163): em28xx: makes audio settings more stable
  V4L/DVB (7162): em28xx: Fix endian and returns the correct values
  V4L/DVB (7161): em28xx: Fix printing debug values higher than 127
  ...
Linus Torvalds 17 years ago
parent
commit
20ef0f1ad0
61 changed files with 1456 additions and 926 deletions
  1. 1 1
      Documentation/video4linux/CARDLIST.em28xx
  2. 4 2
      Documentation/video4linux/CARDLIST.saa7134
  3. 3 1
      Documentation/video4linux/zr364xx.txt
  4. 11 7
      drivers/media/Kconfig
  5. 1 1
      drivers/media/common/Kconfig
  6. 46 0
      drivers/media/common/ir-keymaps.c
  7. 0 1
      drivers/media/common/saa7146_vbi.c
  8. 0 2
      drivers/media/common/saa7146_video.c
  9. 14 9
      drivers/media/dvb/bt8xx/bt878.c
  10. 1 0
      drivers/media/dvb/dvb-usb/ttusb2.c
  11. 22 6
      drivers/media/dvb/frontends/tda10086.c
  12. 3 0
      drivers/media/dvb/frontends/tda10086.h
  13. 1 1
      drivers/media/dvb/frontends/tda18271-common.c
  14. 2 1
      drivers/media/dvb/frontends/xc5000.h
  15. 14 1
      drivers/media/dvb/ttpci/av7110_av.c
  16. 8 0
      drivers/media/dvb/ttpci/budget-av.c
  17. 1 0
      drivers/media/dvb/ttpci/budget.c
  18. 2 2
      drivers/media/radio/Kconfig
  19. 1 0
      drivers/media/radio/radio-sf16fmi.c
  20. 2 3
      drivers/media/radio/radio-sf16fmr2.c
  21. 365 232
      drivers/media/radio/radio-si470x.c
  22. 2 2
      drivers/media/video/Kconfig
  23. 3 2
      drivers/media/video/Makefile
  24. 25 26
      drivers/media/video/bt8xx/bttv-driver.c
  25. 2 2
      drivers/media/video/bt8xx/bttv-vbi.c
  26. 12 4
      drivers/media/video/cx88/cx88-mpeg.c
  27. 1 0
      drivers/media/video/cx88/cx88.h
  28. 5 1
      drivers/media/video/em28xx/em28xx-audio.c
  29. 5 3
      drivers/media/video/em28xx/em28xx-cards.c
  30. 69 42
      drivers/media/video/em28xx/em28xx-core.c
  31. 72 7
      drivers/media/video/em28xx/em28xx-video.c
  32. 1 4
      drivers/media/video/em28xx/em28xx.h
  33. 111 12
      drivers/media/video/saa7134/saa7134-cards.c
  34. 24 4
      drivers/media/video/saa7134/saa7134-dvb.c
  35. 2 4
      drivers/media/video/saa7134/saa7134-empress.c
  36. 6 0
      drivers/media/video/saa7134/saa7134-input.c
  37. 10 10
      drivers/media/video/saa7134/saa7134-video.c
  38. 2 0
      drivers/media/video/saa7134/saa7134.h
  39. 20 3
      drivers/media/video/stk-sensor.c
  40. 82 22
      drivers/media/video/stk-webcam.c
  41. 1 2
      drivers/media/video/stk-webcam.h
  42. 1 1
      drivers/media/video/tcm825x.c
  43. 1 1
      drivers/media/video/tuner-core.c
  44. 3 0
      drivers/media/video/tuner-xc2028.c
  45. 5 5
      drivers/media/video/tvaudio.c
  46. 1 1
      drivers/media/video/tveeprom.c
  47. 27 366
      drivers/media/video/v4l2-common.c
  48. 39 39
      drivers/media/video/videobuf-core.c
  49. 2 2
      drivers/media/video/videobuf-dma-sg.c
  50. 9 11
      drivers/media/video/videobuf-vmalloc.c
  51. 385 59
      drivers/media/video/videodev.c
  52. 11 11
      drivers/media/video/zoran.h
  53. 6 6
      drivers/media/video/zoran_device.c
  54. 2 0
      drivers/media/video/zr364xx.c
  55. 1 0
      include/linux/videodev.h
  56. 1 0
      include/linux/videodev2.h
  57. 1 0
      include/media/ir-common.h
  58. 0 2
      include/media/v4l2-common.h
  59. 2 0
      include/media/v4l2-dev.h
  60. 1 1
      include/media/videobuf-core.h
  61. 1 1
      include/media/videobuf-vmalloc.h

+ 1 - 1
Documentation/video4linux/CARDLIST.em28xx

@@ -8,7 +8,7 @@
   7 -> Leadtek Winfast USB II                   (em2800)
   7 -> Leadtek Winfast USB II                   (em2800)
   8 -> Kworld USB2800                           (em2800)
   8 -> Kworld USB2800                           (em2800)
   9 -> Pinnacle Dazzle DVC 90/DVC 100           (em2820/em2840) [2304:0207,2304:021a]
   9 -> Pinnacle Dazzle DVC 90/DVC 100           (em2820/em2840) [2304:0207,2304:021a]
- 10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
+ 10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500,2040:6502]
  11 -> Terratec Hybrid XS                       (em2880)        [0ccd:0042]
  11 -> Terratec Hybrid XS                       (em2880)        [0ccd:0042]
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]

+ 4 - 2
Documentation/video4linux/CARDLIST.saa7134

@@ -92,9 +92,9 @@
  91 -> AVerMedia A169 B                         [1461:7360]
  91 -> AVerMedia A169 B                         [1461:7360]
  92 -> AVerMedia A169 B1                        [1461:6360]
  92 -> AVerMedia A169 B1                        [1461:6360]
  93 -> Medion 7134 Bridge #2                    [16be:0005]
  93 -> Medion 7134 Bridge #2                    [16be:0005]
- 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
+ 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502]
  95 -> LifeView FlyVIDEO3000 (NTSC)             [5169:0138]
  95 -> LifeView FlyVIDEO3000 (NTSC)             [5169:0138]
- 96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008]
+ 96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008,16be:000d]
  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
  98 -> Proteus Pro 2309                         [0919:2003]
  98 -> Proteus Pro 2309                         [0919:2003]
  99 -> AVerMedia TV Hybrid A16AR                [1461:2c00]
  99 -> AVerMedia TV Hybrid A16AR                [1461:2c00]
@@ -129,3 +129,5 @@
 128 -> Beholder BeholdTV Columbus TVFM          [0000:5201]
 128 -> Beholder BeholdTV Columbus TVFM          [0000:5201]
 129 -> Beholder BeholdTV 607 / BeholdTV 609     [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
 129 -> Beholder BeholdTV 607 / BeholdTV 609     [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
+131 -> Twinhan Hybrid DTV-DVB 3056 PCI          [1822:0022]
+132 -> Genius TVGO AM11MCE

+ 3 - 1
Documentation/video4linux/zr364xx.txt

@@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y
  - debug      : set to 1 to enable verbose debug messages
  - debug      : set to 1 to enable verbose debug messages
  - mode       : 0 = 320x240, 1 = 160x120, 2 = 640x480
  - mode       : 0 = 320x240, 1 = 160x120, 2 = 640x480
 You can then use the camera with V4L2 compatible applications, for example Ekiga.
 You can then use the camera with V4L2 compatible applications, for example Ekiga.
-To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
+To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1
 
 
 links :
 links :
 http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
 http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
@@ -63,3 +63,5 @@ Vendor  Product  Distributor     Model
 0x06d6  0x0034   Trust           Powerc@m 750
 0x06d6  0x0034   Trust           Powerc@m 750
 0x0a17  0x0062   Pentax          Optio 50L
 0x0a17  0x0062   Pentax          Optio 50L
 0x06d6  0x003b   Trust           Powerc@m 970Z
 0x06d6  0x003b   Trust           Powerc@m 970Z
+0x0a17  0x004e   Pentax          Optio 50
+0x041e  0x405d   Creative        DiVi CAM 516

+ 11 - 7
drivers/media/Kconfig

@@ -25,11 +25,16 @@ config VIDEO_DEV
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called videodev.
 	  module will be called videodev.
 
 
+config VIDEO_V4L2_COMMON
+	tristate
+	depends on (I2C || I2C=n) && VIDEO_DEV
+	default (I2C || I2C=n) && VIDEO_DEV
+
 config VIDEO_V4L1
 config VIDEO_V4L1
 	bool "Enable Video For Linux API 1 (DEPRECATED)"
 	bool "Enable Video For Linux API 1 (DEPRECATED)"
-	depends on VIDEO_DEV
+	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
+	default VIDEO_DEV && VIDEO_V4L2_COMMON
 	select VIDEO_V4L1_COMPAT
 	select VIDEO_V4L1_COMPAT
-	default y
 	---help---
 	---help---
 	  Enables a compatibility API used by most V4L2 devices to allow
 	  Enables a compatibility API used by most V4L2 devices to allow
 	  its usage with legacy applications that supports only V4L1 api.
 	  its usage with legacy applications that supports only V4L1 api.
@@ -39,7 +44,7 @@ config VIDEO_V4L1
 config VIDEO_V4L1_COMPAT
 config VIDEO_V4L1_COMPAT
 	bool "Enable Video For Linux API 1 compatible Layer"
 	bool "Enable Video For Linux API 1 compatible Layer"
 	depends on VIDEO_DEV
 	depends on VIDEO_DEV
-	default y
+	default VIDEO_DEV
 	---help---
 	---help---
 	  This api were developed to be used at Kernel 2.2 and 2.4, but
 	  This api were developed to be used at Kernel 2.2 and 2.4, but
 	  lacks support for several video standards. There are several
 	  lacks support for several video standards. There are several
@@ -55,8 +60,8 @@ config VIDEO_V4L1_COMPAT
 
 
 config VIDEO_V4L2
 config VIDEO_V4L2
 	bool
 	bool
-	depends on VIDEO_DEV
-	default y
+	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
+	default VIDEO_DEV && VIDEO_V4L2_COMMON
 
 
 source "drivers/media/video/Kconfig"
 source "drivers/media/video/Kconfig"
 
 
@@ -93,7 +98,7 @@ if VIDEO_TUNER_CUSTOMIZE
 
 
 config TUNER_XC2028
 config TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
 	tristate "XCeive xc2028/xc3028 tuners"
-	depends on I2C
+	depends on I2C && FW_LOADER
 	default m if VIDEO_TUNER_CUSTOMIZE
 	default m if VIDEO_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for the xc2028/xc3028 tuners.
 	  Say Y here to include support for the xc2028/xc3028 tuners.
@@ -180,7 +185,6 @@ config VIDEO_TVEEPROM
 
 
 config DAB
 config DAB
 	boolean "DAB adapters"
 	boolean "DAB adapters"
-	default y
 	---help---
 	---help---
 	  Allow selecting support for for Digital Audio Broadcasting (DAB)
 	  Allow selecting support for for Digital Audio Broadcasting (DAB)
 	  Receiver adapters.
 	  Receiver adapters.

+ 1 - 1
drivers/media/common/Kconfig

@@ -4,6 +4,6 @@ config VIDEO_SAA7146
 
 
 config VIDEO_SAA7146_VV
 config VIDEO_SAA7146_VV
 	tristate
 	tristate
-	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
 	select VIDEOBUF_DMA_SG
 	select VIDEOBUF_DMA_SG
 	select VIDEO_SAA7146
 	select VIDEO_SAA7146

+ 46 - 0
drivers/media/common/ir-keymaps.c

@@ -1987,3 +1987,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
 };
 };
 
 
 EXPORT_SYMBOL_GPL(ir_codes_behold);
 EXPORT_SYMBOL_GPL(ir_codes_behold);
+
+/*
+ * Remote control for the Genius TVGO A11MCE
+ * Adrian Pardini <pardo.bsso@gmail.com>
+ */
+IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
+	/* Keys 0 to 9 */
+	[0x48] = KEY_0,
+	[0x09] = KEY_1,
+	[0x1d] = KEY_2,
+	[0x1f] = KEY_3,
+	[0x19] = KEY_4,
+	[0x1b] = KEY_5,
+	[0x11] = KEY_6,
+	[0x17] = KEY_7,
+	[0x12] = KEY_8,
+	[0x16] = KEY_9,
+
+	[0x54] = KEY_RECORD,		/* recording */
+	[0x06] = KEY_MUTE,		/* mute */
+	[0x10] = KEY_POWER,
+	[0x40] = KEY_LAST,		/* recall */
+	[0x4c] = KEY_CHANNELUP,		/* channel / program + */
+	[0x00] = KEY_CHANNELDOWN,	/* channel / program - */
+	[0x0d] = KEY_VOLUMEUP,
+	[0x15] = KEY_VOLUMEDOWN,
+	[0x4d] = KEY_OK,		/* also labeled as Pause */
+	[0x1c] = KEY_ZOOM,		/* full screen and Stop*/
+	[0x02] = KEY_MODE,		/* AV Source or Rewind*/
+	[0x04] = KEY_LIST,		/* -/-- */
+	/* small arrows above numbers */
+	[0x1a] = KEY_NEXT,		/* also Fast Forward */
+	[0x0e] = KEY_PREVIOUS,	/* also Rewind */
+	/* these are in a rather non standard layout and have
+	an alternate name written */
+	[0x1e] = KEY_UP,		/* Video Setting */
+	[0x0a] = KEY_DOWN,		/* Video Default */
+	[0x05] = KEY_LEFT,		/* Snapshot */
+	[0x0c] = KEY_RIGHT,		/* Hide Panel */
+	/* Four buttons without label */
+	[0x49] = KEY_RED,
+	[0x0b] = KEY_GREEN,
+	[0x13] = KEY_YELLOW,
+	[0x50] = KEY_BLUE,
+};
+EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);

+ 0 - 1
drivers/media/common/saa7146_vbi.c

@@ -413,7 +413,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 			    sizeof(struct saa7146_buf),
 			    sizeof(struct saa7146_buf),
 			    file);
 			    file);
-	mutex_init(&fh->vbi_q.lock);
 
 
 	init_timer(&fh->vbi_read_timeout);
 	init_timer(&fh->vbi_read_timeout);
 	fh->vbi_read_timeout.function = vbi_read_timeout;
 	fh->vbi_read_timeout.function = vbi_read_timeout;

+ 0 - 2
drivers/media/common/saa7146_video.c

@@ -1417,8 +1417,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
 			    sizeof(struct saa7146_buf),
 			    sizeof(struct saa7146_buf),
 			    file);
 			    file);
 
 
-	mutex_init(&fh->video_q.lock);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 14 - 9
drivers/media/dvb/bt8xx/bt878.c

@@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878);
 #if defined(dprintk)
 #if defined(dprintk)
 #undef dprintk
 #undef dprintk
 #endif
 #endif
-#define dprintk if(bt878_debug) printk
+#define dprintk(fmt, arg...) \
+	do { \
+		if (bt878_debug) \
+			printk(KERN_DEBUG fmt, ##arg); \
+	} while (0)
 
 
 static void bt878_mem_free(struct bt878 *bt)
 static void bt878_mem_free(struct bt878 *bt)
 {
 {
@@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt)
 	}
 	}
 
 
 	if (bt->line_count > 255) {
 	if (bt->line_count > 255) {
-		printk("bt878: buffer size error!\n");
+		printk(KERN_ERR "bt878: buffer size error!\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	return 0;
 	return 0;
@@ -285,7 +289,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
 
 
 		if (astat & (BT878_ASCERR | BT878_AOCERR)) {
 		if (astat & (BT878_ASCERR | BT878_AOCERR)) {
 			if (bt878_verbose) {
 			if (bt878_verbose) {
-				printk("bt878(%d): irq%s%s risc_pc=%08x\n",
+				printk(KERN_INFO
+				       "bt878(%d): irq%s%s risc_pc=%08x\n",
 				       bt->nr,
 				       bt->nr,
 				       (astat & BT878_ASCERR) ? " SCERR" :
 				       (astat & BT878_ASCERR) ? " SCERR" :
 				       "",
 				       "",
@@ -295,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
 		}
 		}
 		if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
 		if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
 			if (bt878_verbose) {
 			if (bt878_verbose) {
-				printk
-				    ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
+				printk(KERN_INFO
+				     "bt878(%d): irq%s%s%s risc_pc=%08x\n",
 				     bt->nr,
 				     bt->nr,
 				     (astat & BT878_APABORT) ? " PABORT" :
 				     (astat & BT878_APABORT) ? " PABORT" :
 				     "",
 				     "",
@@ -308,8 +313,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
 		}
 		}
 		if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
 		if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
 			if (bt878_verbose) {
 			if (bt878_verbose) {
-				printk
-				    ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
+				printk(KERN_INFO
+				     "bt878(%d): irq%s%s%s risc_pc=%08x\n",
 				     bt->nr,
 				     bt->nr,
 				     (astat & BT878_AFDSR) ? " FDSR" : "",
 				     (astat & BT878_AFDSR) ? " FDSR" : "",
 				     (astat & BT878_AFTRGT) ? " FTRGT" :
 				     (astat & BT878_AFTRGT) ? " FTRGT" :
@@ -510,7 +515,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
 */
 */
 
 
 	if ((result = bt878_mem_alloc(bt))) {
 	if ((result = bt878_mem_alloc(bt))) {
-		printk("bt878: failed to allocate memory!\n");
+		printk(KERN_ERR "bt878: failed to allocate memory!\n");
 		goto fail2;
 		goto fail2;
 	}
 	}
 
 
@@ -536,7 +541,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev)
 	struct bt878 *bt = pci_get_drvdata(pci_dev);
 	struct bt878 *bt = pci_get_drvdata(pci_dev);
 
 
 	if (bt878_verbose)
 	if (bt878_verbose)
-		printk("bt878(%d): unloading\n", bt->nr);
+		printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
 
 
 	/* turn off all capturing, DMA and IRQs */
 	/* turn off all capturing, DMA and IRQs */
 	btand(~0x13, BT878_AGPIO_DMA_CTL);
 	btand(~0x13, BT878_AGPIO_DMA_CTL);

+ 1 - 0
drivers/media/dvb/dvb-usb/ttusb2.c

@@ -144,6 +144,7 @@ static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
 static struct tda10086_config tda10086_config = {
 static struct tda10086_config tda10086_config = {
 	.demod_address = 0x0e,
 	.demod_address = 0x0e,
 	.invert = 0,
 	.invert = 0,
+	.diseqc_tone = 1,
 };
 };
 
 
 static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
 static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)

+ 22 - 6
drivers/media/dvb/frontends/tda10086.c

@@ -106,9 +106,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask,
 static int tda10086_init(struct dvb_frontend* fe)
 static int tda10086_init(struct dvb_frontend* fe)
 {
 {
 	struct tda10086_state* state = fe->demodulator_priv;
 	struct tda10086_state* state = fe->demodulator_priv;
+	u8 t22k_off = 0x80;
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
+	if (state->config->diseqc_tone)
+		t22k_off = 0;
 	// reset
 	// reset
 	tda10086_write_byte(state, 0x00, 0x00);
 	tda10086_write_byte(state, 0x00, 0x00);
 	msleep(10);
 	msleep(10);
@@ -158,7 +161,7 @@ static int tda10086_init(struct dvb_frontend* fe)
 	tda10086_write_byte(state, 0x3d, 0x80);
 	tda10086_write_byte(state, 0x3d, 0x80);
 
 
 	// setup SEC
 	// setup SEC
-	tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone
+	tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone
 	tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));      // } tone frequency
 	tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));      // } tone frequency
 	tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
 	tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
 
 
@@ -180,16 +183,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state)
 static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
 {
 	struct tda10086_state* state = fe->demodulator_priv;
 	struct tda10086_state* state = fe->demodulator_priv;
+	u8 t22k_off = 0x80;
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
+	if (state->config->diseqc_tone)
+		t22k_off = 0;
+
 	switch (tone) {
 	switch (tone) {
 	case SEC_TONE_OFF:
 	case SEC_TONE_OFF:
-		tda10086_write_byte(state, 0x36, 0x80);
+		tda10086_write_byte(state, 0x36, t22k_off);
 		break;
 		break;
 
 
 	case SEC_TONE_ON:
 	case SEC_TONE_ON:
-		tda10086_write_byte(state, 0x36, 0x81);
+		tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
 		break;
 		break;
 	}
 	}
 
 
@@ -202,9 +209,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
 	struct tda10086_state* state = fe->demodulator_priv;
 	struct tda10086_state* state = fe->demodulator_priv;
 	int i;
 	int i;
 	u8 oldval;
 	u8 oldval;
+	u8 t22k_off = 0x80;
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
+	if (state->config->diseqc_tone)
+		t22k_off = 0;
+
 	if (cmd->msg_len > 6)
 	if (cmd->msg_len > 6)
 		return -EINVAL;
 		return -EINVAL;
 	oldval = tda10086_read_byte(state, 0x36);
 	oldval = tda10086_read_byte(state, 0x36);
@@ -212,7 +223,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
 	for(i=0; i< cmd->msg_len; i++) {
 	for(i=0; i< cmd->msg_len; i++) {
 		tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
 		tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
 	}
 	}
-	tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4));
+	tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
+					| ((cmd->msg_len - 1) << 4));
 
 
 	tda10086_diseqc_wait(state);
 	tda10086_diseqc_wait(state);
 
 
@@ -225,16 +237,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic
 {
 {
 	struct tda10086_state* state = fe->demodulator_priv;
 	struct tda10086_state* state = fe->demodulator_priv;
 	u8 oldval = tda10086_read_byte(state, 0x36);
 	u8 oldval = tda10086_read_byte(state, 0x36);
+	u8 t22k_off = 0x80;
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
+	if (state->config->diseqc_tone)
+		t22k_off = 0;
+
 	switch(minicmd) {
 	switch(minicmd) {
 	case SEC_MINI_A:
 	case SEC_MINI_A:
-		tda10086_write_byte(state, 0x36, 0x84);
+		tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
 		break;
 		break;
 
 
 	case SEC_MINI_B:
 	case SEC_MINI_B:
-		tda10086_write_byte(state, 0x36, 0x86);
+		tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
 		break;
 		break;
 	}
 	}
 
 

+ 3 - 0
drivers/media/dvb/frontends/tda10086.h

@@ -33,6 +33,9 @@ struct tda10086_config
 
 
 	/* does the "inversion" need inverted? */
 	/* does the "inversion" need inverted? */
 	u8 invert;
 	u8 invert;
+
+	/* do we need the diseqc signal with carrier? */
+	u8 diseqc_tone;
 };
 };
 
 
 #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
 #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))

+ 1 - 1
drivers/media/dvb/frontends/tda18271-common.c

@@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe)
 	if (ret != 2)
 	if (ret != 2)
 		tda_err("ERROR: i2c_transfer returned: %d\n", ret);
 		tda_err("ERROR: i2c_transfer returned: %d\n", ret);
 
 
-	for (i = 0; i <= TDA18271_NUM_REGS; i++) {
+	for (i = 0; i < TDA18271_NUM_REGS; i++) {
 		/* don't update write-only registers */
 		/* don't update write-only registers */
 		if ((i != R_EB9)  &&
 		if ((i != R_EB9)  &&
 		    (i != R_EB16) &&
 		    (i != R_EB16) &&

+ 2 - 1
drivers/media/dvb/frontends/xc5000.h

@@ -45,7 +45,8 @@ struct xc5000_config {
 /* xc5000 callback command */
 /* xc5000 callback command */
 #define XC5000_TUNER_RESET		0
 #define XC5000_TUNER_RESET		0
 
 
-#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
+#if defined(CONFIG_DVB_TUNER_XC5000) || \
+    (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE))
 extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 					  struct i2c_adapter *i2c,
 					  struct i2c_adapter *i2c,
 					  struct xc5000_config *cfg);
 					  struct xc5000_config *cfg);

+ 14 - 1
drivers/media/dvb/ttpci/av7110_av.c

@@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
 static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
 static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
 {
 {
 	int i, n;
 	int i, n;
+	int progressive = 0;
 
 
 	dprintk(2, "av7110:%p, \n", av7110);
 	dprintk(2, "av7110:%p, \n", av7110);
 
 
@@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
 			return -EBUSY;
 			return -EBUSY;
 	}
 	}
 
 
+	for (i = 0; i < len - 5; i++) {
+		/* get progressive flag from picture extension */
+		if (buf[i] == 0x00 && buf[i+1] == 0x00 &&
+		    buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 &&
+		    (buf[i+4] & 0xf0) == 0x10)
+			progressive = buf[i+5] & 0x08;
+	}
+
 	/* setting n always > 1, fixes problems when playing stillframes
 	/* setting n always > 1, fixes problems when playing stillframes
 	   consisting of I- and P-Frames */
 	   consisting of I- and P-Frames */
 	n = MIN_IFRAME / len + 1;
 	n = MIN_IFRAME / len + 1;
@@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
 		dvb_play(av7110, buf, len, 0, 1);
 		dvb_play(av7110, buf, len, 0, 1);
 
 
 	av7110_ipack_flush(&av7110->ipack[1]);
 	av7110_ipack_flush(&av7110->ipack[1]);
-	return 0;
+
+	if (progressive)
+		return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
+	else
+		return 0;
 }
 }
 
 
 
 

+ 8 - 0
drivers/media/dvb/ttpci/budget-av.c

@@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av)
 #define SUBID_DVBS_CINERGY1200		0x1154
 #define SUBID_DVBS_CINERGY1200		0x1154
 #define SUBID_DVBS_CYNERGY1200N 	0x1155
 #define SUBID_DVBS_CYNERGY1200N 	0x1155
 #define SUBID_DVBS_TV_STAR		0x0014
 #define SUBID_DVBS_TV_STAR		0x0014
+#define SUBID_DVBS_TV_STAR_PLUS_X4	0x0015
 #define SUBID_DVBS_TV_STAR_CI		0x0016
 #define SUBID_DVBS_TV_STAR_CI		0x0016
 #define SUBID_DVBS_EASYWATCH_1  	0x001a
 #define SUBID_DVBS_EASYWATCH_1  	0x001a
 #define SUBID_DVBS_EASYWATCH_2  	0x001b
 #define SUBID_DVBS_EASYWATCH_2  	0x001b
@@ -910,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av)
 #define SUBID_DVBC_CINERGY1200		0x1156
 #define SUBID_DVBC_CINERGY1200		0x1156
 #define SUBID_DVBC_CINERGY1200_MK3	0x1176
 #define SUBID_DVBC_CINERGY1200_MK3	0x1176
 
 
+#define SUBID_DVBT_EASYWATCH		0x003a
 #define SUBID_DVBT_KNC1_PLUS		0x0031
 #define SUBID_DVBT_KNC1_PLUS		0x0031
 #define SUBID_DVBT_KNC1			0x0030
 #define SUBID_DVBT_KNC1			0x0030
 #define SUBID_DVBT_CINERGY1200		0x1157
 #define SUBID_DVBT_CINERGY1200		0x1157
@@ -957,6 +959,7 @@ static void frontend_init(struct budget_av *budget_av)
 		break;
 		break;
 
 
 	case SUBID_DVBS_TV_STAR:
 	case SUBID_DVBS_TV_STAR:
+	case SUBID_DVBS_TV_STAR_PLUS_X4:
 	case SUBID_DVBS_TV_STAR_CI:
 	case SUBID_DVBS_TV_STAR_CI:
 	case SUBID_DVBS_CYNERGY1200N:
 	case SUBID_DVBS_CYNERGY1200N:
 	case SUBID_DVBS_EASYWATCH:
 	case SUBID_DVBS_EASYWATCH:
@@ -1018,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av)
 		}
 		}
 		break;
 		break;
 
 
+	case SUBID_DVBT_EASYWATCH:
 	case SUBID_DVBT_KNC1:
 	case SUBID_DVBT_KNC1:
 	case SUBID_DVBT_KNC1_PLUS:
 	case SUBID_DVBT_KNC1_PLUS:
 	case SUBID_DVBT_CINERGY1200:
 	case SUBID_DVBT_CINERGY1200:
@@ -1248,7 +1252,9 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
+MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
@@ -1266,12 +1272,14 @@ static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
 	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
 	MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
 	MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
+	MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
 	MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
 	MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
 	MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
 	MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
 	MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
 	MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
 	MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
 	MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
 	MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
 	MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
+	MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
 	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
 	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
 	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
 	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
 	MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
 	MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),

+ 1 - 0
drivers/media/dvb/ttpci/budget.c

@@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = {
 static struct tda10086_config tda10086_config = {
 static struct tda10086_config tda10086_config = {
 	.demod_address = 0x0e,
 	.demod_address = 0x0e,
 	.invert = 0,
 	.invert = 0,
+	.diseqc_tone = 1,
 };
 };
 
 
 static u8 read_pwm(struct budget* budget)
 static u8 read_pwm(struct budget* budget)

+ 2 - 2
drivers/media/radio/Kconfig

@@ -4,12 +4,12 @@
 
 
 menuconfig RADIO_ADAPTERS
 menuconfig RADIO_ADAPTERS
 	bool "Radio Adapters"
 	bool "Radio Adapters"
-	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
 	default y
 	default y
 	---help---
 	---help---
 	  Say Y here to enable selecting AM/FM radio adapters.
 	  Say Y here to enable selecting AM/FM radio adapters.
 
 
-if RADIO_ADAPTERS && VIDEO_DEV
+if RADIO_ADAPTERS && VIDEO_V4L2
 
 
 config RADIO_CADET
 config RADIO_CADET
 	tristate "ADS Cadet AM/FM Tuner"
 	tristate "ADS Cadet AM/FM Tuner"

+ 1 - 0
drivers/media/radio/radio-sf16fmi.c

@@ -361,6 +361,7 @@ static int __init fmi_init(void)
 	}
 	}
 	if (!request_region(io, 2, "radio-sf16fmi")) {
 	if (!request_region(io, 2, "radio-sf16fmi")) {
 		printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
 		printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
+		pnp_device_detach(dev);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 
 

+ 2 - 3
drivers/media/radio/radio-sf16fmr2.c

@@ -470,9 +470,8 @@ static int __init fmr2_init(void)
 
 
 	mutex_init(&lock);
 	mutex_init(&lock);
 
 
-	if (request_region(io, 2, "sf16fmr2"))
-	{
-		printk(KERN_ERR "fmr2: port 0x%x already in use\n", io);
+	if (!request_region(io, 2, "sf16fmr2")) {
+		printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 
 

+ 365 - 232
drivers/media/radio/radio-si470x.c

@@ -62,6 +62,29 @@
  *		- code cleaned of unnecessary rds_commands
  *		- code cleaned of unnecessary rds_commands
  *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
  *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
  *		  (thanks to Guillaume RAMOUSSE)
  *		  (thanks to Guillaume RAMOUSSE)
+ * 2008-01-27	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.5
+ *		- number of seek_retries changed to tune_timeout
+ *		- fixed problem with incomplete tune operations by own buffers
+ *		- optimization of variables and printf types
+ *		- improved error logging
+ * 2008-01-31	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Oliver Neukum <oliver@neukum.org>
+ *		Version 1.0.6
+ *		- fixed coverity checker warnings in *_usb_driver_disconnect
+ *		- probe()/open() race by correct ordering in probe()
+ *		- DMA coherency rules by separate allocation of all buffers
+ *		- use of endianness macros
+ *		- abuse of spinlock, replaced by mutex
+ *		- racy handling of timer in disconnect,
+ *		  replaced by delayed_work
+ *		- racy interruptible_sleep_on(),
+ *		  replaced with wait_event_interruptible()
+ *		- handle signals in read()
+ * 2008-02-08	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Oliver Neukum <oliver@neukum.org>
+ *		Version 1.0.7
+ *		- usb autosuspend support
  *
  *
  * ToDo:
  * ToDo:
  * - add seeking support
  * - add seeking support
@@ -74,9 +97,10 @@
 /* driver definitions */
 /* driver definitions */
 #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
 #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
 #define DRIVER_NAME "radio-si470x"
 #define DRIVER_NAME "radio-si470x"
-#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6)
 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
+#define DRIVER_VERSION "1.0.6"
 
 
 
 
 /* kernel includes */
 /* kernel includes */
@@ -89,8 +113,10 @@
 #include <linux/hid.h>
 #include <linux/hid.h>
 #include <linux/version.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
+#include <linux/mutex.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/rds.h>
 #include <media/rds.h>
+#include <asm/unaligned.h>
 
 
 
 
 /* USB Device ID List */
 /* USB Device ID List */
@@ -119,56 +145,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
 /* 0: 200 kHz (USA, Australia) */
 /* 0: 200 kHz (USA, Australia) */
 /* 1: 100 kHz (Europe, Japan) */
 /* 1: 100 kHz (Europe, Japan) */
 /* 2:  50 kHz */
 /* 2:  50 kHz */
-static int space = 2;
-module_param(space, int, 0);
+static unsigned short space = 2;
+module_param(space, ushort, 0);
 MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
 MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
 
 
 /* Bottom of Band (MHz) */
 /* Bottom of Band (MHz) */
 /* 0: 87.5 - 108 MHz (USA, Europe)*/
 /* 0: 87.5 - 108 MHz (USA, Europe)*/
 /* 1: 76   - 108 MHz (Japan wide band) */
 /* 1: 76   - 108 MHz (Japan wide band) */
 /* 2: 76   -  90 MHz (Japan) */
 /* 2: 76   -  90 MHz (Japan) */
-static int band = 1;
-module_param(band, int, 0);
+static unsigned short band = 1;
+module_param(band, ushort, 0);
 MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
 MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
 
 
 /* De-emphasis */
 /* De-emphasis */
 /* 0: 75 us (USA) */
 /* 0: 75 us (USA) */
 /* 1: 50 us (Europe, Australia, Japan) */
 /* 1: 50 us (Europe, Australia, Japan) */
-static int de = 1;
-module_param(de, int, 0);
+static unsigned short de = 1;
+module_param(de, ushort, 0);
 MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
 MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
 
 
 /* USB timeout */
 /* USB timeout */
-static int usb_timeout = 500;
-module_param(usb_timeout, int, 0);
+static unsigned int usb_timeout = 500;
+module_param(usb_timeout, uint, 0);
 MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
 MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
 
 
-/* Seek retries */
-static int seek_retries = 100;
-module_param(seek_retries, int, 0);
-MODULE_PARM_DESC(seek_retries, "Seek retries: *100*");
+/* Tune timeout */
+static unsigned int tune_timeout = 3000;
+module_param(tune_timeout, uint, 0);
+MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
 
 
 /* RDS buffer blocks */
 /* RDS buffer blocks */
-static int rds_buf = 100;
-module_param(rds_buf, int, 0);
+static unsigned int rds_buf = 100;
+module_param(rds_buf, uint, 0);
 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
 
 
 /* RDS maximum block errors */
 /* RDS maximum block errors */
-static int max_rds_errors = 1;
+static unsigned short max_rds_errors = 1;
 /* 0 means   0  errors requiring correction */
 /* 0 means   0  errors requiring correction */
 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
 /* 2 means 3-5  errors requiring correction */
 /* 2 means 3-5  errors requiring correction */
 /* 3 means   6+ errors or errors in checkword, correction not possible */
 /* 3 means   6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, int, 0);
+module_param(max_rds_errors, ushort, 0);
 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
 
 
 /* RDS poll frequency */
 /* RDS poll frequency */
-static int rds_poll_time = 40;
+static unsigned int rds_poll_time = 40;
 /* 40 is used by the original USBRadio.exe */
 /* 40 is used by the original USBRadio.exe */
 /* 50 is used by radio-cadet */
 /* 50 is used by radio-cadet */
 /* 75 should be okay */
 /* 75 should be okay */
 /* 80 is the usual RDS receive interval */
 /* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, int, 0);
+module_param(rds_poll_time, uint, 0);
 MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
 MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
 
 
 
 
@@ -393,22 +419,19 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
 struct si470x_device {
 struct si470x_device {
 	/* reference to USB and video device */
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
 	struct usb_device *usbdev;
+	struct usb_interface *intf;
 	struct video_device *videodev;
 	struct video_device *videodev;
 
 
-	/* are these really necessary ? */
-	int users;
-
-	/* report buffer (maximum 64 bytes) */
-	unsigned char buf[64];
+	/* driver management */
+	unsigned int users;
 
 
 	/* Silabs internal registers (0..15) */
 	/* Silabs internal registers (0..15) */
 	unsigned short registers[RADIO_REGISTER_NUM];
 	unsigned short registers[RADIO_REGISTER_NUM];
 
 
 	/* RDS receive buffer */
 	/* RDS receive buffer */
-	struct work_struct work;
+	struct delayed_work work;
 	wait_queue_head_t read_queue;
 	wait_queue_head_t read_queue;
-	struct timer_list timer;
-	spinlock_t lock;		/* buffer locking */
+	struct mutex lock;		/* buffer locking */
 	unsigned char *buffer;		/* size is always multiple of three */
 	unsigned char *buffer;		/* size is always multiple of three */
 	unsigned int buf_size;
 	unsigned int buf_size;
 	unsigned int rd_index;
 	unsigned int rd_index;
@@ -434,28 +457,46 @@ struct si470x_device {
 /*
 /*
  * si470x_get_report - receive a HID report
  * si470x_get_report - receive a HID report
  */
  */
-static int si470x_get_report(struct si470x_device *radio, int size)
+static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
 {
 {
-	return usb_control_msg(radio->usbdev,
+	unsigned char *report = (unsigned char *) buf;
+	int retval;
+
+	retval = usb_control_msg(radio->usbdev,
 		usb_rcvctrlpipe(radio->usbdev, 0),
 		usb_rcvctrlpipe(radio->usbdev, 0),
 		HID_REQ_GET_REPORT,
 		HID_REQ_GET_REPORT,
 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-		radio->buf[0], 2,
-		radio->buf, size, usb_timeout);
+		report[0], 2,
+		buf, size, usb_timeout);
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": si470x_get_report: usb_control_msg returned %d\n",
+			retval);
+
+	return retval;
 }
 }
 
 
 
 
 /*
 /*
  * si470x_set_report - send a HID report
  * si470x_set_report - send a HID report
  */
  */
-static int si470x_set_report(struct si470x_device *radio, int size)
+static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
 {
 {
-	return usb_control_msg(radio->usbdev,
+	unsigned char *report = (unsigned char *) buf;
+	int retval;
+
+	retval = usb_control_msg(radio->usbdev,
 		usb_sndctrlpipe(radio->usbdev, 0),
 		usb_sndctrlpipe(radio->usbdev, 0),
 		HID_REQ_SET_REPORT,
 		HID_REQ_SET_REPORT,
 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
-		radio->buf[0], 2,
-		radio->buf, size, usb_timeout);
+		report[0], 2,
+		buf, size, usb_timeout);
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": si470x_set_report: usb_control_msg returned %d\n",
+			retval);
+
+	return retval;
 }
 }
 
 
 
 
@@ -464,13 +505,16 @@ static int si470x_set_report(struct si470x_device *radio, int size)
  */
  */
 static int si470x_get_register(struct si470x_device *radio, int regnr)
 static int si470x_get_register(struct si470x_device *radio, int regnr)
 {
 {
+	unsigned char buf[REGISTER_REPORT_SIZE];
 	int retval;
 	int retval;
 
 
-	radio->buf[0] = REGISTER_REPORT(regnr);
+	buf[0] = REGISTER_REPORT(regnr);
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
 
 
-	retval = si470x_get_report(radio, REGISTER_REPORT_SIZE);
 	if (retval >= 0)
 	if (retval >= 0)
-		radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2];
+		radio->registers[regnr] = be16_to_cpu(get_unaligned(
+			(unsigned short *) &buf[1]));
 
 
 	return (retval < 0) ? -EINVAL : 0;
 	return (retval < 0) ? -EINVAL : 0;
 }
 }
@@ -481,13 +525,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
  */
  */
 static int si470x_set_register(struct si470x_device *radio, int regnr)
 static int si470x_set_register(struct si470x_device *radio, int regnr)
 {
 {
+	unsigned char buf[REGISTER_REPORT_SIZE];
 	int retval;
 	int retval;
 
 
-	radio->buf[0] = REGISTER_REPORT(regnr);
-	radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8;
-	radio->buf[2] = (radio->registers[regnr] & 0x00ff);
+	buf[0] = REGISTER_REPORT(regnr);
+	put_unaligned(cpu_to_be16(radio->registers[regnr]),
+		(unsigned short *) &buf[1]);
 
 
-	retval = si470x_set_report(radio, REGISTER_REPORT_SIZE);
+	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
 
 
 	return (retval < 0) ? -EINVAL : 0;
 	return (retval < 0) ? -EINVAL : 0;
 }
 }
@@ -498,18 +543,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
  */
  */
 static int si470x_get_all_registers(struct si470x_device *radio)
 static int si470x_get_all_registers(struct si470x_device *radio)
 {
 {
+	unsigned char buf[ENTIRE_REPORT_SIZE];
 	int retval;
 	int retval;
-	int regnr;
+	unsigned char regnr;
 
 
-	radio->buf[0] = ENTIRE_REPORT;
+	buf[0] = ENTIRE_REPORT;
 
 
-	retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE);
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
 
 
 	if (retval >= 0)
 	if (retval >= 0)
 		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
 		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
-			radio->registers[regnr] =
-			(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
-			 radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
+			radio->registers[regnr] = be16_to_cpu(get_unaligned(
+				(unsigned short *)
+				&buf[regnr * RADIO_REGISTER_SIZE + 1]));
 
 
 	return (retval < 0) ? -EINVAL : 0;
 	return (retval < 0) ? -EINVAL : 0;
 }
 }
@@ -520,21 +566,28 @@ static int si470x_get_all_registers(struct si470x_device *radio)
  */
  */
 static int si470x_get_rds_registers(struct si470x_device *radio)
 static int si470x_get_rds_registers(struct si470x_device *radio)
 {
 {
+	unsigned char buf[RDS_REPORT_SIZE];
 	int retval;
 	int retval;
-	int regnr;
 	int size;
 	int size;
+	unsigned char regnr;
 
 
-	radio->buf[0] = RDS_REPORT;
+	buf[0] = RDS_REPORT;
 
 
 	retval = usb_interrupt_msg(radio->usbdev,
 	retval = usb_interrupt_msg(radio->usbdev,
-		usb_rcvctrlpipe(radio->usbdev, 1),
-		radio->buf, RDS_REPORT_SIZE, &size, usb_timeout);
+		usb_rcvintpipe(radio->usbdev, 1),
+		(void *) &buf, sizeof(buf), &size, usb_timeout);
+	if (size != sizeof(buf))
+		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
+			"return size differs: %d != %zu\n", size, sizeof(buf));
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+			"usb_interrupt_msg returned %d\n", retval);
 
 
 	if (retval >= 0)
 	if (retval >= 0)
 		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
 		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
 			radio->registers[STATUSRSSI + regnr] =
 			radio->registers[STATUSRSSI + regnr] =
-			(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
-			 radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
+				be16_to_cpu(get_unaligned((unsigned short *)
+				&buf[regnr * RADIO_REGISTER_SIZE + 1]));
 
 
 	return (retval < 0) ? -EINVAL : 0;
 	return (retval < 0) ? -EINVAL : 0;
 }
 }
@@ -543,9 +596,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
 /*
 /*
  * si470x_set_chan - set the channel
  * si470x_set_chan - set the channel
  */
  */
-static int si470x_set_chan(struct si470x_device *radio, int chan)
+static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
 {
 {
-	int retval, i;
+	int retval;
+	unsigned long timeout;
+	bool timed_out = 0;
 
 
 	/* start tuning */
 	/* start tuning */
 	radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
 	radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
@@ -555,16 +610,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
 		return retval;
 		return retval;
 
 
 	/* wait till seek operation has completed */
 	/* wait till seek operation has completed */
-	i = 0;
+	timeout = jiffies + msecs_to_jiffies(tune_timeout);
 	do {
 	do {
 		retval = si470x_get_register(radio, STATUSRSSI);
 		retval = si470x_get_register(radio, STATUSRSSI);
 		if (retval < 0)
 		if (retval < 0)
 			return retval;
 			return retval;
-	} while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) &&
-		(++i < seek_retries));
-	if (i >= seek_retries)
+		timed_out = time_after(jiffies, timeout);
+	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
+		(!timed_out));
+	if (timed_out)
 		printk(KERN_WARNING DRIVER_NAME
 		printk(KERN_WARNING DRIVER_NAME
-			": seek does not finish after %d tries\n", i);
+			": seek does not finish after %u ms\n", tune_timeout);
 
 
 	/* stop tuning */
 	/* stop tuning */
 	radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
 	radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
@@ -575,9 +631,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
 /*
 /*
  * si470x_get_freq - get the frequency
  * si470x_get_freq - get the frequency
  */
  */
-static int si470x_get_freq(struct si470x_device *radio)
+static unsigned int si470x_get_freq(struct si470x_device *radio)
 {
 {
-	int spacing, band_bottom, chan, freq;
+	unsigned int spacing, band_bottom, freq;
+	unsigned short chan;
 	int retval;
 	int retval;
 
 
 	/* Spacing (kHz) */
 	/* Spacing (kHz) */
@@ -616,9 +673,10 @@ static int si470x_get_freq(struct si470x_device *radio)
 /*
 /*
  * si470x_set_freq - set the frequency
  * si470x_set_freq - set the frequency
  */
  */
-static int si470x_set_freq(struct si470x_device *radio, int freq)
+static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
 {
 {
-	int spacing, band_bottom, chan;
+	unsigned int spacing, band_bottom;
+	unsigned short chan;
 
 
 	/* Spacing (kHz) */
 	/* Spacing (kHz) */
 	switch (space) {
 	switch (space) {
@@ -709,9 +767,17 @@ static int si470x_stop(struct si470x_device *radio)
  */
  */
 static int si470x_rds_on(struct si470x_device *radio)
 static int si470x_rds_on(struct si470x_device *radio)
 {
 {
+	int retval;
+
 	/* sysconfig 1 */
 	/* sysconfig 1 */
+	mutex_lock(&radio->lock);
 	radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
 	radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
-	return si470x_set_register(radio, SYSCONFIG1);
+	retval = si470x_set_register(radio, SYSCONFIG1);
+	if (retval < 0)
+		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
+	mutex_unlock(&radio->lock);
+
+	return retval;
 }
 }
 
 
 
 
@@ -725,11 +791,10 @@ static int si470x_rds_on(struct si470x_device *radio)
  */
  */
 static void si470x_rds(struct si470x_device *radio)
 static void si470x_rds(struct si470x_device *radio)
 {
 {
-	unsigned char tmpbuf[3];
 	unsigned char blocknum;
 	unsigned char blocknum;
-	unsigned char bler; /* rds block errors */
+	unsigned short bler; /* rds block errors */
 	unsigned short rds;
 	unsigned short rds;
-	unsigned int i;
+	unsigned char tmpbuf[3];
 
 
 	/* get rds blocks */
 	/* get rds blocks */
 	if (si470x_get_rds_registers(radio) < 0)
 	if (si470x_get_rds_registers(radio) < 0)
@@ -743,63 +808,58 @@ static void si470x_rds(struct si470x_device *radio)
 		return;
 		return;
 	}
 	}
 
 
-	/* copy four RDS blocks to internal buffer */
-	if (spin_trylock(&radio->lock)) {
-		/* process each rds block */
-		for (blocknum = 0; blocknum < 4; blocknum++) {
-			switch (blocknum) {
-			default:
-				bler = (radio->registers[STATUSRSSI] &
-						STATUSRSSI_BLERA) >> 9;
-				rds = radio->registers[RDSA];
-				break;
-			case 1:
-				bler = (radio->registers[READCHAN] &
-						READCHAN_BLERB) >> 14;
-				rds = radio->registers[RDSB];
-				break;
-			case 2:
-				bler = (radio->registers[READCHAN] &
-						READCHAN_BLERC) >> 12;
-				rds = radio->registers[RDSC];
-				break;
-			case 3:
-				bler = (radio->registers[READCHAN] &
-						READCHAN_BLERD) >> 10;
-				rds = radio->registers[RDSD];
-				break;
-			};
-
-			/* Fill the V4L2 RDS buffer */
-			tmpbuf[0] = rds & 0x00ff;	/* LSB */
-			tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */
-			tmpbuf[2] = blocknum;		/* offset name */
-			tmpbuf[2] |= blocknum << 3;	/* received offset */
-			if (bler > max_rds_errors)
-				tmpbuf[2] |= 0x80; /* uncorrectable errors */
-			else if (bler > 0)
-				tmpbuf[2] |= 0x40; /* corrected error(s) */
-
-			/* copy RDS block to internal buffer */
-			for (i = 0; i < 3; i++) {
-				radio->buffer[radio->wr_index] = tmpbuf[i];
-				radio->wr_index++;
-			}
-
-			/* wrap write pointer */
-			if (radio->wr_index >= radio->buf_size)
-				radio->wr_index = 0;
-
-			/* check for overflow */
-			if (radio->wr_index == radio->rd_index) {
-				/* increment and wrap read pointer */
-				radio->rd_index += 3;
-				if (radio->rd_index >= radio->buf_size)
-					radio->rd_index = 0;
-			}
+	/* copy all four RDS blocks to internal buffer */
+	mutex_lock(&radio->lock);
+	for (blocknum = 0; blocknum < 4; blocknum++) {
+		switch (blocknum) {
+		default:
+			bler = (radio->registers[STATUSRSSI] &
+					STATUSRSSI_BLERA) >> 9;
+			rds = radio->registers[RDSA];
+			break;
+		case 1:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERB) >> 14;
+			rds = radio->registers[RDSB];
+			break;
+		case 2:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERC) >> 12;
+			rds = radio->registers[RDSC];
+			break;
+		case 3:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERD) >> 10;
+			rds = radio->registers[RDSD];
+			break;
+		};
+
+		/* Fill the V4L2 RDS buffer */
+		put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
+		tmpbuf[2] = blocknum;		/* offset name */
+		tmpbuf[2] |= blocknum << 3;	/* received offset */
+		if (bler > max_rds_errors)
+			tmpbuf[2] |= 0x80; /* uncorrectable errors */
+		else if (bler > 0)
+			tmpbuf[2] |= 0x40; /* corrected error(s) */
+
+		/* copy RDS block to internal buffer */
+		memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
+		radio->wr_index += 3;
+
+		/* wrap write pointer */
+		if (radio->wr_index >= radio->buf_size)
+			radio->wr_index = 0;
+
+		/* check for overflow */
+		if (radio->wr_index == radio->rd_index) {
+			/* increment and wrap read pointer */
+			radio->rd_index += 3;
+			if (radio->rd_index >= radio->buf_size)
+				radio->rd_index = 0;
 		}
 		}
-		spin_unlock(&radio->lock);
 	}
 	}
+	mutex_unlock(&radio->lock);
 
 
 	/* wake up read queue */
 	/* wake up read queue */
 	if (radio->wr_index != radio->rd_index)
 	if (radio->wr_index != radio->rd_index)
@@ -807,30 +867,19 @@ static void si470x_rds(struct si470x_device *radio)
 }
 }
 
 
 
 
-/*
- * si470x_timer - rds timer function
- */
-static void si470x_timer(unsigned long data)
-{
-	struct si470x_device *radio = (struct si470x_device *) data;
-
-	schedule_work(&radio->work);
-}
-
-
 /*
 /*
  * si470x_work - rds work function
  * si470x_work - rds work function
  */
  */
 static void si470x_work(struct work_struct *work)
 static void si470x_work(struct work_struct *work)
 {
 {
 	struct si470x_device *radio = container_of(work, struct si470x_device,
 	struct si470x_device *radio = container_of(work, struct si470x_device,
-		work);
+		work.work);
 
 
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
 		return;
 		return;
 
 
 	si470x_rds(radio);
 	si470x_rds(radio);
-	mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time));
+	schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
 }
 }
 
 
 
 
@@ -852,44 +901,44 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
 	/* switch on rds reception */
 	/* switch on rds reception */
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
 		si470x_rds_on(radio);
 		si470x_rds_on(radio);
-		schedule_work(&radio->work);
+		schedule_delayed_work(&radio->work,
+			msecs_to_jiffies(rds_poll_time));
 	}
 	}
 
 
 	/* block if no new data available */
 	/* block if no new data available */
 	while (radio->wr_index == radio->rd_index) {
 	while (radio->wr_index == radio->rd_index) {
 		if (file->f_flags & O_NONBLOCK)
 		if (file->f_flags & O_NONBLOCK)
 			return -EWOULDBLOCK;
 			return -EWOULDBLOCK;
-		interruptible_sleep_on(&radio->read_queue);
+		if (wait_event_interruptible(radio->read_queue,
+			radio->wr_index != radio->rd_index) < 0)
+			return -EINTR;
 	}
 	}
 
 
 	/* calculate block count from byte count */
 	/* calculate block count from byte count */
 	count /= 3;
 	count /= 3;
 
 
 	/* copy RDS block out of internal buffer and to user buffer */
 	/* copy RDS block out of internal buffer and to user buffer */
-	if (spin_trylock(&radio->lock)) {
-		while (block_count < count) {
-			if (radio->rd_index == radio->wr_index)
-				break;
-
-			/* always transfer rds complete blocks */
-			if (copy_to_user(buf,
-					&radio->buffer[radio->rd_index], 3))
-				/* retval = -EFAULT; */
-				break;
-
-			/* increment and wrap read pointer */
-			radio->rd_index += 3;
-			if (radio->rd_index >= radio->buf_size)
-				radio->rd_index = 0;
-
-			/* increment counters */
-			block_count++;
-			buf += 3;
-			retval += 3;
-		}
-
-		spin_unlock(&radio->lock);
+	mutex_lock(&radio->lock);
+	while (block_count < count) {
+		if (radio->rd_index == radio->wr_index)
+			break;
+
+		/* always transfer rds complete blocks */
+		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
+			/* retval = -EFAULT; */
+			break;
+
+		/* increment and wrap read pointer */
+		radio->rd_index += 3;
+		if (radio->rd_index >= radio->buf_size)
+			radio->rd_index = 0;
+
+		/* increment counters */
+		block_count++;
+		buf += 3;
+		retval += 3;
 	}
 	}
+	mutex_unlock(&radio->lock);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -906,7 +955,8 @@ static unsigned int si470x_fops_poll(struct file *file,
 	/* switch on rds reception */
 	/* switch on rds reception */
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
 		si470x_rds_on(radio);
 		si470x_rds_on(radio);
-		schedule_work(&radio->work);
+		schedule_delayed_work(&radio->work,
+			msecs_to_jiffies(rds_poll_time));
 	}
 	}
 
 
 	poll_wait(file, &radio->read_queue, pts);
 	poll_wait(file, &radio->read_queue, pts);
@@ -924,10 +974,22 @@ static unsigned int si470x_fops_poll(struct file *file,
 static int si470x_fops_open(struct inode *inode, struct file *file)
 static int si470x_fops_open(struct inode *inode, struct file *file)
 {
 {
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	radio->users++;
 	radio->users++;
-	if (radio->users == 1)
-		return si470x_start(radio);
+
+	retval = usb_autopm_get_interface(radio->intf);
+	if (retval < 0) {
+		radio->users--;
+		return -EIO;
+	}
+
+	if (radio->users == 1) {
+		retval = si470x_start(radio);
+		if (retval < 0)
+			usb_autopm_put_interface(radio->intf);
+		return retval;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -939,6 +1001,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
 static int si470x_fops_release(struct inode *inode, struct file *file)
 static int si470x_fops_release(struct inode *inode, struct file *file)
 {
 {
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	if (!radio)
 	if (!radio)
 		return -ENODEV;
 		return -ENODEV;
@@ -946,13 +1009,14 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
 	radio->users--;
 	radio->users--;
 	if (radio->users == 0) {
 	if (radio->users == 0) {
 		/* stop rds reception */
 		/* stop rds reception */
-		del_timer_sync(&radio->timer);
-		flush_scheduled_work();
+		cancel_delayed_work_sync(&radio->work);
 
 
 		/* cancel read processes */
 		/* cancel read processes */
 		wake_up_interruptible(&radio->read_queue);
 		wake_up_interruptible(&radio->read_queue);
 
 
-		return si470x_stop(radio);
+		retval = si470x_stop(radio);
+		usb_autopm_put_interface(radio->intf);
+		return retval;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -1030,7 +1094,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
 	sprintf(capability->bus_info, "USB");
 	sprintf(capability->bus_info, "USB");
-	capability->version = DRIVER_VERSION;
+	capability->version = DRIVER_KERNEL_VERSION;
 	capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 
 
 	return 0;
 	return 0;
@@ -1067,16 +1131,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 static int si470x_vidioc_queryctrl(struct file *file, void *priv,
 static int si470x_vidioc_queryctrl(struct file *file, void *priv,
 		struct v4l2_queryctrl *qc)
 		struct v4l2_queryctrl *qc)
 {
 {
-	int i;
+	unsigned char i;
+	int retval = -EINVAL;
 
 
 	for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
 	for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
 		if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
 		if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
 			memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
 			memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
-			return 0;
+			retval = 0;
+			break;
 		}
 		}
 	}
 	}
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": query control failed with %d\n", retval);
 
 
-	return -EINVAL;
+	return retval;
 }
 }
 
 
 
 
@@ -1110,21 +1179,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
 		struct v4l2_control *ctrl)
 		struct v4l2_control *ctrl)
 {
 {
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	switch (ctrl->id) {
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_VOLUME:
 		radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
 		radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
 		radio->registers[SYSCONFIG2] |= ctrl->value;
 		radio->registers[SYSCONFIG2] |= ctrl->value;
-		return si470x_set_register(radio, SYSCONFIG2);
+		retval = si470x_set_register(radio, SYSCONFIG2);
+		break;
 	case V4L2_CID_AUDIO_MUTE:
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value == 1)
 		if (ctrl->value == 1)
 			radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
 			radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
 		else
 		else
 			radio->registers[POWERCFG] |= POWERCFG_DMUTE;
 			radio->registers[POWERCFG] |= POWERCFG_DMUTE;
-		return si470x_set_register(radio, POWERCFG);
+		retval = si470x_set_register(radio, POWERCFG);
+		break;
+	default:
+		retval = -EINVAL;
 	}
 	}
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": set control failed with %d\n", retval);
 
 
-	return -EINVAL;
+	return retval;
 }
 }
 
 
 
 
@@ -1163,8 +1240,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv,
 static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 		struct v4l2_tuner *tuner)
 		struct v4l2_tuner *tuner)
 {
 {
-	int retval;
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	if (tuner->index > 0)
 	if (tuner->index > 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1220,6 +1297,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
 		struct v4l2_tuner *tuner)
 		struct v4l2_tuner *tuner)
 {
 {
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	if (tuner->index > 0)
 	if (tuner->index > 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1229,7 +1307,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
 	else
 	else
 		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
 		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
 
 
-	return si470x_set_register(radio, POWERCFG);
+	retval = si470x_set_register(radio, POWERCFG);
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": set tuner failed with %d\n", retval);
+
+	return retval;
 }
 }
 
 
 
 
@@ -1255,11 +1338,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
 		struct v4l2_frequency *freq)
 		struct v4l2_frequency *freq)
 {
 {
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 
 	if (freq->type != V4L2_TUNER_RADIO)
 	if (freq->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	return si470x_set_freq(radio, freq->frequency);
+	retval = si470x_set_freq(radio, freq->frequency);
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME
+			": set frequency failed with %d\n", retval);
+
+	return 0;
 }
 }
 
 
 
 
@@ -1299,71 +1388,116 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 		const struct usb_device_id *id)
 {
 {
 	struct si470x_device *radio;
 	struct si470x_device *radio;
+	int retval = -ENOMEM;
 
 
-	/* memory and interface allocations */
-	radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL);
+	/* private data allocation */
+	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
 	if (!radio)
 	if (!radio)
-		return -ENOMEM;
+		goto err_initial;
+
+	/* video device allocation */
 	radio->videodev = video_device_alloc();
 	radio->videodev = video_device_alloc();
-	if (!radio->videodev) {
-		kfree(radio);
-		return -ENOMEM;
-	}
+	if (!radio->videodev)
+		goto err_radio;
+
+	/* initial configuration */
 	memcpy(radio->videodev, &si470x_viddev_template,
 	memcpy(radio->videodev, &si470x_viddev_template,
 			sizeof(si470x_viddev_template));
 			sizeof(si470x_viddev_template));
 	radio->users = 0;
 	radio->users = 0;
 	radio->usbdev = interface_to_usbdev(intf);
 	radio->usbdev = interface_to_usbdev(intf);
+	radio->intf = intf;
+	mutex_init(&radio->lock);
 	video_set_drvdata(radio->videodev, radio);
 	video_set_drvdata(radio->videodev, radio);
-	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
-		printk(KERN_WARNING DRIVER_NAME
-				": Could not register video device\n");
-		video_device_release(radio->videodev);
-		kfree(radio);
-		return -EIO;
-	}
-	usb_set_intfdata(intf, radio);
 
 
 	/* show some infos about the specific device */
 	/* show some infos about the specific device */
-	if (si470x_get_all_registers(radio) < 0) {
-		video_device_release(radio->videodev);
-		kfree(radio);
-		return -EIO;
-	}
-	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n",
+	retval = -EIO;
+	if (si470x_get_all_registers(radio) < 0)
+		goto err_all;
+	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
 			radio->registers[DEVICEID], radio->registers[CHIPID]);
 			radio->registers[DEVICEID], radio->registers[CHIPID]);
 
 
 	/* check if firmware is current */
 	/* check if firmware is current */
 	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
 	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
-			< RADIO_SW_VERSION_CURRENT)
+			< RADIO_SW_VERSION_CURRENT) {
+		printk(KERN_WARNING DRIVER_NAME
+			": This driver is known to work with "
+			"firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
+		printk(KERN_WARNING DRIVER_NAME
+			": but the device has firmware version %hu.\n",
+			radio->registers[CHIPID] & CHIPID_FIRMWARE);
+		printk(KERN_WARNING DRIVER_NAME
+			": If you have some trouble using this driver,\n");
 		printk(KERN_WARNING DRIVER_NAME
 		printk(KERN_WARNING DRIVER_NAME
-			": This driver is known to work with chip version %d, "
-			"but the device has firmware %d.\n"
-			DRIVER_NAME
-			"If you have some trouble using this driver, please "
-			"report to V4L ML at video4linux-list@redhat.com\n",
-			radio->registers[CHIPID] & CHIPID_FIRMWARE,
-			RADIO_SW_VERSION_CURRENT);
+			": please report to V4L ML at "
+			"video4linux-list@redhat.com\n");
+	}
 
 
 	/* set initial frequency */
 	/* set initial frequency */
 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
 
 
-	/* rds initialization */
+	/* rds buffer allocation */
 	radio->buf_size = rds_buf * 3;
 	radio->buf_size = rds_buf * 3;
 	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
 	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
-	if (!radio->buffer) {
-		video_device_release(radio->videodev);
-		kfree(radio);
-		return -ENOMEM;
-	}
+	if (!radio->buffer)
+		goto err_all;
+
+	/* rds buffer configuration */
 	radio->wr_index = 0;
 	radio->wr_index = 0;
 	radio->rd_index = 0;
 	radio->rd_index = 0;
 	init_waitqueue_head(&radio->read_queue);
 	init_waitqueue_head(&radio->read_queue);
 
 
-	/* prepare polling via eventd */
-	INIT_WORK(&radio->work, si470x_work);
-	init_timer(&radio->timer);
-	radio->timer.function = si470x_timer;
-	radio->timer.data = (unsigned long) radio;
+	/* prepare rds work function */
+	INIT_DELAYED_WORK(&radio->work, si470x_work);
+
+	/* register video device */
+	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
+		printk(KERN_WARNING DRIVER_NAME
+				": Could not register video device\n");
+		goto err_all;
+	}
+	usb_set_intfdata(intf, radio);
+
+	return 0;
+err_all:
+	video_device_release(radio->videodev);
+	kfree(radio->buffer);
+err_radio:
+	kfree(radio);
+err_initial:
+	return retval;
+}
+
+
+/*
+ * si470x_usb_driver_suspend - suspend the device
+ */
+static int si470x_usb_driver_suspend(struct usb_interface *intf,
+		pm_message_t message)
+{
+	struct si470x_device *radio = usb_get_intfdata(intf);
+
+	printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
+
+	cancel_delayed_work_sync(&radio->work);
+
+	return 0;
+}
+
+
+/*
+ * si470x_usb_driver_resume - resume the device
+ */
+static int si470x_usb_driver_resume(struct usb_interface *intf)
+{
+	struct si470x_device *radio = usb_get_intfdata(intf);
+
+	printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
+
+	mutex_lock(&radio->lock);
+	if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
+		schedule_delayed_work(&radio->work,
+			msecs_to_jiffies(rds_poll_time));
+	mutex_unlock(&radio->lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1376,15 +1510,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
 {
 {
 	struct si470x_device *radio = usb_get_intfdata(intf);
 	struct si470x_device *radio = usb_get_intfdata(intf);
 
 
-	del_timer_sync(&radio->timer);
-	flush_scheduled_work();
-
+	cancel_delayed_work_sync(&radio->work);
 	usb_set_intfdata(intf, NULL);
 	usb_set_intfdata(intf, NULL);
-	if (radio) {
-		video_unregister_device(radio->videodev);
-		kfree(radio->buffer);
-		kfree(radio);
-	}
+	video_unregister_device(radio->videodev);
+	kfree(radio->buffer);
+	kfree(radio);
 }
 }
 
 
 
 
@@ -1392,10 +1522,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
  * si470x_usb_driver - usb driver interface
  * si470x_usb_driver - usb driver interface
  */
  */
 static struct usb_driver si470x_usb_driver = {
 static struct usb_driver si470x_usb_driver = {
-	.name		= DRIVER_NAME,
-	.probe		= si470x_usb_driver_probe,
-	.disconnect	= si470x_usb_driver_disconnect,
-	.id_table	= si470x_usb_driver_id_table,
+	.name			= DRIVER_NAME,
+	.probe			= si470x_usb_driver_probe,
+	.disconnect		= si470x_usb_driver_disconnect,
+	.suspend		= si470x_usb_driver_suspend,
+	.resume			= si470x_usb_driver_resume,
+	.id_table		= si470x_usb_driver_id_table,
+	.supports_autosuspend	= 1,
 };
 };
 
 
 
 
@@ -1409,7 +1542,7 @@ static struct usb_driver si470x_usb_driver = {
  */
  */
 static int __init si470x_module_init(void)
 static int __init si470x_module_init(void)
 {
 {
-	printk(KERN_INFO DRIVER_DESC "\n");
+	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
 	return usb_register(&si470x_usb_driver);
 	return usb_register(&si470x_usb_driver);
 }
 }
 
 
@@ -1429,4 +1562,4 @@ module_exit(si470x_module_exit);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION("1.0.4");
+MODULE_VERSION(DRIVER_VERSION);

+ 2 - 2
drivers/media/video/Kconfig

@@ -4,14 +4,14 @@
 
 
 menuconfig VIDEO_CAPTURE_DRIVERS
 menuconfig VIDEO_CAPTURE_DRIVERS
 	bool "Video capture adapters"
 	bool "Video capture adapters"
-	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
 	default y
 	default y
 	---help---
 	---help---
 	  Say Y here to enable selecting the video adapters for
 	  Say Y here to enable selecting the video adapters for
 	  webcams, analog TV, and hybrid analog/digital TV.
 	  webcams, analog TV, and hybrid analog/digital TV.
 	  Some of those devices also supports FM radio.
 	  Some of those devices also supports FM radio.
 
 
-if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV
+if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
 
 
 config VIDEO_ADV_DEBUG
 config VIDEO_ADV_DEBUG
 	bool "Enable advanced debug functionality"
 	bool "Enable advanced debug functionality"

+ 3 - 2
drivers/media/video/Makefile

@@ -10,8 +10,9 @@ msp3400-objs	:=	msp3400-driver.o msp3400-kthreads.o
 
 
 stkwebcam-objs	:=	stk-webcam.o stk-sensor.o
 stkwebcam-objs	:=	stk-webcam.o stk-sensor.o
 
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
-			   v4l2-int-device.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
+
+obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
 
 
 ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
 ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o

+ 25 - 26
drivers/media/video/bt8xx/bttv-driver.c

@@ -2354,8 +2354,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
 		BUG();
 		BUG();
 	}
 	}
 
 
-	mutex_lock(&fh->cap.lock);
-		kfree(fh->ov.clips);
+	mutex_lock(&fh->cap.vb_lock);
+	kfree(fh->ov.clips);
 	fh->ov.clips    = clips;
 	fh->ov.clips    = clips;
 	fh->ov.nclips   = n;
 	fh->ov.nclips   = n;
 
 
@@ -2376,7 +2376,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
 		retval = bttv_switch_overlay(btv,fh,new);
 		retval = bttv_switch_overlay(btv,fh,new);
 	}
 	}
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -2576,7 +2576,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
 	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 
 
 	/* update our state informations */
 	/* update our state informations */
-	mutex_lock(&fh->cap.lock);
+	mutex_lock(&fh->cap.vb_lock);
 	fh->fmt              = fmt;
 	fh->fmt              = fmt;
 	fh->cap.field        = f->fmt.pix.field;
 	fh->cap.field        = f->fmt.pix.field;
 	fh->cap.last         = V4L2_FIELD_NONE;
 	fh->cap.last         = V4L2_FIELD_NONE;
@@ -2585,7 +2585,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
 	btv->init.fmt        = fmt;
 	btv->init.fmt        = fmt;
 	btv->init.width      = f->fmt.pix.width;
 	btv->init.width      = f->fmt.pix.width;
 	btv->init.height     = f->fmt.pix.height;
 	btv->init.height     = f->fmt.pix.height;
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -2611,11 +2611,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
 	unsigned int i;
 	unsigned int i;
 	struct bttv_fh *fh = priv;
 	struct bttv_fh *fh = priv;
 
 
-	mutex_lock(&fh->cap.lock);
+	mutex_lock(&fh->cap.vb_lock);
 	retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
 	retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
 				     V4L2_MEMORY_MMAP);
 				     V4L2_MEMORY_MMAP);
 	if (retval < 0) {
 	if (retval < 0) {
-		mutex_unlock(&fh->cap.lock);
+		mutex_unlock(&fh->cap.vb_lock);
 		return retval;
 		return retval;
 	}
 	}
 
 
@@ -2627,7 +2627,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
 	for (i = 0; i < gbuffers; i++)
 	for (i = 0; i < gbuffers; i++)
 		mbuf->offsets[i] = i * gbufsize;
 		mbuf->offsets[i] = i * gbufsize;
 
 
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 	return 0;
 	return 0;
 }
 }
 #endif
 #endif
@@ -2756,10 +2756,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
 	if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY))
 	if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY))
 		return -EBUSY;
 		return -EBUSY;
 
 
-	mutex_lock(&fh->cap.lock);
+	mutex_lock(&fh->cap.vb_lock);
 	if (on) {
 	if (on) {
 		fh->ov.tvnorm = btv->tvnorm;
 		fh->ov.tvnorm = btv->tvnorm;
 		new = videobuf_pci_alloc(sizeof(*new));
 		new = videobuf_pci_alloc(sizeof(*new));
+		new->crop = btv->crop[!!fh->do_crop].rect;
 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
 	} else {
 	} else {
 		new = NULL;
 		new = NULL;
@@ -2767,7 +2768,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
 
 
 	/* switch over */
 	/* switch over */
 	retval = bttv_switch_overlay(btv, fh, new);
 	retval = bttv_switch_overlay(btv, fh, new);
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -2806,7 +2807,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
 	}
 	}
 
 
 	/* ok, accept it */
 	/* ok, accept it */
-	mutex_lock(&fh->cap.lock);
+	mutex_lock(&fh->cap.vb_lock);
 	btv->fbuf.base       = fb->base;
 	btv->fbuf.base       = fb->base;
 	btv->fbuf.fmt.width  = fb->fmt.width;
 	btv->fbuf.fmt.width  = fb->fmt.width;
 	btv->fbuf.fmt.height = fb->fmt.height;
 	btv->fbuf.fmt.height = fb->fmt.height;
@@ -2838,7 +2839,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
 			retval = bttv_switch_overlay(btv, fh, new);
 			retval = bttv_switch_overlay(btv, fh, new);
 		}
 		}
 	}
 	}
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -3090,7 +3091,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
 
 
 	fh->do_crop = 1;
 	fh->do_crop = 1;
 
 
-	mutex_lock(&fh->cap.lock);
+	mutex_lock(&fh->cap.vb_lock);
 
 
 	if (fh->width < c.min_scaled_width) {
 	if (fh->width < c.min_scaled_width) {
 		fh->width = c.min_scaled_width;
 		fh->width = c.min_scaled_width;
@@ -3108,7 +3109,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
 		btv->init.height = c.max_scaled_height;
 		btv->init.height = c.max_scaled_height;
 	}
 	}
 
 
-	mutex_unlock(&fh->cap.lock);
+	mutex_unlock(&fh->cap.vb_lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -3177,30 +3178,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
 		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
 		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
 	} else {
 	} else {
 		/* read() capture */
 		/* read() capture */
-		mutex_lock(&fh->cap.lock);
+		mutex_lock(&fh->cap.vb_lock);
 		if (NULL == fh->cap.read_buf) {
 		if (NULL == fh->cap.read_buf) {
 			/* need to capture a new frame */
 			/* need to capture a new frame */
-			if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) {
-				mutex_unlock(&fh->cap.lock);
-				return POLLERR;
-			}
+			if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
+				goto err;
 			fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
 			fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
-			if (NULL == fh->cap.read_buf) {
-				mutex_unlock(&fh->cap.lock);
-				return POLLERR;
-			}
+			if (NULL == fh->cap.read_buf)
+				goto err;
 			fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
 			fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
 			field = videobuf_next_field(&fh->cap);
 			field = videobuf_next_field(&fh->cap);
 			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
 			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
 				kfree (fh->cap.read_buf);
 				kfree (fh->cap.read_buf);
 				fh->cap.read_buf = NULL;
 				fh->cap.read_buf = NULL;
-				mutex_unlock(&fh->cap.lock);
-				return POLLERR;
+				goto err;
 			}
 			}
 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
 			fh->cap.read_off = 0;
 			fh->cap.read_off = 0;
 		}
 		}
-		mutex_unlock(&fh->cap.lock);
+		mutex_unlock(&fh->cap.vb_lock);
 		buf = (struct bttv_buffer*)fh->cap.read_buf;
 		buf = (struct bttv_buffer*)fh->cap.read_buf;
 	}
 	}
 
 
@@ -3209,6 +3205,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
 	    buf->vb.state == VIDEOBUF_ERROR)
 	    buf->vb.state == VIDEOBUF_ERROR)
 		return POLLIN|POLLRDNORM;
 		return POLLIN|POLLRDNORM;
 	return 0;
 	return 0;
+err:
+	mutex_unlock(&fh->cap.vb_lock);
+	return POLLERR;
 }
 }
 
 
 static int bttv_open(struct inode *inode, struct file *file)
 static int bttv_open(struct inode *inode, struct file *file)

+ 2 - 2
drivers/media/video/bt8xx/bttv-vbi.c

@@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
 	   because vbi_fmt.end counts field lines times two. */
 	   because vbi_fmt.end counts field lines times two. */
 	end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
 	end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
 
 
-	mutex_lock(&fh->vbi.lock);
+	mutex_lock(&fh->vbi.vb_lock);
 
 
 	fh->vbi_fmt.fmt    = frt->fmt.vbi;
 	fh->vbi_fmt.fmt    = frt->fmt.vbi;
 	fh->vbi_fmt.tvnorm = tvnorm;
 	fh->vbi_fmt.tvnorm = tvnorm;
 	fh->vbi_fmt.end    = end;
 	fh->vbi_fmt.end    = end;
 
 
-	mutex_unlock(&fh->vbi.lock);
+	mutex_unlock(&fh->vbi.vb_lock);
 
 
 	rc = 0;
 	rc = 0;
 
 

+ 12 - 4
drivers/media/video/cx88/cx88-mpeg.c

@@ -609,13 +609,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
 	struct cx88_core *core = drv->core;
 	struct cx88_core *core = drv->core;
 
 
 	/* Fail a request for hardware if the device is busy. */
 	/* Fail a request for hardware if the device is busy. */
-	if (core->active_type_id != CX88_BOARD_NONE)
+	if (core->active_type_id != CX88_BOARD_NONE &&
+	    core->active_type_id != drv->type_id)
 		return -EBUSY;
 		return -EBUSY;
 
 
 	if (drv->advise_acquire)
 	if (drv->advise_acquire)
 	{
 	{
-		core->active_type_id = drv->type_id;
-		drv->advise_acquire(drv);
+		mutex_lock(&drv->core->lock);
+		core->active_ref++;
+		if (core->active_type_id == CX88_BOARD_NONE) {
+			core->active_type_id = drv->type_id;
+			drv->advise_acquire(drv);
+		}
+		mutex_unlock(&drv->core->lock);
 
 
 		mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
 		mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
 	}
 	}
@@ -628,12 +634,14 @@ static int cx8802_request_release(struct cx8802_driver *drv)
 {
 {
 	struct cx88_core *core = drv->core;
 	struct cx88_core *core = drv->core;
 
 
-	if (drv->advise_release)
+	mutex_lock(&drv->core->lock);
+	if (drv->advise_release && --core->active_ref == 0)
 	{
 	{
 		drv->advise_release(drv);
 		drv->advise_release(drv);
 		core->active_type_id = CX88_BOARD_NONE;
 		core->active_type_id = CX88_BOARD_NONE;
 		mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
 		mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
 	}
 	}
+	mutex_unlock(&drv->core->lock);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 0
drivers/media/video/cx88/cx88.h

@@ -336,6 +336,7 @@ struct cx88_core {
 	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
 	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
 	struct cx8802_dev          *dvbdev;
 	struct cx8802_dev          *dvbdev;
 	enum cx88_board_type       active_type_id;
 	enum cx88_board_type       active_type_id;
+	int			   active_ref;
 };
 };
 
 
 struct cx8800_dev;
 struct cx8800_dev;

+ 5 - 1
drivers/media/video/em28xx/em28xx-audio.c

@@ -35,7 +35,6 @@
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/pcm_params.h>
@@ -270,8 +269,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 	dprintk("opening device and trying to acquire exclusive lock\n");
 	dprintk("opening device and trying to acquire exclusive lock\n");
 
 
 	/* Sets volume, mute, etc */
 	/* Sets volume, mute, etc */
+
 	dev->mute = 0;
 	dev->mute = 0;
+	mutex_lock(&dev->lock);
 	ret = em28xx_audio_analog_set(dev);
 	ret = em28xx_audio_analog_set(dev);
+	mutex_unlock(&dev->lock);
 	if (ret < 0)
 	if (ret < 0)
 		goto err;
 		goto err;
 
 
@@ -303,7 +305,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
 	dprintk("closing device\n");
 	dprintk("closing device\n");
 
 
 	dev->mute = 1;
 	dev->mute = 1;
+	mutex_lock(&dev->lock);
 	em28xx_audio_analog_set(dev);
 	em28xx_audio_analog_set(dev);
+	mutex_unlock(&dev->lock);
 
 
 	if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
 	if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
 		dprintk("audio users: %d\n", dev->adev->users);
 		dprintk("audio users: %d\n", dev->adev->users);

+ 5 - 3
drivers/media/video/em28xx/em28xx-cards.c

@@ -393,15 +393,15 @@ struct em28xx_board em28xx_boards[] = {
 		.input          = { {
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = SAA7115_COMPOSITE2,
 			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = 1,
+			.amux     = EM28XX_AMUX_LINE_IN,
 		}, {
 		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.vmux     = SAA7115_COMPOSITE0,
 			.vmux     = SAA7115_COMPOSITE0,
-			.amux     = 1,
+			.amux     = EM28XX_AMUX_LINE_IN,
 		}, {
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = SAA7115_SVIDEO3,
 			.vmux     = SAA7115_SVIDEO3,
-			.amux     = 1,
+			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 		} },
 	},
 	},
 };
 };
@@ -441,6 +441,8 @@ struct usb_device_id em28xx_id_table [] = {
 			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
 			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
 	{ USB_DEVICE(0x2040, 0x6500),
 	{ USB_DEVICE(0x2040, 0x6500),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+	{ USB_DEVICE(0x2040, 0x6502),
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 	{ USB_DEVICE(0x2040, 0x6513),
 	{ USB_DEVICE(0x2040, 0x6513),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x0ccd, 0x0042),
 	{ USB_DEVICE(0x0ccd, 0x0042),

+ 69 - 42
drivers/media/video/em28xx/em28xx-core.c

@@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
 	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
 	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
 	void *buff = NULL;
 	void *buff = NULL;
 	u32 i;
 	u32 i;
-	em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
+	em28xx_coredbg("requested %i buffers with size %zi\n",
+			count, imagesize);
 	if (count > EM28XX_NUM_FRAMES)
 	if (count > EM28XX_NUM_FRAMES)
 		count = EM28XX_NUM_FRAMES;
 		count = EM28XX_NUM_FRAMES;
 
 
@@ -150,7 +151,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
 	if (reg_debug){
 	if (reg_debug){
 		printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
 		printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
 		for (byte = 0; byte < len; byte++) {
 		for (byte = 0; byte < len; byte++) {
-			printk(" %02x", buf[byte]);
+			printk(" %02x", (unsigned char)buf[byte]);
 		}
 		}
 		printk("\n");
 		printk("\n");
 	}
 	}
@@ -177,7 +178,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
 			      0x0000, reg, &val, 1, HZ);
 			      0x0000, reg, &val, 1, HZ);
 
 
 	if (reg_debug)
 	if (reg_debug)
-		printk(ret < 0 ? " failed!\n" : "%02x\n", val);
+		printk(ret < 0 ? " failed!\n" :
+				 "%02x\n", (unsigned char) val);
 
 
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
@@ -237,7 +239,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
  * sets only some bits (specified by bitmask) of a register, by first reading
  * sets only some bits (specified by bitmask) of a register, by first reading
  * the actual value
  * the actual value
  */
  */
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
 				 u8 bitmask)
 				 u8 bitmask)
 {
 {
 	int oldval;
 	int oldval;
@@ -254,26 +256,31 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
  */
  */
 static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
 static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
 {
 {
-	int ret;
+	int ret, i;
 	u8 addr = reg & 0x7f;
 	u8 addr = reg & 0x7f;
 	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
 	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
 		return ret;
 		return ret;
 	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
 	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
 		return ret;
 		return ret;
-	if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
-		return ret;
-	else if (((u8) ret) & 0x01) {
-		em28xx_warn ("AC97 command still being executed: not handled properly!\n");
+
+	/* Wait up to 50 ms for AC97 command to complete */
+	for (i = 0; i < 10; i++) {
+		if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
+			return ret;
+		if (!((u8) ret) & 0x01)
+			return 0;
+		msleep(5);
 	}
 	}
+	em28xx_warn ("AC97 command still being executed: not handled properly!\n");
 	return 0;
 	return 0;
 }
 }
 
 
-int em28xx_set_audio_source(struct em28xx *dev)
+static int em28xx_set_audio_source(struct em28xx *dev)
 {
 {
 	static char *enable  = "\x08\x08";
 	static char *enable  = "\x08\x08";
 	static char *disable = "\x08\x88";
 	static char *disable = "\x08\x88";
 	char *video = enable, *line = disable;
 	char *video = enable, *line = disable;
-	int ret, no_ac97;
+	int ret;
 	u8 input;
 	u8 input;
 
 
 	if (dev->is_em2800) {
 	if (dev->is_em2800) {
@@ -293,11 +300,9 @@ int em28xx_set_audio_source(struct em28xx *dev)
 		switch (dev->ctl_ainput) {
 		switch (dev->ctl_ainput) {
 		case EM28XX_AMUX_VIDEO:
 		case EM28XX_AMUX_VIDEO:
 			input = EM28XX_AUDIO_SRC_TUNER;
 			input = EM28XX_AUDIO_SRC_TUNER;
-			no_ac97 = 1;
 			break;
 			break;
 		case EM28XX_AMUX_LINE_IN:
 		case EM28XX_AMUX_LINE_IN:
 			input = EM28XX_AUDIO_SRC_LINE;
 			input = EM28XX_AUDIO_SRC_LINE;
-			no_ac97 = 1;
 			break;
 			break;
 		case EM28XX_AMUX_AC97_VIDEO:
 		case EM28XX_AMUX_AC97_VIDEO:
 			input = EM28XX_AUDIO_SRC_LINE;
 			input = EM28XX_AUDIO_SRC_LINE;
@@ -313,12 +318,11 @@ int em28xx_set_audio_source(struct em28xx *dev)
 	ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
 	ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
+	msleep(5);
 
 
-	if (no_ac97)
-		return 0;
-
-	/* Sets AC97 mixer registers */
-
+	/* Sets AC97 mixer registers
+	   This is seems to be needed, even for non-ac97 configs
+	 */
 	ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
 	ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
@@ -337,9 +341,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 	s[0] |= 0x1f - dev->volume;
 	s[0] |= 0x1f - dev->volume;
 	s[1] |= 0x1f - dev->volume;
 	s[1] |= 0x1f - dev->volume;
 
 
-	if (dev->mute)
-		s[1] |= 0x80;
+	/* Mute */
+	s[1] |= 0x80;
 	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
 	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -357,6 +362,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 	/* Selects the proper audio input */
 	/* Selects the proper audio input */
 	ret = em28xx_set_audio_source(dev);
 	ret = em28xx_set_audio_source(dev);
 
 
+	/* Unmute device */
+	if (!dev->mute)
+		s[1] &= ~0x80;
+	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
+
 	return ret;
 	return ret;
 }
 }
 EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
 EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
@@ -667,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb)
 				continue;
 				continue;
 			}
 			}
 			if (urb->iso_frame_desc[i].actual_length >
 			if (urb->iso_frame_desc[i].actual_length >
-						 dev->max_pkt_size) {
+			    urb->iso_frame_desc[i].length) {
 				em28xx_isocdbg("packet bigger than packet size");
 				em28xx_isocdbg("packet bigger than packet size");
 				continue;
 				continue;
 			}
 			}
@@ -713,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 		if (dev->urb[i]) {
 		if (dev->urb[i]) {
 			usb_kill_urb(dev->urb[i]);
 			usb_kill_urb(dev->urb[i]);
-			if (dev->transfer_buffer[i]){
-				usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
+			if (dev->transfer_buffer[i]) {
+				usb_buffer_free(dev->udev,
+						dev->urb[i]->transfer_buffer_length,
+						dev->transfer_buffer[i],
+						dev->urb[i]->transfer_dma);
 			}
 			}
 			usb_free_urb(dev->urb[i]);
 			usb_free_urb(dev->urb[i]);
 		}
 		}
@@ -732,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev)
 {
 {
 	/* change interface to 3 which allows the biggest packet sizes */
 	/* change interface to 3 which allows the biggest packet sizes */
 	int i, errCode;
 	int i, errCode;
-	const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
+	int sb_size;
+
+	em28xx_set_alternate(dev);
+	sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
 
 
 	/* reset streaming vars */
 	/* reset streaming vars */
 	dev->frame_current = NULL;
 	dev->frame_current = NULL;
@@ -741,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev)
 	/* allocate urbs */
 	/* allocate urbs */
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 		struct urb *urb;
 		struct urb *urb;
-		int j, k;
+		int j;
 		/* allocate transfer buffer */
 		/* allocate transfer buffer */
 		urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
 		urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
 		if (!urb){
 		if (!urb){
@@ -749,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev)
 			em28xx_uninit_isoc(dev);
 			em28xx_uninit_isoc(dev);
 			return -ENOMEM;
 			return -ENOMEM;
 		}
 		}
-		dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+		dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size,
+							   GFP_KERNEL,
+							   &urb->transfer_dma);
 		if (!dev->transfer_buffer[i]) {
 		if (!dev->transfer_buffer[i]) {
 			em28xx_errdev
 			em28xx_errdev
 					("unable to allocate %i bytes for transfer buffer %i\n",
 					("unable to allocate %i bytes for transfer buffer %i\n",
@@ -762,22 +780,22 @@ int em28xx_init_isoc(struct em28xx *dev)
 		urb->dev = dev->udev;
 		urb->dev = dev->udev;
 		urb->context = dev;
 		urb->context = dev;
 		urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
 		urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
-		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 		urb->interval = 1;
 		urb->interval = 1;
 		urb->transfer_buffer = dev->transfer_buffer[i];
 		urb->transfer_buffer = dev->transfer_buffer[i];
 		urb->complete = em28xx_isocIrq;
 		urb->complete = em28xx_isocIrq;
 		urb->number_of_packets = EM28XX_NUM_PACKETS;
 		urb->number_of_packets = EM28XX_NUM_PACKETS;
 		urb->transfer_buffer_length = sb_size;
 		urb->transfer_buffer_length = sb_size;
-		for (j = k = 0; j < EM28XX_NUM_PACKETS;
-				j++, k += dev->max_pkt_size) {
-			urb->iso_frame_desc[j].offset = k;
-			urb->iso_frame_desc[j].length =
-				dev->max_pkt_size;
+		for (j = 0; j < EM28XX_NUM_PACKETS; j++) {
+			urb->iso_frame_desc[j].offset = j * dev->max_pkt_size;
+			urb->iso_frame_desc[j].length = dev->max_pkt_size;
 		}
 		}
 		dev->urb[i] = urb;
 		dev->urb[i] = urb;
 	}
 	}
 
 
 	/* submit urbs */
 	/* submit urbs */
+	em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n",
+		       EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size);
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
 		errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
 		errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
 		if (errCode) {
 		if (errCode) {
@@ -794,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev)
 int em28xx_set_alternate(struct em28xx *dev)
 int em28xx_set_alternate(struct em28xx *dev)
 {
 {
 	int errCode, prev_alt = dev->alt;
 	int errCode, prev_alt = dev->alt;
-	dev->alt = alt;
-	if (dev->alt == 0) {
-		int i;
-		for(i=0;i< dev->num_alt; i++)
-			if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
-				dev->alt=i;
-	}
+	int i;
+	unsigned int min_pkt_size = dev->bytesperline+4;
+
+	/* When image size is bigger than a ceirtain value,
+	   the frame size should be increased, otherwise, only
+	   green screen will be received.
+	 */
+	if (dev->frame_size > 720*240*2)
+		min_pkt_size *= 2;
+
+	for (i = 0; i < dev->num_alt; i++)
+		if (dev->alt_max_pkt_size[i] >= min_pkt_size)
+			break;
+	dev->alt = i;
 
 
 	if (dev->alt != prev_alt) {
 	if (dev->alt != prev_alt) {
+		em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
+				min_pkt_size, dev->alt);
 		dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
 		dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
-		em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
-		       dev->max_pkt_size);
+		em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
+			       dev->alt, dev->max_pkt_size);
 		errCode = usb_set_interface(dev->udev, 0, dev->alt);
 		errCode = usb_set_interface(dev->udev, 0, dev->alt);
 		if (errCode < 0) {
 		if (errCode < 0) {
 			em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
 			em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
-							dev->alt, errCode);
+					dev->alt, errCode);
 			return errCode;
 			return errCode;
 		}
 		}
 	}
 	}

+ 72 - 7
drivers/media/video/em28xx/em28xx-video.c

@@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
 		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
 		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
 	}
 	}
 
 
-	em28xx_set_audio_source(dev);
+	em28xx_audio_analog_set(dev);
 }
 }
 
 
 /* Usage lock check functions */
 /* Usage lock check functions */
@@ -830,6 +830,63 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int em28xx_reg_len(int reg)
+{
+	switch (reg) {
+	case AC97LSB_REG:
+	case HSCALELOW_REG:
+	case VSCALELOW_REG:
+		return 2;
+	default:
+		return 1;
+	}
+}
+
+static int vidioc_g_register(struct file *file, void *priv,
+			     struct v4l2_register *reg)
+{
+	struct em28xx_fh      *fh  = priv;
+	struct em28xx         *dev = fh->dev;
+	int ret;
+
+	if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+		return -EINVAL;
+
+	if (em28xx_reg_len(reg->reg) == 1) {
+		ret = em28xx_read_reg(dev, reg->reg);
+		if (ret < 0)
+			return ret;
+
+		reg->val = ret;
+	} else {
+		u64 val = 0;
+		ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
+						   reg->reg, (char *)&val, 2);
+		if (ret < 0)
+			return ret;
+
+		reg->val = cpu_to_le64((__u64)val);
+	}
+
+	return 0;
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+			     struct v4l2_register *reg)
+{
+	struct em28xx_fh      *fh  = priv;
+	struct em28xx         *dev = fh->dev;
+	u64 buf;
+
+	buf = le64_to_cpu((__u64)reg->val);
+
+	return em28xx_write_regs(dev, reg->reg, (char *)&buf,
+				 em28xx_reg_len(reg->reg));
+}
+#endif
+
+
 static int vidioc_cropcap(struct file *file, void *priv,
 static int vidioc_cropcap(struct file *file, void *priv,
 					struct v4l2_cropcap *cc)
 					struct v4l2_cropcap *cc)
 {
 {
@@ -1295,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
 	filp->private_data = fh;
 	filp->private_data = fh;
 
 
 	if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
 	if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
-		em28xx_set_alternate(dev);
-
 		dev->width = norm_maxw(dev);
 		dev->width = norm_maxw(dev);
 		dev->height = norm_maxh(dev);
 		dev->height = norm_maxh(dev);
 		dev->frame_size = dev->width * dev->height * 2;
 		dev->frame_size = dev->width * dev->height * 2;
@@ -1305,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
 		dev->hscale = 0;
 		dev->hscale = 0;
 		dev->vscale = 0;
 		dev->vscale = 0;
 
 
+		em28xx_set_alternate(dev);
 		em28xx_capture_start(dev, 1);
 		em28xx_capture_start(dev, 1);
 		em28xx_resolution_set(dev);
 		em28xx_resolution_set(dev);
 
 
@@ -1730,6 +1786,10 @@ static const struct video_device em28xx_video_template = {
 	.vidioc_s_tuner             = vidioc_s_tuner,
 	.vidioc_s_tuner             = vidioc_s_tuner,
 	.vidioc_g_frequency         = vidioc_g_frequency,
 	.vidioc_g_frequency         = vidioc_g_frequency,
 	.vidioc_s_frequency         = vidioc_s_frequency,
 	.vidioc_s_frequency         = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register          = vidioc_g_register,
+	.vidioc_s_register          = vidioc_s_register,
+#endif
 
 
 	.tvnorms                    = V4L2_STD_ALL,
 	.tvnorms                    = V4L2_STD_ALL,
 	.current_norm               = V4L2_STD_PAL,
 	.current_norm               = V4L2_STD_PAL,
@@ -1752,6 +1812,10 @@ static struct video_device em28xx_radio_template = {
 	.vidioc_s_ctrl        = vidioc_s_ctrl,
 	.vidioc_s_ctrl        = vidioc_s_ctrl,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register    = vidioc_g_register,
+	.vidioc_s_register    = vidioc_s_register,
+#endif
 };
 };
 
 
 /******************************** usb interface *****************************************/
 /******************************** usb interface *****************************************/
@@ -1796,10 +1860,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
 }
 }
 EXPORT_SYMBOL(em28xx_unregister_extension);
 EXPORT_SYMBOL(em28xx_unregister_extension);
 
 
-struct video_device *em28xx_vdev_init(struct em28xx *dev,
-				      const struct video_device *template,
-				      const int type,
-				      const char *type_name)
+static struct video_device *em28xx_vdev_init(struct em28xx *dev,
+					     const struct video_device *template,
+					     const int type,
+					     const char *type_name)
 {
 {
 	struct video_device *vfd;
 	struct video_device *vfd;
 
 
@@ -2064,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 	snprintf(dev->name, 29, "em28xx #%d", nr);
 	snprintf(dev->name, 29, "em28xx #%d", nr);
 	dev->devno = nr;
 	dev->devno = nr;
 	dev->model = id->driver_info;
 	dev->model = id->driver_info;
+	dev->alt   = -1;
 
 
 	/* Checks if audio is provided by some interface */
 	/* Checks if audio is provided by some interface */
 	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
 	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {

+ 1 - 4
drivers/media/video/em28xx/em28xx.h

@@ -33,7 +33,7 @@
 #define UNSET -1
 #define UNSET -1
 
 
 /* maximum number of em28xx boards */
 /* maximum number of em28xx boards */
-#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
+#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 
 
 /* maximum number of frames that can be queued */
 /* maximum number of frames that can be queued */
 #define EM28XX_NUM_FRAMES 5
 #define EM28XX_NUM_FRAMES 5
@@ -345,9 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg);
 int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
 int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
 			  int len);
 			  int len);
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
-			  u8 bitmask);
-int em28xx_set_audio_source(struct em28xx *dev);
 int em28xx_audio_analog_set(struct em28xx *dev);
 int em28xx_audio_analog_set(struct em28xx *dev);
 
 
 int em28xx_colorlevels_set_default(struct em28xx *dev);
 int em28xx_colorlevels_set_default(struct em28xx *dev);

+ 111 - 12
drivers/media/video/saa7134/saa7134-cards.c

@@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = {
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask	= 0x03,
 		.inputs         = {{
 		.inputs         = {{
 			.name = name_tv,
 			.name = name_tv,
 			.vmux = 1,
 			.vmux = 1,
 			.amux = TV,
 			.amux = TV,
 			.tv   = 1,
 			.tv   = 1,
-		},{
+			.gpio = 0x00,
+		}, {
 			.name = name_comp1,
 			.name = name_comp1,
-			.vmux = 0,
-			.amux = LINE2,
-		},{
-			.name = name_comp2,
 			.vmux = 3,
 			.vmux = 3,
-			.amux = LINE2,
-		},{
+			.amux = LINE1,
+			.gpio = 0x02,
+		}, {
+			.name = name_comp2,
+			.vmux = 0,
+			.amux = LINE1,
+			.gpio = 0x02,
+		}, {
 			.name = name_svideo,
 			.name = name_svideo,
 			.vmux = 8,
 			.vmux = 8,
-			.amux = LINE2,
-		}},
+			.amux = LINE1,
+			.gpio = 0x02,
+		} },
 		.radio = {
 		.radio = {
 			.name = name_radio,
 			.name = name_radio,
-			.amux = LINE2,
+			.amux = LINE1,
+			.gpio = 0x01,
+		},
+		.mute  = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x00,
 		},
 		},
 	},
 	},
 	[SAA7134_BOARD_BMK_MPEX_TUNER] = {
 	[SAA7134_BOARD_BMK_MPEX_TUNER] = {
@@ -3912,6 +3923,74 @@ struct saa7134_board saa7134_boards[] = {
 		},
 		},
 		.mpeg  = SAA7134_MPEG_EMPRESS,
 		.mpeg  = SAA7134_MPEG_EMPRESS,
 	},
 	},
+	[SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
+		.name           = "Twinhan Hybrid DTV-DVB 3056 PCI",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tuner_config   = 2,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.gpiomask       = 0x0200000,
+		.inputs = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+		}, {
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+		}, {
+			.name   = name_svideo,
+			.vmux   = 8,		/* untested */
+			.amux   = LINE1,
+		} },
+		.radio = {
+			.name   = name_radio,
+			.amux   = TV,
+			.gpio   = 0x0200000,
+		},
+	},
+	[SAA7134_BOARD_GENIUS_TVGO_A11MCE] = {
+		/* Adrian Pardini <pardo.bsso@gmail.com> */
+		.name		= "Genius TVGO AM11MCE",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_TNF_5335MF,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask       = 0xf000,
+		.inputs         = {{
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.gpio = 0x0000,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x2000,
+			.tv = 1
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+			.gpio = 0x2000,
+	} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+			.gpio = 0x1000,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE2,
+			.gpio = 0x6000,
+		},
+	},
 };
 };
 
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -4509,6 +4588,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subdevice    = 0x3502,  /* whats the difference to 0x3306 ?*/
 		.subdevice    = 0x3502,  /* whats the difference to 0x3306 ?*/
 		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
 		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
 	},{
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x5168,
+		.subdevice    = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
+		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+	}, {
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x16be,
 		.subvendor    = 0x16be,
@@ -4521,6 +4606,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subdevice    = 0x0008,
 		.subdevice    = 0x0008,
 		.driver_data  = SAA7134_BOARD_MEDION_MD8800_QUADRO,
 		.driver_data  = SAA7134_BOARD_MEDION_MD8800_QUADRO,
 	},{
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x16be,
+		.subdevice    = 0x000d, /* triple CTX948_V1.1.1 */
+		.driver_data  = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+	}, {
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x1461,
 		.subvendor    = 0x1461,
@@ -4843,7 +4934,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x4e42,
 		.subvendor    = 0x4e42,
 		.subdevice    = 0x3502,
 		.subdevice    = 0x3502,
-		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS
+		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1822, /*Twinhan Technology Co. Ltd*/
+		.subdevice    = 0x0022,
+		.driver_data  = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
 	},{
 	},{
 		/* --- boards without eeprom + subsystem ID --- */
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -4995,6 +5092,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_505FM:
 	case SAA7134_BOARD_BEHOLD_505FM:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
+	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
 	case SAA7134_BOARD_FLYDVBS_LR300:
@@ -5232,7 +5330,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
-       case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
 		/* this is a hybrid board, initialize to analog mode
 		/* this is a hybrid board, initialize to analog mode
 		 * and configure firmware eeprom address
 		 * and configure firmware eeprom address
 		 */
 		 */

+ 24 - 4
drivers/media/video/saa7134/saa7134-dvb.c

@@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = {
 	.request_firmware = philips_tda1004x_request_firmware
 	.request_firmware = philips_tda1004x_request_firmware
 };
 };
 
 
+static struct tda1004x_config twinhan_dtv_dvb_3056_config = {
+	.demod_address = 0x08,
+	.invert        = 1,
+	.invert_oclk   = 0,
+	.xtal_freq     = TDA10046_XTAL_16M,
+	.agc_config    = TDA10046_AGC_TDA827X,
+	.gpio_config   = TDA10046_GP01_I,
+	.if_freq       = TDA10046_FREQ_045,
+	.i2c_gate      = 0x42,
+	.tuner_address = 0x61,
+	.tuner_config  = 2,
+	.antenna_switch = 1,
+	.request_firmware = philips_tda1004x_request_firmware
+};
+
 /* ------------------------------------------------------------------
 /* ------------------------------------------------------------------
  * special case: this card uses saa713x GPIO22 for the mode switch
  * special case: this card uses saa713x GPIO22 for the mode switch
  */
  */
@@ -826,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = {
 static struct tda10086_config flydvbs = {
 static struct tda10086_config flydvbs = {
 	.demod_address = 0x0e,
 	.demod_address = 0x0e,
 	.invert = 0,
 	.invert = 0,
+	.diseqc_tone = 0,
 };
 };
 
 
 /* ==================================================================
 /* ==================================================================
@@ -940,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev)
 		configure_tda827x_fe(dev, &tda827x_lifeview_config);
 		configure_tda827x_fe(dev, &tda827x_lifeview_config);
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVB_TRIO:
 	case SAA7134_BOARD_FLYDVB_TRIO:
-		if(! use_frontend) {	//terrestrial
+		if(! use_frontend) {	/* terrestrial */
 			configure_tda827x_fe(dev, &lifeview_trio_config);
 			configure_tda827x_fe(dev, &lifeview_trio_config);
-		} else {  	      //satellite
+		} else {  	        /* satellite */
 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			if (dev->dvb.frontend) {
 			if (dev->dvb.frontend) {
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
@@ -1007,8 +1023,9 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 		}
 		break;
 		break;
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
-		dev->dvb.frontend = tda10046_attach(&medion_cardbus,
-						    &dev->i2c_adap);
+		dev->dvb.frontend = dvb_attach(tda10046_attach,
+					       &medion_cardbus,
+					       &dev->i2c_adap);
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
 			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
 			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
 			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
 			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
@@ -1044,6 +1061,9 @@ static int dvb_init(struct saa7134_dev *dev)
 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
 		configure_tda827x_fe(dev, &avermedia_super_007_config);
 		configure_tda827x_fe(dev, &avermedia_super_007_config);
 		break;
 		break;
+	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
+		configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config);
+		break;
 	default:
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		wprintk("Huh? unknown DVB card?\n");
 		break;
 		break;

+ 2 - 4
drivers/media/video/saa7134/saa7134-empress.c

@@ -87,7 +87,7 @@ static int ts_open(struct inode *inode, struct file *file)
 
 
 	dprintk("open minor=%d\n",minor);
 	dprintk("open minor=%d\n",minor);
 	err = -EBUSY;
 	err = -EBUSY;
-	if (!mutex_trylock(&dev->empress_tsq.lock))
+	if (!mutex_trylock(&dev->empress_tsq.vb_lock))
 		goto done;
 		goto done;
 	if (dev->empress_users)
 	if (dev->empress_users)
 		goto done_up;
 		goto done_up;
@@ -101,7 +101,7 @@ static int ts_open(struct inode *inode, struct file *file)
 	err = 0;
 	err = 0;
 
 
 done_up:
 done_up:
-	mutex_unlock(&dev->empress_tsq.lock);
+	mutex_unlock(&dev->empress_tsq.vb_lock);
 done:
 done:
 	return err;
 	return err;
 }
 }
@@ -110,7 +110,6 @@ static int ts_release(struct inode *inode, struct file *file)
 {
 {
 	struct saa7134_dev *dev = file->private_data;
 	struct saa7134_dev *dev = file->private_data;
 
 
-	mutex_lock(&dev->empress_tsq.lock);
 	videobuf_stop(&dev->empress_tsq);
 	videobuf_stop(&dev->empress_tsq);
 	videobuf_mmap_free(&dev->empress_tsq);
 	videobuf_mmap_free(&dev->empress_tsq);
 	dev->empress_users--;
 	dev->empress_users--;
@@ -122,7 +121,6 @@ static int ts_release(struct inode *inode, struct file *file)
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
 		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
 		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
 
 
-	mutex_unlock(&dev->empress_tsq.lock);
 	return 0;
 	return 0;
 }
 }
 
 

+ 6 - 0
drivers/media/video/saa7134/saa7134-input.c

@@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 		mask_keyup   = 0x8000000;
 		mask_keyup   = 0x8000000;
 		polling      = 50; //ms
 		polling      = 50; //ms
 		break;
 		break;
+	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
+		ir_codes     = ir_codes_genius_tvgo_a11mce;
+		mask_keycode = 0xff;
+		mask_keydown = 0xf00000;
+		polling = 50; /* ms */
+		break;
 	}
 	}
 	if (NULL == ir_codes) {
 	if (NULL == ir_codes) {
 		printk("%s: Oops: IR config error [card=%d]\n",
 		printk("%s: Oops: IR config error [card=%d]\n",

+ 10 - 10
drivers/media/video/saa7134/saa7134-video.c

@@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 		if (!list_empty(&fh->cap.stream))
 		if (!list_empty(&fh->cap.stream))
 			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
 			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
 	} else {
 	} else {
-		mutex_lock(&fh->cap.lock);
+		mutex_lock(&fh->cap.vb_lock);
 		if (UNSET == fh->cap.read_off) {
 		if (UNSET == fh->cap.read_off) {
 			/* need to capture a new frame */
 			/* need to capture a new frame */
-			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
-				mutex_unlock(&fh->cap.lock);
-				return POLLERR;
-			}
-			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
-				mutex_unlock(&fh->cap.lock);
-				return POLLERR;
-			}
+			if (res_locked(fh->dev,RESOURCE_VIDEO))
+				goto err;
+			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
+				goto err;
 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
 			fh->cap.read_off = 0;
 			fh->cap.read_off = 0;
 		}
 		}
-		mutex_unlock(&fh->cap.lock);
+		mutex_unlock(&fh->cap.vb_lock);
 		buf = fh->cap.read_buf;
 		buf = fh->cap.read_buf;
 	}
 	}
 
 
@@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 	    buf->state == VIDEOBUF_ERROR)
 	    buf->state == VIDEOBUF_ERROR)
 		return POLLIN|POLLRDNORM;
 		return POLLIN|POLLRDNORM;
 	return 0;
 	return 0;
+
+err:
+	mutex_unlock(&fh->cap.vb_lock);
+	return POLLERR;
 }
 }
 
 
 static int video_release(struct inode *inode, struct file *file)
 static int video_release(struct inode *inode, struct file *file)

+ 2 - 0
drivers/media/video/saa7134/saa7134.h

@@ -252,6 +252,8 @@ struct saa7134_format {
 #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
 #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
 #define SAA7134_BOARD_BEHOLD_607_9FM	129
 #define SAA7134_BOARD_BEHOLD_607_9FM	129
 #define SAA7134_BOARD_BEHOLD_M6		130
 #define SAA7134_BOARD_BEHOLD_M6		130
+#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
+#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
 
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
 #define SAA7134_INPUT_MAX 8

+ 20 - 3
drivers/media/video/stk-sensor.c

@@ -225,7 +225,7 @@
 
 
 
 
 /* Returns 0 if OK */
 /* Returns 0 if OK */
-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
+static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
 {
 {
 	int i = 0;
 	int i = 0;
 	int tmpval = 0;
 	int tmpval = 0;
@@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
 		return 0;
 		return 0;
 }
 }
 
 
-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
+static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
 {
 {
 	int i = 0;
 	int i = 0;
 	int tmpval = 0;
 	int tmpval = 0;
@@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev)
 		STK_ERROR("Strange error reading sensor ID\n");
 		STK_ERROR("Strange error reading sensor ID\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
-	if (idh != 0x7F || idl != 0xA2) {
+	if (idh != 0x7f || idl != 0xa2) {
 		STK_ERROR("Huh? you don't have a sensor from ovt\n");
 		STK_ERROR("Huh? you don't have a sensor from ovt\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = {
 	{REG_COM15, COM15_R00FF },
 	{REG_COM15, COM15_R00FF },
 	{0xff, 0xff}, /* END MARKER */
 	{0xff, 0xff}, /* END MARKER */
 };
 };
+/* V4L2_PIX_FMT_YUYV */
+static struct regval ov_fmt_yuyv[] = {
+	{REG_TSLB, 0 },
+	{ 0x4f, 0x80 }, 	/* "matrix coefficient 1" */
+	{ 0x50, 0x80 }, 	/* "matrix coefficient 2" */
+	{ 0x51, 0    },		/* vb */
+	{ 0x52, 0x22 }, 	/* "matrix coefficient 4" */
+	{ 0x53, 0x5e }, 	/* "matrix coefficient 5" */
+	{ 0x54, 0x80 }, 	/* "matrix coefficient 6" */
+	{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
+	{REG_COM15, COM15_R00FF },
+	{0xff, 0xff}, /* END MARKER */
+};
 
 
 /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
 /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
 static struct regval ov_fmt_rgbr[] = {
 static struct regval ov_fmt_rgbr[] = {
@@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev)
 		com7 |= COM7_YUV;
 		com7 |= COM7_YUV;
 		rv = ov_fmt_uyvy;
 		rv = ov_fmt_uyvy;
 		break;
 		break;
+	case V4L2_PIX_FMT_YUYV:
+		com7 |= COM7_YUV;
+		rv = ov_fmt_yuyv;
+		break;
 	case V4L2_PIX_FMT_RGB565:
 	case V4L2_PIX_FMT_RGB565:
 		com7 |= COM7_RGB;
 		com7 |= COM7_RGB;
 		rv = ov_fmt_rgbp;
 		rv = ov_fmt_rgbp;

+ 82 - 22
drivers/media/video/stk-webcam.c

@@ -63,7 +63,7 @@ static struct usb_device_id stkwebcam_table[] = {
 };
 };
 MODULE_DEVICE_TABLE(usb, stkwebcam_table);
 MODULE_DEVICE_TABLE(usb, stkwebcam_table);
 
 
-void stk_camera_cleanup(struct kref *kref)
+static void stk_camera_cleanup(struct kref *kref)
 {
 {
 	struct stk_camera *dev = to_stk_camera(kref);
 	struct stk_camera *dev = to_stk_camera(kref);
 
 
@@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
 		return -ENXIO;
 		return -ENXIO;
 	fp->private_data = vdev;
 	fp->private_data = vdev;
 	kref_get(&dev->kref);
 	kref_get(&dev->kref);
+	usb_autopm_get_interface(dev->interface);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
 	}
 	}
 
 
 	if (dev->owner != fp) {
 	if (dev->owner != fp) {
+		usb_autopm_put_interface(dev->interface);
 		kref_put(&dev->kref, stk_camera_cleanup);
 		kref_put(&dev->kref, stk_camera_cleanup);
 		return 0;
 		return 0;
 	}
 	}
@@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
 
 
 	dev->owner = NULL;
 	dev->owner = NULL;
 
 
+	usb_autopm_put_interface(dev->interface);
 	kref_put(&dev->kref, stk_camera_cleanup);
 	kref_put(&dev->kref, stk_camera_cleanup);
 
 
 	return 0;
 	return 0;
@@ -993,6 +996,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp,
 		fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
 		fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
 		strcpy(fmtd->description, "Raw bayer");
 		strcpy(fmtd->description, "Raw bayer");
 		break;
 		break;
+	case 4:
+		fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
+		strcpy(fmtd->description, "yuv4:2:2");
+		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1048,6 +1055,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
 	case V4L2_PIX_FMT_RGB565:
 	case V4L2_PIX_FMT_RGB565:
 	case V4L2_PIX_FMT_RGB565X:
 	case V4L2_PIX_FMT_RGB565X:
 	case V4L2_PIX_FMT_UYVY:
 	case V4L2_PIX_FMT_UYVY:
+	case V4L2_PIX_FMT_YUYV:
 	case V4L2_PIX_FMT_SBGGR8:
 	case V4L2_PIX_FMT_SBGGR8:
 		break;
 		break;
 	default:
 	default:
@@ -1080,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
 	return 0;
 	return 0;
 }
 }
 
 
+static int stk_setup_format(struct stk_camera *dev)
+{
+	int i = 0;
+	int depth;
+	if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
+		depth = 1;
+	else
+		depth = 2;
+	while (stk_sizes[i].m != dev->vsettings.mode
+			&& i < ARRAY_SIZE(stk_sizes))
+		i++;
+	if (i == ARRAY_SIZE(stk_sizes)) {
+		STK_ERROR("Something is broken in %s\n", __FUNCTION__);
+		return -EFAULT;
+	}
+	/* This registers controls some timings, not sure of what. */
+	stk_camera_write_reg(dev, 0x001b, 0x0e);
+	if (dev->vsettings.mode == MODE_SXGA)
+		stk_camera_write_reg(dev, 0x001c, 0x0e);
+	else
+		stk_camera_write_reg(dev, 0x001c, 0x46);
+	/*
+	 * Registers 0x0115 0x0114 are the size of each line (bytes),
+	 * regs 0x0117 0x0116 are the heigth of the image.
+	 */
+	stk_camera_write_reg(dev, 0x0115,
+		((stk_sizes[i].w * depth) >> 8) & 0xff);
+	stk_camera_write_reg(dev, 0x0114,
+		(stk_sizes[i].w * depth) & 0xff);
+	stk_camera_write_reg(dev, 0x0117,
+		(stk_sizes[i].h >> 8) & 0xff);
+	stk_camera_write_reg(dev, 0x0116,
+		stk_sizes[i].h & 0xff);
+	return stk_sensor_configure(dev);
+}
+
 static int stk_vidioc_s_fmt_cap(struct file *filp,
 static int stk_vidioc_s_fmt_cap(struct file *filp,
 		void *priv, struct v4l2_format *fmtd)
 		void *priv, struct v4l2_format *fmtd)
 {
 {
@@ -1094,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
 		return -EBUSY;
 		return -EBUSY;
 	if (dev->owner && dev->owner != filp)
 	if (dev->owner && dev->owner != filp)
 		return -EBUSY;
 		return -EBUSY;
-	dev->owner = filp;
 	ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
 	ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
+	dev->owner = filp;
 
 
 	dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
 	dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
 	stk_free_buffers(dev);
 	stk_free_buffers(dev);
@@ -1105,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
 	dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
 	dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
 
 
 	stk_initialise(dev);
 	stk_initialise(dev);
-	/* This registers controls some timings, not sure of what. */
-	stk_camera_write_reg(dev, 0x001b, 0x0e);
-	if (dev->vsettings.mode == MODE_SXGA)
-		stk_camera_write_reg(dev, 0x001c, 0x0e);
-	else
-		stk_camera_write_reg(dev, 0x001c, 0x46);
-	/*
-	 * Registers 0x0115 0x0114 are the size of each line (bytes),
-	 * regs 0x0117 0x0116 are the heigth of the image.
-	 */
-	stk_camera_write_reg(dev, 0x0115,
-		(fmtd->fmt.pix.bytesperline >> 8) & 0xff);
-	stk_camera_write_reg(dev, 0x0114,
-		fmtd->fmt.pix.bytesperline & 0xff);
-	stk_camera_write_reg(dev, 0x0117,
-		(fmtd->fmt.pix.height >> 8) & 0xff);
-	stk_camera_write_reg(dev, 0x0116,
-		fmtd->fmt.pix.height & 0xff);
-	return stk_sensor_configure(dev);
+	return stk_setup_format(dev);
 }
 }
 
 
 static int stk_vidioc_reqbufs(struct file *filp,
 static int stk_vidioc_reqbufs(struct file *filp,
@@ -1288,6 +1314,9 @@ static struct file_operations v4l_stk_fops = {
 	.poll = v4l_stk_poll,
 	.poll = v4l_stk_poll,
 	.mmap = v4l_stk_mmap,
 	.mmap = v4l_stk_mmap,
 	.ioctl = video_ioctl2,
 	.ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = v4l_compat_ioctl32,
+#endif
 	.llseek = no_llseek
 	.llseek = no_llseek
 };
 };
 
 
@@ -1403,7 +1432,7 @@ static int stk_camera_probe(struct usb_interface *interface,
 	dev->vsettings.brightness = 0x7fff;
 	dev->vsettings.brightness = 0x7fff;
 	dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
 	dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
 	dev->vsettings.mode = MODE_VGA;
 	dev->vsettings.mode = MODE_VGA;
-	dev->frame_size = 640*480*2;
+	dev->frame_size = 640 * 480 * 2;
 
 
 	INIT_LIST_HEAD(&dev->sio_avail);
 	INIT_LIST_HEAD(&dev->sio_avail);
 	INIT_LIST_HEAD(&dev->sio_full);
 	INIT_LIST_HEAD(&dev->sio_full);
@@ -1417,6 +1446,7 @@ static int stk_camera_probe(struct usb_interface *interface,
 	}
 	}
 
 
 	stk_create_sysfs_files(&dev->vdev);
 	stk_create_sysfs_files(&dev->vdev);
+	usb_autopm_enable(dev->interface);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1434,11 +1464,41 @@ static void stk_camera_disconnect(struct usb_interface *interface)
 	kref_put(&dev->kref, stk_camera_cleanup);
 	kref_put(&dev->kref, stk_camera_cleanup);
 }
 }
 
 
+#ifdef CONFIG_PM
+int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct stk_camera *dev = usb_get_intfdata(intf);
+	if (is_streaming(dev)) {
+		stk_stop_stream(dev);
+		/* yes, this is ugly */
+		set_streaming(dev);
+	}
+	return 0;
+}
+
+int stk_camera_resume(struct usb_interface *intf)
+{
+	struct stk_camera *dev = usb_get_intfdata(intf);
+	if (!is_initialised(dev))
+		return 0;
+	unset_initialised(dev);
+	stk_initialise(dev);
+	stk_setup_format(dev);
+	if (is_streaming(dev))
+		stk_start_stream(dev);
+	return 0;
+}
+#endif
+
 static struct usb_driver stk_camera_driver = {
 static struct usb_driver stk_camera_driver = {
 	.name = "stkwebcam",
 	.name = "stkwebcam",
 	.probe = stk_camera_probe,
 	.probe = stk_camera_probe,
 	.disconnect = stk_camera_disconnect,
 	.disconnect = stk_camera_disconnect,
 	.id_table = stkwebcam_table,
 	.id_table = stkwebcam_table,
+#ifdef CONFIG_PM
+	.suspend = stk_camera_suspend,
+	.resume = stk_camera_resume,
+#endif
 };
 };
 
 
 
 

+ 1 - 2
drivers/media/video/stk-webcam.h

@@ -79,6 +79,7 @@ enum stk_status {
 #define unset_present(dev)	((dev)->status &= \
 #define unset_present(dev)	((dev)->status &= \
 					~(S_PRESENT|S_INITIALISED|S_STREAMING))
 					~(S_PRESENT|S_INITIALISED|S_STREAMING))
 #define set_initialised(dev)	((dev)->status |= S_INITIALISED)
 #define set_initialised(dev)	((dev)->status |= S_INITIALISED)
+#define unset_initialised(dev)	((dev)->status &= ~S_INITIALISED)
 #define set_memallocd(dev)	((dev)->status |= S_MEMALLOCD)
 #define set_memallocd(dev)	((dev)->status |= S_MEMALLOCD)
 #define unset_memallocd(dev)	((dev)->status &= ~S_MEMALLOCD)
 #define unset_memallocd(dev)	((dev)->status &= ~S_MEMALLOCD)
 #define set_streaming(dev)	((dev)->status |= S_STREAMING)
 #define set_streaming(dev)	((dev)->status |= S_STREAMING)
@@ -127,8 +128,6 @@ void stk_camera_delete(struct kref *);
 int stk_camera_write_reg(struct stk_camera *, u16, u8);
 int stk_camera_write_reg(struct stk_camera *, u16, u8);
 int stk_camera_read_reg(struct stk_camera *, u16, int *);
 int stk_camera_read_reg(struct stk_camera *, u16, int *);
 
 
-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val);
-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val);
 int stk_sensor_init(struct stk_camera *);
 int stk_sensor_init(struct stk_camera *);
 int stk_sensor_configure(struct stk_camera *);
 int stk_sensor_configure(struct stk_camera *);
 int stk_sensor_sleep(struct stk_camera *dev);
 int stk_sensor_sleep(struct stk_camera *dev);

+ 1 - 1
drivers/media/video/tcm825x.c

@@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client)
 	sensor->platform_data = client->dev.platform_data;
 	sensor->platform_data = client->dev.platform_data;
 
 
 	if (sensor->platform_data == NULL
 	if (sensor->platform_data == NULL
-	    && !sensor->platform_data->is_okay())
+	    || !sensor->platform_data->is_okay())
 		return -ENODEV;
 		return -ENODEV;
 
 
 	sensor->v4l2_int_device = &tcm825x_int_device;
 	sensor->v4l2_int_device = &tcm825x_int_device;

+ 1 - 1
drivers/media/video/tuner-core.c

@@ -1038,7 +1038,7 @@ static int tuner_resume(struct i2c_client *c)
 
 
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 
 
-LIST_HEAD(tuner_list);
+static LIST_HEAD(tuner_list);
 
 
 /* Search for existing radio and/or TV tuners on the given I2C adapter.
 /* Search for existing radio and/or TV tuners on the given I2C adapter.
    Note that when this function is called from tuner_probe you can be
    Note that when this function is called from tuner_probe you can be

+ 3 - 0
drivers/media/video/tuner-xc2028.c

@@ -754,6 +754,9 @@ skip_std_specific:
 		goto check_device;
 		goto check_device;
 	}
 	}
 
 
+	if (new_fw.type & FM)
+		goto check_device;
+
 	/* Load SCODE firmware, if exists */
 	/* Load SCODE firmware, if exists */
 	tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
 	tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
 
 

+ 5 - 5
drivers/media/video/tvaudio.c

@@ -1571,14 +1571,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
 		ctrl->value=chip->muted;
 		ctrl->value=chip->muted;
 		return 0;
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_VOLUME:
-		if (!desc->flags & CHIP_HAS_VOLUME)
+		if (!(desc->flags & CHIP_HAS_VOLUME))
 			break;
 			break;
 		ctrl->value = max(chip->left,chip->right);
 		ctrl->value = max(chip->left,chip->right);
 		return 0;
 		return 0;
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BALANCE:
 	{
 	{
 		int volume;
 		int volume;
-		if (!desc->flags & CHIP_HAS_VOLUME)
+		if (!(desc->flags & CHIP_HAS_VOLUME))
 			break;
 			break;
 		volume = max(chip->left,chip->right);
 		volume = max(chip->left,chip->right);
 		if (volume)
 		if (volume)
@@ -1621,7 +1621,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
 	{
 	{
 		int volume,balance;
 		int volume,balance;
 
 
-		if (!desc->flags & CHIP_HAS_VOLUME)
+		if (!(desc->flags & CHIP_HAS_VOLUME))
 			break;
 			break;
 
 
 		volume = max(chip->left,chip->right);
 		volume = max(chip->left,chip->right);
@@ -1642,7 +1642,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BALANCE:
 	{
 	{
 		int volume, balance;
 		int volume, balance;
-		if (!desc->flags & CHIP_HAS_VOLUME)
+		if (!(desc->flags & CHIP_HAS_VOLUME))
 			break;
 			break;
 
 
 		volume = max(chip->left,chip->right);
 		volume = max(chip->left,chip->right);
@@ -1702,7 +1702,7 @@ static int chip_command(struct i2c_client *client,
 				break;
 				break;
 			case V4L2_CID_AUDIO_VOLUME:
 			case V4L2_CID_AUDIO_VOLUME:
 			case V4L2_CID_AUDIO_BALANCE:
 			case V4L2_CID_AUDIO_BALANCE:
-				if (!desc->flags & CHIP_HAS_VOLUME)
+				if (!(desc->flags & CHIP_HAS_VOLUME))
 					return -EINVAL;
 					return -EINVAL;
 				break;
 				break;
 			case V4L2_CID_AUDIO_BASS:
 			case V4L2_CID_AUDIO_BASS:

+ 1 - 1
drivers/media/video/tveeprom.c

@@ -242,7 +242,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        		"TCL M2523_3DBH_E"},
 	{ TUNER_ABSENT,        		"TCL M2523_3DBH_E"},
 	{ TUNER_ABSENT,        		"TCL M2523_3DIH_E"},
 	{ TUNER_ABSENT,        		"TCL M2523_3DIH_E"},
 	{ TUNER_ABSENT,        		"TCL MFPE05_2_U"},
 	{ TUNER_ABSENT,        		"TCL MFPE05_2_U"},
-	{ TUNER_ABSENT,        		"Philips FMD1216MEX"},
+	{ TUNER_PHILIPS_FMD1216ME_MK3,	"Philips FMD1216MEX"},
 	{ TUNER_ABSENT,        		"Philips FRH2036B"},
 	{ TUNER_ABSENT,        		"Philips FRH2036B"},
 	{ TUNER_ABSENT,        		"Panasonic ENGF75_01GF"},
 	{ TUNER_ABSENT,        		"Panasonic ENGF75_01GF"},
 	{ TUNER_ABSENT,        		"MaxLinear MXL5005"},
 	{ TUNER_ABSENT,        		"MaxLinear MXL5005"},

+ 27 - 366
drivers/media/video/v4l2-common.c

@@ -56,7 +56,6 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/div64.h>
 #include <asm/div64.h>
-#include <linux/video_decoder.h>
 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
@@ -82,108 +81,6 @@ MODULE_LICENSE("GPL");
  */
  */
 
 
 
 
-char *v4l2_norm_to_name(v4l2_std_id id)
-{
-	char *name;
-	u32 myid = id;
-
-	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
-	   64 bit comparations. So, on that architecture, with some gcc variants,
-	   compilation fails. Currently, the max value is 30bit wide.
-	 */
-	BUG_ON(myid != id);
-
-	switch (myid) {
-	case V4L2_STD_PAL:
-		name="PAL";		break;
-	case V4L2_STD_PAL_BG:
-		name="PAL-BG";		break;
-	case V4L2_STD_PAL_DK:
-		name="PAL-DK";		break;
-	case V4L2_STD_PAL_B:
-		name="PAL-B";		break;
-	case V4L2_STD_PAL_B1:
-		name="PAL-B1";		break;
-	case V4L2_STD_PAL_G:
-		name="PAL-G";		break;
-	case V4L2_STD_PAL_H:
-		name="PAL-H";		break;
-	case V4L2_STD_PAL_I:
-		name="PAL-I";		break;
-	case V4L2_STD_PAL_D:
-		name="PAL-D";		break;
-	case V4L2_STD_PAL_D1:
-		name="PAL-D1";		break;
-	case V4L2_STD_PAL_K:
-		name="PAL-K";		break;
-	case V4L2_STD_PAL_M:
-		name="PAL-M";		break;
-	case V4L2_STD_PAL_N:
-		name="PAL-N";		break;
-	case V4L2_STD_PAL_Nc:
-		name="PAL-Nc";		break;
-	case V4L2_STD_PAL_60:
-		name="PAL-60";		break;
-	case V4L2_STD_NTSC:
-		name="NTSC";		break;
-	case V4L2_STD_NTSC_M:
-		name="NTSC-M";		break;
-	case V4L2_STD_NTSC_M_JP:
-		name="NTSC-M-JP";	break;
-	case V4L2_STD_NTSC_443:
-		name="NTSC-443";	break;
-	case V4L2_STD_NTSC_M_KR:
-		name="NTSC-M-KR";	break;
-	case V4L2_STD_SECAM:
-		name="SECAM";		break;
-	case V4L2_STD_SECAM_DK:
-		name="SECAM-DK";	break;
-	case V4L2_STD_SECAM_B:
-		name="SECAM-B";		break;
-	case V4L2_STD_SECAM_D:
-		name="SECAM-D";		break;
-	case V4L2_STD_SECAM_G:
-		name="SECAM-G";		break;
-	case V4L2_STD_SECAM_H:
-		name="SECAM-H";		break;
-	case V4L2_STD_SECAM_K:
-		name="SECAM-K";		break;
-	case V4L2_STD_SECAM_K1:
-		name="SECAM-K1";	break;
-	case V4L2_STD_SECAM_L:
-		name="SECAM-L";		break;
-	case V4L2_STD_SECAM_LC:
-		name="SECAM-LC";	break;
-	default:
-		name="Unknown";		break;
-	}
-
-	return name;
-}
-
-/* Fill in the fields of a v4l2_standard structure according to the
-   'id' and 'transmission' parameters.  Returns negative on error.  */
-int v4l2_video_std_construct(struct v4l2_standard *vs,
-			     int id, char *name)
-{
-	u32 index = vs->index;
-
-	memset(vs, 0, sizeof(struct v4l2_standard));
-	vs->index = index;
-	vs->id    = id;
-	if (id & V4L2_STD_525_60) {
-		vs->frameperiod.numerator = 1001;
-		vs->frameperiod.denominator = 30000;
-		vs->framelines = 525;
-	} else {
-		vs->frameperiod.numerator = 1;
-		vs->frameperiod.denominator = 25;
-		vs->framelines = 625;
-	}
-	strlcpy(vs->name,name,sizeof(vs->name));
-	return 0;
-}
-
 /* ----------------------------------------------------------------- */
 /* ----------------------------------------------------------------- */
 /* priority handling                                                 */
 /* priority handling                                                 */
 
 
@@ -196,6 +93,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global)
 	memset(global,0,sizeof(*global));
 	memset(global,0,sizeof(*global));
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_prio_init);
 
 
 int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
 int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
 		     enum v4l2_priority new)
 		     enum v4l2_priority new)
@@ -211,11 +109,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
 	*local = new;
 	*local = new;
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_prio_change);
 
 
 int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
 int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
 {
 {
 	return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
 	return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
 }
 }
+EXPORT_SYMBOL(v4l2_prio_open);
 
 
 int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
 int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
 {
 {
@@ -223,6 +123,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
 		atomic_dec(&global->prios[*local]);
 		atomic_dec(&global->prios[*local]);
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_prio_close);
 
 
 enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
 enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
 {
 {
@@ -234,6 +135,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
 		return V4L2_PRIORITY_BACKGROUND;
 		return V4L2_PRIORITY_BACKGROUND;
 	return V4L2_PRIORITY_UNSET;
 	return V4L2_PRIORITY_UNSET;
 }
 }
+EXPORT_SYMBOL(v4l2_prio_max);
 
 
 int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
 int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
 {
 {
@@ -241,225 +143,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
 		return -EBUSY;
 		return -EBUSY;
 	return 0;
 	return 0;
 }
 }
-
-
-/* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages of enum types      */
-
-char *v4l2_field_names[] = {
-	[V4L2_FIELD_ANY]        = "any",
-	[V4L2_FIELD_NONE]       = "none",
-	[V4L2_FIELD_TOP]        = "top",
-	[V4L2_FIELD_BOTTOM]     = "bottom",
-	[V4L2_FIELD_INTERLACED] = "interlaced",
-	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
-	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
-	[V4L2_FIELD_ALTERNATE]  = "alternate",
-	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
-	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-
-char *v4l2_type_names[] = {
-	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
-	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
-	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
-	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
-	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
-	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
-};
-
-
-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
-
-/* ------------------------------------------------------------------ */
-/* debug help functions                                               */
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static const char *v4l1_ioctls[] = {
-	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
-	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
-	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
-	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
-	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
-	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
-	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
-	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
-	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
-	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
-	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
-	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
-	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
-	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
-	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
-	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
-	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
-	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
-	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
-	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
-	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
-	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
-	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
-	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
-	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
-	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
-	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
-	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
-	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
-};
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-#endif
-
-static const char *v4l2_ioctls[] = {
-	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
-	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
-	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
-	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
-	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
-	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
-	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
-	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
-	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
-	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
-	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
-	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
-	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
-	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
-	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
-	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
-	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
-	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
-	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
-	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
-	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
-	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
-	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
-	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
-	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
-	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
-	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
-	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
-	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
-	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
-	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
-	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
-	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
-	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
-	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
-	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
-	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
-	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
-	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
-	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
-	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
-	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
-	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
-	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
-	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
-	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
-	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
-	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
-	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
-	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
-	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
-	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
-	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
-	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
-	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
-#if 1
-	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
-	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
-	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
-	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
-	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
-
-	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
-	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
-
-	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
-#endif
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
-	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
-	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
-	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
-	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
-	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
-	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
-	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
-	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
-	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
-	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
-#endif
-	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
-
-	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
-	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
-	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
-
-	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
-	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
-	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
-	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
-	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
-	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
-	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
-	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
-
-/* Common ioctl debug function. This function can be used by
-   external ioctl messages as well as internal V4L ioctl */
-void v4l_printk_ioctl(unsigned int cmd)
-{
-	char *dir;
-
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:              dir = "--"; break;
-	case _IOC_READ:              dir = "r-"; break;
-	case _IOC_WRITE:             dir = "-w"; break;
-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
-	default:                     dir = "*ERR*"; break;
-	}
-	switch (_IOC_TYPE(cmd)) {
-	case 'd':
-		printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
-		       (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
-		       v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
-		break;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	case 'v':
-		printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
-		       (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-		       v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
-		break;
-#endif
-	case 'V':
-		printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
-		       (_IOC_NR(cmd) < V4L2_IOCTLS) ?
-		       v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
-		break;
-
-	default:
-		printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
-		       _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
-	}
-}
-
+EXPORT_SYMBOL(v4l2_prio_check);
 
 
 /* ----------------------------------------------------------------- */
 /* ----------------------------------------------------------------- */
 
 
@@ -488,6 +172,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
 	}
 	}
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_check);
 
 
 /* Returns NULL or a character pointer array containing the menu for
 /* Returns NULL or a character pointer array containing the menu for
    the given control ID. The pointer array ends with a NULL pointer.
    the given control ID. The pointer array ends with a NULL pointer.
@@ -648,6 +333,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
 			return NULL;
 			return NULL;
 	}
 	}
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_get_menu);
 
 
 /* Fill in a struct v4l2_queryctrl */
 /* Fill in a struct v4l2_queryctrl */
 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
@@ -770,6 +456,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
 	snprintf(qctrl->name, sizeof(qctrl->name), name);
 	snprintf(qctrl->name, sizeof(qctrl->name), name);
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 
 
 /* Fill in a struct v4l2_queryctrl with standard values based on
 /* Fill in a struct v4l2_queryctrl with standard values based on
    the control ID. */
    the control ID. */
@@ -904,6 +591,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
 
 
 /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
 /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
    the menu. The qctrl pointer may be NULL, in which case it is ignored. */
    the menu. The qctrl pointer may be NULL, in which case it is ignored. */
@@ -922,6 +610,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
 	qmenu->reserved = 0;
 	qmenu->reserved = 0;
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 
 
 /* ctrl_classes points to an array of u32 pointers, the last element is
 /* ctrl_classes points to an array of u32 pointers, the last element is
    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
@@ -972,7 +661,20 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
 		return 0;
 		return 0;
 	return **ctrl_classes;
 	return **ctrl_classes;
 }
 }
+EXPORT_SYMBOL(v4l2_ctrl_next);
 
 
+int v4l2_chip_match_host(u32 match_type, u32 match_chip)
+{
+	switch (match_type) {
+	case V4L2_CHIP_MATCH_HOST:
+		return match_chip == 0;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(v4l2_chip_match_host);
+
+#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
 int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
 {
 {
 	switch (match_type) {
 	switch (match_type) {
@@ -984,6 +686,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c
 		return 0;
 		return 0;
 	}
 	}
 }
 }
+EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
 
 
 int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
 int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
 		u32 ident, u32 revision)
 		u32 ident, u32 revision)
@@ -1000,16 +703,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi
 	}
 	}
 	return 0;
 	return 0;
 }
 }
-
-int v4l2_chip_match_host(u32 match_type, u32 match_chip)
-{
-	switch (match_type) {
-	case V4L2_CHIP_MATCH_HOST:
-		return match_chip == 0;
-	default:
-		return 0;
-	}
-}
+EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
 
 
 /* ----------------------------------------------------------------- */
 /* ----------------------------------------------------------------- */
 
 
@@ -1038,38 +732,5 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
 	}
 	}
 	return err != -ENOMEM ? 0 : err;
 	return err != -ENOMEM ? 0 : err;
 }
 }
-
-/* ----------------------------------------------------------------- */
-
-EXPORT_SYMBOL(v4l2_norm_to_name);
-EXPORT_SYMBOL(v4l2_video_std_construct);
-
-EXPORT_SYMBOL(v4l2_prio_init);
-EXPORT_SYMBOL(v4l2_prio_change);
-EXPORT_SYMBOL(v4l2_prio_open);
-EXPORT_SYMBOL(v4l2_prio_close);
-EXPORT_SYMBOL(v4l2_prio_max);
-EXPORT_SYMBOL(v4l2_prio_check);
-
-EXPORT_SYMBOL(v4l2_field_names);
-EXPORT_SYMBOL(v4l2_type_names);
-EXPORT_SYMBOL(v4l_printk_ioctl);
-
-EXPORT_SYMBOL(v4l2_ctrl_next);
-EXPORT_SYMBOL(v4l2_ctrl_check);
-EXPORT_SYMBOL(v4l2_ctrl_get_menu);
-EXPORT_SYMBOL(v4l2_ctrl_query_menu);
-EXPORT_SYMBOL(v4l2_ctrl_query_fill);
-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
-
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
 EXPORT_SYMBOL(v4l2_i2c_attach);
 EXPORT_SYMBOL(v4l2_i2c_attach);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+#endif

+ 39 - 39
drivers/media/video/videobuf-core.c

@@ -147,7 +147,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
 	/* Having implementations for abstract methods are mandatory */
 	/* Having implementations for abstract methods are mandatory */
 	BUG_ON(!q->int_ops);
 	BUG_ON(!q->int_ops);
 
 
-	mutex_init(&q->lock);
+	mutex_init(&q->vb_lock);
 	INIT_LIST_HEAD(&q->stream);
 	INIT_LIST_HEAD(&q->stream);
 }
 }
 
 
@@ -189,7 +189,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
 	return 0;
 	return 0;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 void videobuf_queue_cancel(struct videobuf_queue *q)
 void videobuf_queue_cancel(struct videobuf_queue *q)
 {
 {
 	unsigned long flags = 0;
 	unsigned long flags = 0;
@@ -220,7 +220,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
 
 
 /* --------------------------------------------------------------------- */
 /* --------------------------------------------------------------------- */
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
 enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
 {
 {
 	enum v4l2_field field = q->field;
 	enum v4l2_field field = q->field;
@@ -239,7 +239,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
 	return field;
 	return field;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
 static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
 			    struct videobuf_buffer *vb, enum v4l2_buf_type type)
 			    struct videobuf_buffer *vb, enum v4l2_buf_type type)
 {
 {
@@ -295,7 +295,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
 	b->sequence  = vb->field_count >> 1;
 	b->sequence  = vb->field_count >> 1;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static int __videobuf_mmap_free(struct videobuf_queue *q)
 static int __videobuf_mmap_free(struct videobuf_queue *q)
 {
 {
 	int i;
 	int i;
@@ -328,13 +328,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
 int videobuf_mmap_free(struct videobuf_queue *q)
 int videobuf_mmap_free(struct videobuf_queue *q)
 {
 {
 	int ret;
 	int ret;
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	ret = __videobuf_mmap_free(q);
 	ret = __videobuf_mmap_free(q);
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return ret;
 	return ret;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static int __videobuf_mmap_setup(struct videobuf_queue *q,
 static int __videobuf_mmap_setup(struct videobuf_queue *q,
 			unsigned int bcount, unsigned int bsize,
 			unsigned int bcount, unsigned int bsize,
 			enum v4l2_memory memory)
 			enum v4l2_memory memory)
@@ -384,9 +384,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
 			enum v4l2_memory memory)
 			enum v4l2_memory memory)
 {
 {
 	int ret;
 	int ret;
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
 	ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -408,7 +408,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	if (req->type != q->type) {
 	if (req->type != q->type) {
 		dprintk(1, "reqbufs: queue type invalid\n");
 		dprintk(1, "reqbufs: queue type invalid\n");
 		retval = -EINVAL;
 		retval = -EINVAL;
@@ -444,7 +444,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
 	req->count = retval;
 	req->count = retval;
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -452,7 +452,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 {
 {
 	int ret = -EINVAL;
 	int ret = -EINVAL;
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	if (unlikely(b->type != q->type)) {
 	if (unlikely(b->type != q->type)) {
 		dprintk(1, "querybuf: Wrong type.\n");
 		dprintk(1, "querybuf: Wrong type.\n");
 		goto done;
 		goto done;
@@ -470,7 +470,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 
 
 	ret = 0;
 	ret = 0;
 done:
 done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -487,7 +487,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
 	if (b->memory == V4L2_MEMORY_MMAP)
 	if (b->memory == V4L2_MEMORY_MMAP)
 		down_read(&current->mm->mmap_sem);
 		down_read(&current->mm->mmap_sem);
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = -EBUSY;
 	retval = -EBUSY;
 	if (q->reading) {
 	if (q->reading) {
 		dprintk(1, "qbuf: Reading running...\n");
 		dprintk(1, "qbuf: Reading running...\n");
@@ -573,7 +573,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
 	retval = 0;
 	retval = 0;
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 
 
 	if (b->memory == V4L2_MEMORY_MMAP)
 	if (b->memory == V4L2_MEMORY_MMAP)
 		up_read(&current->mm->mmap_sem);
 		up_read(&current->mm->mmap_sem);
@@ -589,7 +589,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
 
 
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = -EBUSY;
 	retval = -EBUSY;
 	if (q->reading) {
 	if (q->reading) {
 		dprintk(1, "dqbuf: Reading running...\n");
 		dprintk(1, "dqbuf: Reading running...\n");
@@ -632,7 +632,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
 	videobuf_status(q, b, buf, q->type);
 	videobuf_status(q, b, buf, q->type);
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -642,7 +642,7 @@ int videobuf_streamon(struct videobuf_queue *q)
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 	int retval;
 	int retval;
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = -EBUSY;
 	retval = -EBUSY;
 	if (q->reading)
 	if (q->reading)
 		goto done;
 		goto done;
@@ -659,11 +659,11 @@ int videobuf_streamon(struct videobuf_queue *q)
 		spin_unlock_irqrestore(q->irqlock, flags);
 		spin_unlock_irqrestore(q->irqlock, flags);
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static int __videobuf_streamoff(struct videobuf_queue *q)
 static int __videobuf_streamoff(struct videobuf_queue *q)
 {
 {
 	if (!q->streaming)
 	if (!q->streaming)
@@ -679,14 +679,14 @@ int videobuf_streamoff(struct videobuf_queue *q)
 {
 {
 	int retval;
 	int retval;
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = __videobuf_streamoff(q);
 	retval = __videobuf_streamoff(q);
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
 static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
 				      char __user *data,
 				      char __user *data,
 				      size_t count, loff_t *ppos)
 				      size_t count, loff_t *ppos)
@@ -745,7 +745,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
 
 
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 
 
 	nbufs = 1; size = 0;
 	nbufs = 1; size = 0;
 	q->ops->buf_setup(q, &nbufs, &size);
 	q->ops->buf_setup(q, &nbufs, &size);
@@ -817,11 +817,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
 	}
 	}
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
-/* Locking: Caller holds q->lock */
+/* Locking: Caller holds q->vb_lock */
 static int __videobuf_read_start(struct videobuf_queue *q)
 static int __videobuf_read_start(struct videobuf_queue *q)
 {
 {
 	enum v4l2_field field;
 	enum v4l2_field field;
@@ -882,23 +882,23 @@ int videobuf_read_start(struct videobuf_queue *q)
 {
 {
 	int rc;
 	int rc;
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	rc = __videobuf_read_start(q);
 	rc = __videobuf_read_start(q);
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 
 
 	return rc;
 	return rc;
 }
 }
 
 
 void videobuf_read_stop(struct videobuf_queue *q)
 void videobuf_read_stop(struct videobuf_queue *q)
 {
 {
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	__videobuf_read_stop(q);
 	__videobuf_read_stop(q);
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 }
 }
 
 
 void videobuf_stop(struct videobuf_queue *q)
 void videobuf_stop(struct videobuf_queue *q)
 {
 {
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 
 
 	if (q->streaming)
 	if (q->streaming)
 		__videobuf_streamoff(q);
 		__videobuf_streamoff(q);
@@ -906,7 +906,7 @@ void videobuf_stop(struct videobuf_queue *q)
 	if (q->reading)
 	if (q->reading)
 		__videobuf_read_stop(q);
 		__videobuf_read_stop(q);
 
 
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 }
 }
 
 
 
 
@@ -920,7 +920,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
 
 	dprintk(2, "%s\n", __FUNCTION__);
 	dprintk(2, "%s\n", __FUNCTION__);
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = -EBUSY;
 	retval = -EBUSY;
 	if (q->streaming)
 	if (q->streaming)
 		goto done;
 		goto done;
@@ -980,7 +980,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
 	}
 	}
 
 
  done:
  done:
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -991,7 +991,7 @@ unsigned int videobuf_poll_stream(struct file *file,
 	struct videobuf_buffer *buf = NULL;
 	struct videobuf_buffer *buf = NULL;
 	unsigned int rc = 0;
 	unsigned int rc = 0;
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	if (q->streaming) {
 	if (q->streaming) {
 		if (!list_empty(&q->stream))
 		if (!list_empty(&q->stream))
 			buf = list_entry(q->stream.next,
 			buf = list_entry(q->stream.next,
@@ -1019,7 +1019,7 @@ unsigned int videobuf_poll_stream(struct file *file,
 		    buf->state == VIDEOBUF_ERROR)
 		    buf->state == VIDEOBUF_ERROR)
 			rc = POLLIN|POLLRDNORM;
 			rc = POLLIN|POLLRDNORM;
 	}
 	}
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -1030,10 +1030,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
 
 
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
 
 
-	mutex_lock(&q->lock);
+	mutex_lock(&q->vb_lock);
 	retval = CALL(q, mmap_mapper, q, vma);
 	retval = CALL(q, mmap_mapper, q, vma);
 	q->is_mmapped = 1;
 	q->is_mmapped = 1;
-	mutex_unlock(&q->lock);
+	mutex_unlock(&q->vb_lock);
 
 
 	return retval;
 	return retval;
 }
 }

+ 2 - 2
drivers/media/video/videobuf-dma-sg.c

@@ -356,7 +356,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
 	map->count--;
 	map->count--;
 	if (0 == map->count) {
 	if (0 == map->count) {
 		dprintk(1,"munmap %p q=%p\n",map,q);
 		dprintk(1,"munmap %p q=%p\n",map,q);
-		mutex_lock(&q->lock);
+		mutex_lock(&q->vb_lock);
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 			if (NULL == q->bufs[i])
 			if (NULL == q->bufs[i])
 				continue;
 				continue;
@@ -373,7 +373,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
 			q->bufs[i]->baddr = 0;
 			q->bufs[i]->baddr = 0;
 			q->ops->buf_release(q,q->bufs[i]);
 			q->ops->buf_release(q,q->bufs[i]);
 		}
 		}
-		mutex_unlock(&q->lock);
+		mutex_unlock(&q->vb_lock);
 		kfree(map);
 		kfree(map);
 	}
 	}
 	return;
 	return;

+ 9 - 11
drivers/media/video/videobuf-vmalloc.c

@@ -70,7 +70,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
 	map->count--;
 	map->count--;
 	if (0 == map->count) {
 	if (0 == map->count) {
 		dprintk(1,"munmap %p q=%p\n",map,q);
 		dprintk(1,"munmap %p q=%p\n",map,q);
-		mutex_lock(&q->lock);
+		mutex_lock(&q->vb_lock);
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 			if (NULL == q->bufs[i])
 			if (NULL == q->bufs[i])
 				continue;
 				continue;
@@ -83,7 +83,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
 			q->bufs[i]->map   = NULL;
 			q->bufs[i]->map   = NULL;
 			q->bufs[i]->baddr = 0;
 			q->bufs[i]->baddr = 0;
 		}
 		}
-		mutex_unlock(&q->lock);
+		mutex_unlock(&q->vb_lock);
 		kfree(map);
 		kfree(map);
 	}
 	}
 	return;
 	return;
@@ -107,7 +107,7 @@ static struct vm_operations_struct videobuf_vm_ops =
 
 
 static void *__videobuf_alloc(size_t size)
 static void *__videobuf_alloc(size_t size)
 {
 {
-	struct videbuf_vmalloc_memory *mem;
+	struct videobuf_vmalloc_memory *mem;
 	struct videobuf_buffer *vb;
 	struct videobuf_buffer *vb;
 
 
 	vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
 	vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
@@ -127,9 +127,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
 			      struct v4l2_framebuffer *fbuf)
 			      struct v4l2_framebuffer *fbuf)
 {
 {
 	int pages;
 	int pages;
-
-	struct videbuf_vmalloc_memory *mem=vb->priv;
-
+	struct videobuf_vmalloc_memory *mem=vb->priv;
 
 
 	BUG_ON(!mem);
 	BUG_ON(!mem);
 
 
@@ -195,7 +193,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
 			 struct vm_area_struct *vma)
 			 struct vm_area_struct *vma)
 {
 {
-	struct videbuf_vmalloc_memory *mem;
+	struct videobuf_vmalloc_memory *mem;
 	struct videobuf_mapping *map;
 	struct videobuf_mapping *map;
 	unsigned int first;
 	unsigned int first;
 	int retval;
 	int retval;
@@ -267,7 +265,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q,
 				char __user *data, size_t count,
 				char __user *data, size_t count,
 				int nonblocking )
 				int nonblocking )
 {
 {
-	struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+	struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
 	BUG_ON (!mem);
 	BUG_ON (!mem);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 
 
@@ -288,7 +286,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q,
 				int vbihack, int nonblocking )
 				int vbihack, int nonblocking )
 {
 {
 	unsigned int  *fc;
 	unsigned int  *fc;
-	struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+	struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
 	BUG_ON (!mem);
 	BUG_ON (!mem);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 
 
@@ -341,7 +339,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
 
 
 void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
 void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
 {
 {
-	struct videbuf_vmalloc_memory *mem=buf->priv;
+	struct videobuf_vmalloc_memory *mem=buf->priv;
 	BUG_ON (!mem);
 	BUG_ON (!mem);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 
 
@@ -351,7 +349,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
 
 
 void videobuf_vmalloc_free (struct videobuf_buffer *buf)
 void videobuf_vmalloc_free (struct videobuf_buffer *buf)
 {
 {
-	struct videbuf_vmalloc_memory *mem=buf->priv;
+	struct videobuf_vmalloc_memory *mem=buf->priv;
 	BUG_ON (!mem);
 	BUG_ON (!mem);
 
 
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);

+ 385 - 59
drivers/media/video/videodev.c

@@ -46,10 +46,373 @@
 #include <linux/videodev.h>
 #include <linux/videodev.h>
 #endif
 #endif
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <linux/video_decoder.h>
 
 
 #define VIDEO_NUM_DEVICES	256
 #define VIDEO_NUM_DEVICES	256
 #define VIDEO_NAME              "video4linux"
 #define VIDEO_NAME              "video4linux"
 
 
+/* video4linux standard ID conversion to standard name
+ */
+char *v4l2_norm_to_name(v4l2_std_id id)
+{
+	char *name;
+	u32 myid = id;
+
+	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
+	   64 bit comparations. So, on that architecture, with some gcc
+	   variants, compilation fails. Currently, the max value is 30bit wide.
+	 */
+	BUG_ON(myid != id);
+
+	switch (myid) {
+	case V4L2_STD_PAL:
+		name = "PAL";
+		break;
+	case V4L2_STD_PAL_BG:
+		name = "PAL-BG";
+		break;
+	case V4L2_STD_PAL_DK:
+		name = "PAL-DK";
+		break;
+	case V4L2_STD_PAL_B:
+		name = "PAL-B";
+		break;
+	case V4L2_STD_PAL_B1:
+		name = "PAL-B1";
+		break;
+	case V4L2_STD_PAL_G:
+		name = "PAL-G";
+		break;
+	case V4L2_STD_PAL_H:
+		name = "PAL-H";
+		break;
+	case V4L2_STD_PAL_I:
+		name = "PAL-I";
+		break;
+	case V4L2_STD_PAL_D:
+		name = "PAL-D";
+		break;
+	case V4L2_STD_PAL_D1:
+		name = "PAL-D1";
+		break;
+	case V4L2_STD_PAL_K:
+		name = "PAL-K";
+		break;
+	case V4L2_STD_PAL_M:
+		name = "PAL-M";
+		break;
+	case V4L2_STD_PAL_N:
+		name = "PAL-N";
+		break;
+	case V4L2_STD_PAL_Nc:
+		name = "PAL-Nc";
+		break;
+	case V4L2_STD_PAL_60:
+		name = "PAL-60";
+		break;
+	case V4L2_STD_NTSC:
+		name = "NTSC";
+		break;
+	case V4L2_STD_NTSC_M:
+		name = "NTSC-M";
+		break;
+	case V4L2_STD_NTSC_M_JP:
+		name = "NTSC-M-JP";
+		break;
+	case V4L2_STD_NTSC_443:
+		name = "NTSC-443";
+		break;
+	case V4L2_STD_NTSC_M_KR:
+		name = "NTSC-M-KR";
+		break;
+	case V4L2_STD_SECAM:
+		name = "SECAM";
+		break;
+	case V4L2_STD_SECAM_DK:
+		name = "SECAM-DK";
+		break;
+	case V4L2_STD_SECAM_B:
+		name = "SECAM-B";
+		break;
+	case V4L2_STD_SECAM_D:
+		name = "SECAM-D";
+		break;
+	case V4L2_STD_SECAM_G:
+		name = "SECAM-G";
+		break;
+	case V4L2_STD_SECAM_H:
+		name = "SECAM-H";
+		break;
+	case V4L2_STD_SECAM_K:
+		name = "SECAM-K";
+		break;
+	case V4L2_STD_SECAM_K1:
+		name = "SECAM-K1";
+		break;
+	case V4L2_STD_SECAM_L:
+		name = "SECAM-L";
+		break;
+	case V4L2_STD_SECAM_LC:
+		name = "SECAM-LC";
+		break;
+	default:
+		name = "Unknown";
+		break;
+	}
+
+	return name;
+}
+EXPORT_SYMBOL(v4l2_norm_to_name);
+
+/* Fill in the fields of a v4l2_standard structure according to the
+   'id' and 'transmission' parameters.  Returns negative on error.  */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+			     int id, char *name)
+{
+	u32 index = vs->index;
+
+	memset(vs, 0, sizeof(struct v4l2_standard));
+	vs->index = index;
+	vs->id    = id;
+	if (id & V4L2_STD_525_60) {
+		vs->frameperiod.numerator = 1001;
+		vs->frameperiod.denominator = 30000;
+		vs->framelines = 525;
+	} else {
+		vs->frameperiod.numerator = 1;
+		vs->frameperiod.denominator = 25;
+		vs->framelines = 625;
+	}
+	strlcpy(vs->name, name, sizeof(vs->name));
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_video_std_construct);
+
+/* ----------------------------------------------------------------- */
+/* some arrays for pretty-printing debug messages of enum types      */
+
+char *v4l2_field_names[] = {
+	[V4L2_FIELD_ANY]        = "any",
+	[V4L2_FIELD_NONE]       = "none",
+	[V4L2_FIELD_TOP]        = "top",
+	[V4L2_FIELD_BOTTOM]     = "bottom",
+	[V4L2_FIELD_INTERLACED] = "interlaced",
+	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
+	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
+	[V4L2_FIELD_ALTERNATE]  = "alternate",
+	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+};
+EXPORT_SYMBOL(v4l2_field_names);
+
+char *v4l2_type_names[] = {
+	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
+	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
+	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
+	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
+	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
+	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
+	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
+	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
+};
+EXPORT_SYMBOL(v4l2_type_names);
+
+static char *v4l2_memory_names[] = {
+	[V4L2_MEMORY_MMAP]    = "mmap",
+	[V4L2_MEMORY_USERPTR] = "userptr",
+	[V4L2_MEMORY_OVERLAY] = "overlay",
+};
+
+#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
+			   arr[a] : "unknown")
+
+/* ------------------------------------------------------------------ */
+/* debug help functions                                               */
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static const char *v4l1_ioctls[] = {
+	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
+	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
+	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
+	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
+	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
+	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
+	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
+	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
+	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
+	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
+	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
+	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
+	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
+	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
+	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
+	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
+	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
+	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
+	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
+	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
+	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
+	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
+	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
+	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
+	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
+	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
+	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
+};
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+#endif
+
+static const char *v4l2_ioctls[] = {
+	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
+	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
+	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
+	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
+	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
+	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
+	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
+	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
+	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
+	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
+	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
+	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
+	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
+	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
+	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
+	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
+	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
+	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
+	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
+	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
+	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
+	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
+	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
+	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
+	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
+	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
+	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
+	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
+	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
+	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
+	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
+	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
+	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
+	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
+	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
+	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
+	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
+	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
+	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
+	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
+	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
+	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
+	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
+	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
+	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
+	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
+	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
+	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
+	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
+	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
+	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
+	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
+	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
+	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
+#if 1
+	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
+	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
+	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
+	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
+
+	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
+	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
+
+	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
+#endif
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+static const char *v4l2_int_ioctls[] = {
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
+	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
+	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
+	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
+	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
+	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
+	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
+	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
+	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
+	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
+	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
+#endif
+	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
+
+	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
+	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
+	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
+
+	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
+	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
+	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
+	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
+	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
+	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
+	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
+	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
+	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
+};
+#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+
+/* Common ioctl debug function. This function can be used by
+   external ioctl messages as well as internal V4L ioctl */
+void v4l_printk_ioctl(unsigned int cmd)
+{
+	char *dir;
+
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:              dir = "--"; break;
+	case _IOC_READ:              dir = "r-"; break;
+	case _IOC_WRITE:             dir = "-w"; break;
+	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+	default:                     dir = "*ERR*"; break;
+	}
+	switch (_IOC_TYPE(cmd)) {
+	case 'd':
+		printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
+		       v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	case 'v':
+		printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+		       v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+#endif
+	case 'V':
+		printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+		       v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+
+	default:
+		printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
+		       _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+	}
+}
+EXPORT_SYMBOL(v4l_printk_ioctl);
+
 /*
 /*
  *	sysfs stuff
  *	sysfs stuff
  */
  */
@@ -69,11 +432,13 @@ struct video_device *video_device_alloc(void)
 	vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
 	vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
 	return vfd;
 	return vfd;
 }
 }
+EXPORT_SYMBOL(video_device_alloc);
 
 
 void video_device_release(struct video_device *vfd)
 void video_device_release(struct video_device *vfd)
 {
 {
 	kfree(vfd);
 	kfree(vfd);
 }
 }
+EXPORT_SYMBOL(video_device_release);
 
 
 static void video_release(struct device *cd)
 static void video_release(struct device *cd)
 {
 {
@@ -110,6 +475,7 @@ struct video_device* video_devdata(struct file *file)
 {
 {
 	return video_device[iminor(file->f_path.dentry->d_inode)];
 	return video_device[iminor(file->f_path.dentry->d_inode)];
 }
 }
+EXPORT_SYMBOL(video_devdata);
 
 
 /*
 /*
  *	Open a video device - FIXME: Obsoleted
  *	Open a video device - FIXME: Obsoleted
@@ -278,6 +644,7 @@ out:
 	kfree(mbuf);
 	kfree(mbuf);
 	return err;
 	return err;
 }
 }
+EXPORT_SYMBOL(video_usercopy);
 
 
 /*
 /*
  * open/release helper functions -- handle exclusive opens
  * open/release helper functions -- handle exclusive opens
@@ -297,6 +664,7 @@ int video_exclusive_open(struct inode *inode, struct file *file)
 	mutex_unlock(&vfl->lock);
 	mutex_unlock(&vfl->lock);
 	return retval;
 	return retval;
 }
 }
+EXPORT_SYMBOL(video_exclusive_open);
 
 
 int video_exclusive_release(struct inode *inode, struct file *file)
 int video_exclusive_release(struct inode *inode, struct file *file)
 {
 {
@@ -305,41 +673,7 @@ int video_exclusive_release(struct inode *inode, struct file *file)
 	vfl->users--;
 	vfl->users--;
 	return 0;
 	return 0;
 }
 }
-
-static char *v4l2_memory_names[] = {
-	[V4L2_MEMORY_MMAP]    = "mmap",
-	[V4L2_MEMORY_USERPTR] = "userptr",
-	[V4L2_MEMORY_OVERLAY] = "overlay",
-};
-
-
-/* FIXME: Those stuff are replicated also on v4l2-common.c */
-static char *v4l2_type_names_FIXME[] = {
-	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
-	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
-	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
-	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
-	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
-	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
-	[V4L2_BUF_TYPE_PRIVATE]            = "private",
-};
-
-static char *v4l2_field_names_FIXME[] = {
-	[V4L2_FIELD_ANY]        = "any",
-	[V4L2_FIELD_NONE]       = "none",
-	[V4L2_FIELD_TOP]        = "top",
-	[V4L2_FIELD_BOTTOM]     = "bottom",
-	[V4L2_FIELD_INTERLACED] = "interlaced",
-	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
-	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
-	[V4L2_FIELD_ALTERNATE]  = "alternate",
-	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
-	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-
-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
+EXPORT_SYMBOL(video_exclusive_release);
 
 
 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
 					struct v4l2_buffer *p)
 					struct v4l2_buffer *p)
@@ -354,10 +688,10 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
 			(int)(p->timestamp.tv_sec%60),
 			(int)(p->timestamp.tv_sec%60),
 			p->timestamp.tv_usec,
 			p->timestamp.tv_usec,
 			p->index,
 			p->index,
-			prt_names(p->type,v4l2_type_names_FIXME),
-			p->bytesused,p->flags,
-			p->field,p->sequence,
-			prt_names(p->memory,v4l2_memory_names),
+			prt_names(p->type, v4l2_type_names),
+			p->bytesused, p->flags,
+			p->field, p->sequence,
+			prt_names(p->memory, v4l2_memory_names),
 			p->m.userptr, p->length);
 			p->m.userptr, p->length);
 	dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
 	dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
 		"flags=0x%08d, frames=%d, userbits=0x%08x\n",
 		"flags=0x%08d, frames=%d, userbits=0x%08x\n",
@@ -382,8 +716,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd,
 		(fmt->pixelformat >>  8) & 0xff,
 		(fmt->pixelformat >>  8) & 0xff,
 		(fmt->pixelformat >> 16) & 0xff,
 		(fmt->pixelformat >> 16) & 0xff,
 		(fmt->pixelformat >> 24) & 0xff,
 		(fmt->pixelformat >> 24) & 0xff,
-		prt_names(fmt->field,v4l2_field_names_FIXME),
-		fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
+		prt_names(fmt->field, v4l2_field_names),
+		fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
 };
 };
 
 
 
 
@@ -597,7 +931,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 
 
 		/* FIXME: Should be one dump per type */
 		/* FIXME: Should be one dump per type */
 		dbgarg (cmd, "type=%s\n", prt_names(type,
 		dbgarg (cmd, "type=%s\n", prt_names(type,
-					v4l2_type_names_FIXME));
+					v4l2_type_names));
 
 
 		switch (type) {
 		switch (type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -650,7 +984,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 
 
 		/* FIXME: Should be one dump per type */
 		/* FIXME: Should be one dump per type */
 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
-					v4l2_type_names_FIXME));
+					v4l2_type_names));
 
 
 		switch (f->type) {
 		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -702,7 +1036,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 
 
 		/* FIXME: Should be one dump per type */
 		/* FIXME: Should be one dump per type */
 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
-						v4l2_type_names_FIXME));
+						v4l2_type_names));
 		switch (f->type) {
 		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 			if (vfd->vidioc_try_fmt_cap)
 			if (vfd->vidioc_try_fmt_cap)
@@ -768,8 +1102,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		ret=vfd->vidioc_reqbufs(file, fh, p);
 		ret=vfd->vidioc_reqbufs(file, fh, p);
 		dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
 		dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
 				p->count,
 				p->count,
-				prt_names(p->type,v4l2_type_names_FIXME),
-				prt_names(p->memory,v4l2_memory_names));
+				prt_names(p->type, v4l2_type_names),
+				prt_names(p->memory, v4l2_memory_names));
 		break;
 		break;
 	}
 	}
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QUERYBUF:
@@ -858,7 +1192,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		enum v4l2_buf_type i = *(int *)arg;
 		enum v4l2_buf_type i = *(int *)arg;
 		if (!vfd->vidioc_streamon)
 		if (!vfd->vidioc_streamon)
 			break;
 			break;
-		dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
+		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
 		ret=vfd->vidioc_streamon(file, fh,i);
 		ret=vfd->vidioc_streamon(file, fh,i);
 		break;
 		break;
 	}
 	}
@@ -868,7 +1202,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 
 
 		if (!vfd->vidioc_streamoff)
 		if (!vfd->vidioc_streamoff)
 			break;
 			break;
-		dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
+		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
 		ret=vfd->vidioc_streamoff(file, fh, i);
 		ret=vfd->vidioc_streamoff(file, fh, i);
 		break;
 		break;
 	}
 	}
@@ -1624,7 +1958,7 @@ out:
 	kfree(mbuf);
 	kfree(mbuf);
 	return err;
 	return err;
 }
 }
-
+EXPORT_SYMBOL(video_ioctl2);
 
 
 static const struct file_operations video_fops;
 static const struct file_operations video_fops;
 
 
@@ -1743,6 +2077,7 @@ fail_minor:
 	mutex_unlock(&videodev_lock);
 	mutex_unlock(&videodev_lock);
 	return ret;
 	return ret;
 }
 }
+EXPORT_SYMBOL(video_register_device);
 
 
 /**
 /**
  *	video_unregister_device - unregister a video4linux device
  *	video_unregister_device - unregister a video4linux device
@@ -1762,6 +2097,7 @@ void video_unregister_device(struct video_device *vfd)
 	device_unregister(&vfd->class_dev);
 	device_unregister(&vfd->class_dev);
 	mutex_unlock(&videodev_lock);
 	mutex_unlock(&videodev_lock);
 }
 }
+EXPORT_SYMBOL(video_unregister_device);
 
 
 /*
 /*
  * Video fs operations
  * Video fs operations
@@ -1806,16 +2142,6 @@ static void __exit videodev_exit(void)
 module_init(videodev_init)
 module_init(videodev_init)
 module_exit(videodev_exit)
 module_exit(videodev_exit)
 
 
-EXPORT_SYMBOL(video_register_device);
-EXPORT_SYMBOL(video_unregister_device);
-EXPORT_SYMBOL(video_devdata);
-EXPORT_SYMBOL(video_usercopy);
-EXPORT_SYMBOL(video_exclusive_open);
-EXPORT_SYMBOL(video_exclusive_release);
-EXPORT_SYMBOL(video_ioctl2);
-EXPORT_SYMBOL(video_device_alloc);
-EXPORT_SYMBOL(video_device_release);
-
 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 11 - 11
drivers/media/video/zoran.h

@@ -221,15 +221,15 @@ enum zoran_map_mode {
 };
 };
 
 
 enum gpio_type {
 enum gpio_type {
-	GPIO_JPEG_SLEEP = 0,
-	GPIO_JPEG_RESET,
-	GPIO_JPEG_FRAME,
-	GPIO_VID_DIR,
-	GPIO_VID_EN,
-	GPIO_VID_RESET,
-	GPIO_CLK_SEL1,
-	GPIO_CLK_SEL2,
-	GPIO_MAX,
+	ZR_GPIO_JPEG_SLEEP = 0,
+	ZR_GPIO_JPEG_RESET,
+	ZR_GPIO_JPEG_FRAME,
+	ZR_GPIO_VID_DIR,
+	ZR_GPIO_VID_EN,
+	ZR_GPIO_VID_RESET,
+	ZR_GPIO_CLK_SEL1,
+	ZR_GPIO_CLK_SEL2,
+	ZR_GPIO_MAX,
 };
 };
 
 
 enum gpcs_type {
 enum gpcs_type {
@@ -378,11 +378,11 @@ struct card_info {
 
 
 	u32 jpeg_int;		/* JPEG interrupt */
 	u32 jpeg_int;		/* JPEG interrupt */
 	u32 vsync_int;		/* VSYNC interrupt */
 	u32 vsync_int;		/* VSYNC interrupt */
-	s8 gpio[GPIO_MAX];
+	s8 gpio[ZR_GPIO_MAX];
 	u8 gpcs[GPCS_MAX];
 	u8 gpcs[GPCS_MAX];
 
 
 	struct vfe_polarity vfe_pol;
 	struct vfe_polarity vfe_pol;
-	u8 gpio_pol[GPIO_MAX];
+	u8 gpio_pol[ZR_GPIO_MAX];
 
 
 	/* is the /GWS line conected? */
 	/* is the /GWS line conected? */
 	u8 gws_not_connected;
 	u8 gws_not_connected;

+ 6 - 6
drivers/media/video/zoran_device.c

@@ -250,7 +250,7 @@ void
 jpeg_codec_sleep (struct zoran *zr,
 jpeg_codec_sleep (struct zoran *zr,
 		  int           sleep)
 		  int           sleep)
 {
 {
-	GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
+	GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
 	if (!sleep) {
 	if (!sleep) {
 		dprintk(3,
 		dprintk(3,
 			KERN_DEBUG
 			KERN_DEBUG
@@ -277,9 +277,9 @@ jpeg_codec_reset (struct zoran *zr)
 				  0);
 				  0);
 		udelay(2);
 		udelay(2);
 	} else {
 	} else {
-		GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
+		GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
 		udelay(2);
 		udelay(2);
-		GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
+		GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
 		udelay(2);
 		udelay(2);
 	}
 	}
 
 
@@ -688,7 +688,7 @@ static inline void
 set_frame (struct zoran *zr,
 set_frame (struct zoran *zr,
 	   int           val)
 	   int           val)
 {
 {
-	GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
+	GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
 }
 }
 
 
 static void
 static void
@@ -704,8 +704,8 @@ set_videobus_dir (struct zoran *zr,
 			GPIO(zr, 5, 1);
 			GPIO(zr, 5, 1);
 		break;
 		break;
 	default:
 	default:
-		GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
-		     zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
+		GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
+		     zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
 		break;
 		break;
 	}
 	}
 }
 }

+ 2 - 0
drivers/media/video/zr364xx.c

@@ -93,6 +93,8 @@ static struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
 	{USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
 	{USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
 	{USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
 	{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
 	{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
+	{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
+	{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
 	{}			/* Terminating entry */
 	{}			/* Terminating entry */
 };
 };
 
 

+ 1 - 0
include/linux/videodev.h

@@ -12,6 +12,7 @@
 #ifndef __LINUX_VIDEODEV_H
 #ifndef __LINUX_VIDEODEV_H
 #define __LINUX_VIDEODEV_H
 #define __LINUX_VIDEODEV_H
 
 
+#include <linux/ioctl.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 
 
 #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
 #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)

+ 1 - 0
include/linux/videodev2.h

@@ -62,6 +62,7 @@
 #define __user
 #define __user
 #include <sys/time.h>
 #include <sys/time.h>
 #endif
 #endif
+#include <linux/ioctl.h>
 #include <linux/types.h>
 #include <linux/types.h>
 
 
 /*
 /*

+ 1 - 0
include/media/ir-common.h

@@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
 
 
 #endif
 #endif
 
 

+ 0 - 2
include/media/v4l2-common.h

@@ -61,8 +61,6 @@
 			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
 			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
 	} while (0)
 	} while (0)
 
 
-/* Prints the ioctl in a human-readable format */
-extern void v4l_printk_ioctl(unsigned int cmd);
 
 
 /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
 /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
 #define v4l_print_ioctl(name, cmd)  		 \
 #define v4l_print_ioctl(name, cmd)  		 \

+ 2 - 0
include/media/v4l2-dev.h

@@ -44,6 +44,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
 extern char *v4l2_norm_to_name(v4l2_std_id id);
 extern char *v4l2_norm_to_name(v4l2_std_id id);
 extern int v4l2_video_std_construct(struct v4l2_standard *vs,
 extern int v4l2_video_std_construct(struct v4l2_standard *vs,
 				    int id, char *name);
 				    int id, char *name);
+/* Prints the ioctl in a human-readable format */
+extern void v4l_printk_ioctl(unsigned int cmd);
 
 
 /* prority handling */
 /* prority handling */
 struct v4l2_prio_state {
 struct v4l2_prio_state {

+ 1 - 1
include/media/videobuf-core.h

@@ -149,7 +149,7 @@ struct videobuf_qtype_ops {
 };
 };
 
 
 struct videobuf_queue {
 struct videobuf_queue {
-	struct mutex               lock;
+	struct mutex               vb_lock;
 	spinlock_t                 *irqlock;
 	spinlock_t                 *irqlock;
 	void			   *dev; /* on pci, points to struct pci_dev */
 	void			   *dev; /* on pci, points to struct pci_dev */
 
 

+ 1 - 1
include/media/videobuf-vmalloc.h

@@ -17,7 +17,7 @@
 
 
 /* --------------------------------------------------------------------- */
 /* --------------------------------------------------------------------- */
 
 
-struct videbuf_vmalloc_memory
+struct videobuf_vmalloc_memory
 {
 {
 	u32                 magic;
 	u32                 magic;