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: (98 commits)
  V4L/DVB (8549): mxl5007: Fix an error at include file
  V4L/DVB (8548): pwc: Fix compilation
  V4L/DVB (8546): add tuner-3036 and dpc7146 drivers to feature-removal-schedule.txt
  V4L/DVB (8546): saa7146: fix read from uninitialized memory
  V4L/DVB (8544): gspca: probe/open race.
  V4L/DVB (8543): em28xx: Rename #define for Compro VideoMate ForYou/Stereo
  V4L/DVB (8542): em28xx: AMD ATI TV Wonder HD 600 entry at cards struct is duplicated
  V4L/DVB (8541): em28xx: HVR-950 entry is duplicated.
  V4L/DVB (8540): em28xx-cards: Add Compro VideoMate ForYou/Stereo model
  V4L/DVB (8539): em28xx-cards: New supported IDs for analog models
  V4L/DVB (8538): em28xx-cards: Add GrabBeeX+ USB2800 model
  V4L/DVB (8534): remove select's of FW_LOADER
  V4L/DVB (8522): videodev2: Fix merge conflict
  V4L/DVB (8532): mxl5007t: remove excessive locks
  V4L/DVB (8531): mxl5007t: move i2c gate handling outside of mutex protected code blocks
  V4L/DVB (8530): au0828: add support for new revision of HVR950Q
  V4L/DVB (8529): mxl5007t: enable _init and _sleep power management functionality
  V4L/DVB (8528): add support for MaxLinear MxL5007T silicon tuner
  V4L/DVB (8526): saa7146: fix VIDIOC_ENUM_FMT
  V4L/DVB (8525): fix a few assorted spelling mistakes.
  ...
Linus Torvalds 17 years ago
parent
commit
58f250714f
100 changed files with 5032 additions and 659 deletions
  1. 24 0
      Documentation/feature-removal-schedule.txt
  2. 1 0
      Documentation/video4linux/CARDLIST.au0828
  3. 42 3
      Documentation/video4linux/CARDLIST.em28xx
  4. 1 1
      Documentation/video4linux/gspca.txt
  5. 6 0
      MAINTAINERS
  6. 1 1
      drivers/media/common/saa7146_fops.c
  7. 8 11
      drivers/media/common/saa7146_video.c
  8. 9 7
      drivers/media/common/tuners/Kconfig
  9. 1 0
      drivers/media/common/tuners/Makefile
  10. 2 1
      drivers/media/common/tuners/mt20xx.c
  11. 1030 0
      drivers/media/common/tuners/mxl5007t.c
  12. 104 0
      drivers/media/common/tuners/mxl5007t.h
  13. 1 1
      drivers/media/common/tuners/tda9887.c
  14. 1 1
      drivers/media/common/tuners/tuner-simple.c
  15. 0 2
      drivers/media/dvb/bt8xx/Kconfig
  16. 8 2
      drivers/media/dvb/dvb-usb/Kconfig
  17. 3 0
      drivers/media/dvb/dvb-usb/Makefile
  18. 1 1
      drivers/media/dvb/dvb-usb/anysee.c
  19. 1 0
      drivers/media/dvb/dvb-usb/dvb-usb-ids.h
  20. 425 0
      drivers/media/dvb/dvb-usb/dw2102.c
  21. 9 0
      drivers/media/dvb/dvb-usb/dw2102.h
  22. 22 16
      drivers/media/dvb/frontends/Kconfig
  23. 1 0
      drivers/media/dvb/frontends/Makefile
  24. 1504 0
      drivers/media/dvb/frontends/drx397xD.c
  25. 130 0
      drivers/media/dvb/frontends/drx397xD.h
  26. 40 0
      drivers/media/dvb/frontends/drx397xD_fw.h
  27. 97 0
      drivers/media/dvb/frontends/z0194a.h
  28. 7 7
      drivers/media/dvb/siano/smscoreapi.c
  29. 2 2
      drivers/media/dvb/siano/smsdvb.c
  30. 0 4
      drivers/media/dvb/ttpci/Kconfig
  31. 0 2
      drivers/media/dvb/ttusb-dec/Kconfig
  32. 10 8
      drivers/media/radio/dsbr100.c
  33. 1 2
      drivers/media/radio/miropcm20-radio.c
  34. 8 6
      drivers/media/radio/radio-aimslab.c
  35. 8 6
      drivers/media/radio/radio-aztech.c
  36. 8 6
      drivers/media/radio/radio-cadet.c
  37. 8 5
      drivers/media/radio/radio-gemtek-pci.c
  38. 8 5
      drivers/media/radio/radio-gemtek.c
  39. 8 4
      drivers/media/radio/radio-maestro.c
  40. 8 7
      drivers/media/radio/radio-maxiradio.c
  41. 8 6
      drivers/media/radio/radio-rtrack2.c
  42. 8 6
      drivers/media/radio/radio-sf16fmi.c
  43. 8 6
      drivers/media/radio/radio-sf16fmr2.c
  44. 12 10
      drivers/media/radio/radio-si470x.c
  45. 8 6
      drivers/media/radio/radio-terratec.c
  46. 8 6
      drivers/media/radio/radio-trust.c
  47. 8 6
      drivers/media/radio/radio-typhoon.c
  48. 8 6
      drivers/media/radio/radio-zoltrix.c
  49. 1 18
      drivers/media/video/Kconfig
  50. 2 1
      drivers/media/video/Makefile
  51. 0 1
      drivers/media/video/arv.c
  52. 1 0
      drivers/media/video/au0828/Kconfig
  53. 12 0
      drivers/media/video/au0828/au0828-cards.c
  54. 1 0
      drivers/media/video/au0828/au0828-cards.h
  55. 15 0
      drivers/media/video/au0828/au0828-dvb.c
  56. 0 2
      drivers/media/video/bt8xx/Kconfig
  57. 26 32
      drivers/media/video/bt8xx/bttv-driver.c
  58. 1 0
      drivers/media/video/bt8xx/bttv-risc.c
  59. 1 0
      drivers/media/video/bt8xx/bttv-vbi.c
  60. 1 2
      drivers/media/video/bw-qcam.c
  61. 1 2
      drivers/media/video/c-qcam.c
  62. 14 12
      drivers/media/video/cafe_ccic.c
  63. 1 1
      drivers/media/video/compat_ioctl32.c
  64. 0 2
      drivers/media/video/cpia.c
  65. 1 0
      drivers/media/video/cpia.h
  66. 1 0
      drivers/media/video/cpia2/cpia2_core.c
  67. 1 4
      drivers/media/video/cpia2/cpia2_v4l.c
  68. 1 1
      drivers/media/video/cs5345.c
  69. 1 1
      drivers/media/video/cs53l32a.c
  70. 0 2
      drivers/media/video/cx18/Kconfig
  71. 94 17
      drivers/media/video/cx18/cx18-av-audio.c
  72. 1 0
      drivers/media/video/cx18/cx18-driver.h
  73. 13 41
      drivers/media/video/cx18/cx18-firmware.c
  74. 48 44
      drivers/media/video/cx18/cx18-ioctl.c
  75. 1 4
      drivers/media/video/cx18/cx18-streams.c
  76. 0 2
      drivers/media/video/cx23885/Kconfig
  77. 10 9
      drivers/media/video/cx23885/cx23885-417.c
  78. 42 12
      drivers/media/video/cx23885/cx23885-cards.c
  79. 139 8
      drivers/media/video/cx23885/cx23885-core.c
  80. 11 8
      drivers/media/video/cx23885/cx23885-video.c
  81. 0 2
      drivers/media/video/cx25840/Kconfig
  82. 1 1
      drivers/media/video/cx25840/cx25840-core.c
  83. 0 2
      drivers/media/video/cx25840/cx25840-core.h
  84. 1 2
      drivers/media/video/cx88/Kconfig
  85. 9 6
      drivers/media/video/cx88/cx88-blackbird.c
  86. 1 1
      drivers/media/video/cx88/cx88-cards.c
  87. 2 1
      drivers/media/video/cx88/cx88-core.c
  88. 21 16
      drivers/media/video/cx88/cx88-video.c
  89. 2 2
      drivers/media/video/cx88/cx88.h
  90. 781 113
      drivers/media/video/em28xx/em28xx-cards.c
  91. 12 1
      drivers/media/video/em28xx/em28xx-dvb.c
  92. 31 30
      drivers/media/video/em28xx/em28xx-video.c
  93. 47 2
      drivers/media/video/em28xx/em28xx.h
  94. 2 3
      drivers/media/video/et61x251/et61x251_core.c
  95. 2 7
      drivers/media/video/gspca/conex.c
  96. 5 25
      drivers/media/video/gspca/etoms.c
  97. 30 13
      drivers/media/video/gspca/gspca.c
  98. 2 7
      drivers/media/video/gspca/mars.c
  99. 14 19
      drivers/media/video/gspca/ov519.c
  100. 12 17
      drivers/media/video/gspca/pac207.c

+ 24 - 0
Documentation/feature-removal-schedule.txt

@@ -47,6 +47,30 @@ Who:	Mauro Carvalho Chehab <mchehab@infradead.org>
 
 
 ---------------------------
 ---------------------------
 
 
+What:	old tuner-3036 i2c driver
+When:	2.6.28
+Why:	This driver is for VERY old i2c-over-parallel port teletext receiver
+	boxes. Rather then spending effort on converting this driver to V4L2,
+	and since it is extremely unlikely that anyone still uses one of these
+	devices, it was decided to drop it.
+Who:	Hans Verkuil <hverkuil@xs4all.nl>
+	Mauro Carvalho Chehab <mchehab@infradead.org>
+
+ ---------------------------
+
+What:   V4L2 dpc7146 driver
+When:   2.6.28
+Why:    Old driver for the dpc7146 demonstration board that is no longer
+	relevant. The last time this was tested on actual hardware was
+	probably around 2002. Since this is a driver for a demonstration
+	board the decision was made to remove it rather than spending a
+	lot of effort continually updating this driver to stay in sync
+	with the latest internal V4L2 or I2C API.
+Who:    Hans Verkuil <hverkuil@xs4all.nl>
+	Mauro Carvalho Chehab <mchehab@infradead.org>
+
+---------------------------
+
 What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
 What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
 When:	November 2005
 When:	November 2005
 Files:	drivers/pcmcia/: pcmcia_ioctl.c
 Files:	drivers/pcmcia/: pcmcia_ioctl.c

+ 1 - 0
Documentation/video4linux/CARDLIST.au0828

@@ -2,3 +2,4 @@
   1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
   1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
+  4 -> Hauppauge HVR950Q rev xxF8               (au0828)        [2040:7201,2040:7211,2040:7281]

+ 42 - 3
Documentation/video4linux/CARDLIST.em28xx

@@ -1,11 +1,11 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
   5 -> MSI VOX USB 2.0                          (em2820/em2840)
   5 -> MSI VOX USB 2.0                          (em2820/em2840)
   6 -> Terratec Cinergy 200 USB                 (em2800)
   6 -> Terratec Cinergy 200 USB                 (em2800)
-  7 -> Leadtek Winfast USB II                   (em2800)
+  7 -> Leadtek Winfast USB II                   (em2800)        [0413:6023]
   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]
@@ -14,7 +14,46 @@
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  15 -> V-Gear PocketTV                          (em2800)
  15 -> V-Gear PocketTV                          (em2800)
- 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513,2040:6517,2040:651b,2040:651f]
+ 16 -> Hauppauge WinTV HVR 950                  (em2883)        [2040:6513,2040:6517,2040:651b,2040:651f]
  17 -> Pinnacle PCTV HD Pro Stick               (em2880)        [2304:0227]
  17 -> Pinnacle PCTV HD Pro Stick               (em2880)        [2304:0227]
  18 -> Hauppauge WinTV HVR 900 (R2)             (em2880)        [2040:6502]
  18 -> Hauppauge WinTV HVR 900 (R2)             (em2880)        [2040:6502]
  19 -> PointNix Intra-Oral Camera               (em2860)
  19 -> PointNix Intra-Oral Camera               (em2860)
+ 20 -> AMD ATI TV Wonder HD 600                 (em2880)        [0438:b002]
+ 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800)        [eb1a:2801]
+ 22 -> Unknown EM2750/EM2751 webcam grabber     (em2750)        [eb1a:2750,eb1a:2751]
+ 23 -> Huaqi DLCW-130                           (em2750)
+ 24 -> D-Link DUB-T210 TV Tuner                 (em2820/em2840) [2001:f112]
+ 25 -> Gadmei UTV310                            (em2820/em2840)
+ 26 -> Hercules Smart TV USB 2.0                (em2820/em2840)
+ 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME)   (em2820/em2840)
+ 28 -> Leadtek Winfast USB II Deluxe            (em2820/em2840)
+ 29 -> Pinnacle Dazzle DVC 100                  (em2820/em2840)
+ 30 -> Videology 20K14XUSB USB2.0               (em2820/em2840)
+ 31 -> Usbgear VD204v9                          (em2821)
+ 32 -> Supercomp USB 2.0 TV                     (em2821)
+ 33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0  (em2821)
+ 34 -> Terratec Cinergy A Hybrid XS             (em2860)        [0ccd:004f]
+ 35 -> Typhoon DVD Maker                        (em2860)
+ 36 -> NetGMBH Cam                              (em2860)
+ 37 -> Gadmei UTV330                            (em2860)
+ 38 -> Yakumo MovieMixer                        (em2861)
+ 39 -> KWorld PVRTV 300U                        (em2861)        [eb1a:e300]
+ 40 -> Plextor ConvertX PX-TV100U               (em2861)        [093b:a005]
+ 41 -> Kworld 350 U DVB-T                       (em2870)        [eb1a:e350]
+ 42 -> Kworld 355 U DVB-T                       (em2870)        [eb1a:e355,eb1a:e357]
+ 43 -> Terratec Cinergy T XS                    (em2870)        [0ccd:0043]
+ 44 -> Terratec Cinergy T XS (MT2060)           (em2870)
+ 45 -> Pinnacle PCTV DVB-T                      (em2870)
+ 46 -> Compro, VideoMate U3                     (em2870)        [185b:2870]
+ 47 -> KWorld DVB-T 305U                        (em2880)        [eb1a:e305]
+ 48 -> KWorld DVB-T 310U                        (em2880)
+ 49 -> MSI DigiVox A/D                          (em2880)        [eb1a:e310]
+ 50 -> MSI DigiVox A/D II                       (em2880)        [eb1a:e320]
+ 51 -> Terratec Hybrid XS Secam                 (em2880)        [0ccd:004c]
+ 52 -> DNT DA2 Hybrid                           (em2881)
+ 53 -> Pinnacle Hybrid Pro                      (em2881)
+ 54 -> Kworld VS-DVB-T 323UR                    (em2882)        [eb1a:e323]
+ 55 -> Terratec Hybrid XS (em2882)              (em2882)        [0ccd:005e]
+ 56 -> Pinnacle Hybrid Pro (2)                  (em2882)        [2304:0226]
+ 57 -> Kworld PlusTV HD Hybrid 330              (em2883)        [eb1a:a316]
+ 58 -> Compro VideoMate ForYou/Stereo           (em2820/em2840) [185b:2041]

+ 1 - 1
Documentation/video4linux/gspca.txt

@@ -1,4 +1,4 @@
-List of the webcams know by gspca.
+List of the webcams known by gspca.
 
 
 The modules are:
 The modules are:
 	gspca_main	main driver
 	gspca_main	main driver

+ 6 - 0
MAINTAINERS

@@ -3796,6 +3796,12 @@ P:	Ben Nizette
 M:	bn@niasdigital.com
 M:	bn@niasdigital.com
 S:	Maintained
 S:	Maintained
 
 
+SOC-CAMERA V4L2 SUBSYSTEM
+P:     Guennadi Liakhovetski
+M:     g.liakhovetski@gmx.de
+L:     video4linux-list@redhat.com
+S:     Maintained
+
 SOFTWARE RAID (Multiple Disks) SUPPORT
 SOFTWARE RAID (Multiple Disks) SUPPORT
 P:	Ingo Molnar
 P:	Ingo Molnar
 M:	mingo@redhat.com
 M:	mingo@redhat.com

+ 1 - 1
drivers/media/common/saa7146_fops.c

@@ -563,7 +563,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev
 
 
 	DEB_EE(("dev:%p\n",dev));
 	DEB_EE(("dev:%p\n",dev));
 
 
-	if( VFL_TYPE_GRABBER == (*vid)->type ) {
+	if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
 		vv->video_minor = -1;
 		vv->video_minor = -1;
 	} else {
 	} else {
 		vv->vbi_minor = -1;
 		vv->vbi_minor = -1;

+ 8 - 11
drivers/media/common/saa7146_video.c

@@ -656,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
 
 
 		/* if we have a user buffer, the first page may not be
 		/* if we have a user buffer, the first page may not be
 		   aligned to a page boundary. */
 		   aligned to a page boundary. */
-		pt1->offset = list->offset;
+		pt1->offset = dma->sglist->offset;
 		pt2->offset = pt1->offset+o1;
 		pt2->offset = pt1->offset+o1;
 		pt3->offset = pt1->offset+o2;
 		pt3->offset = pt1->offset+o2;
 
 
@@ -958,21 +958,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
 	case VIDIOC_ENUM_FMT:
 	case VIDIOC_ENUM_FMT:
 	{
 	{
 		struct v4l2_fmtdesc *f = arg;
 		struct v4l2_fmtdesc *f = arg;
-		int index;
 
 
 		switch (f->type) {
 		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
-			index = f->index;
-			if (index < 0 || index >= NUM_FORMATS) {
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (f->index >= NUM_FORMATS)
 				return -EINVAL;
 				return -EINVAL;
-			}
-			memset(f,0,sizeof(*f));
-			f->index = index;
-			strlcpy((char *)f->description,formats[index].name,sizeof(f->description));
-			f->pixelformat = formats[index].pixelformat;
+			strlcpy((char *)f->description, formats[f->index].name,
+					sizeof(f->description));
+			f->pixelformat = formats[f->index].pixelformat;
+			f->flags = 0;
+			memset(f->reserved, 0, sizeof(f->reserved));
 			break;
 			break;
-		}
 		default:
 		default:
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}

+ 9 - 7
drivers/media/common/tuners/Kconfig

@@ -21,9 +21,8 @@ config MEDIA_TUNER
 	tristate
 	tristate
 	default VIDEO_MEDIA && I2C
 	default VIDEO_MEDIA && I2C
 	depends on VIDEO_MEDIA && I2C
 	depends on VIDEO_MEDIA && I2C
-	select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -138,8 +137,6 @@ config MEDIA_TUNER_QT1010
 config MEDIA_TUNER_XC2028
 config MEDIA_TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
 	tristate "XCeive xc2028/xc3028 tuners"
 	depends on VIDEO_MEDIA && I2C
 	depends on VIDEO_MEDIA && I2C
-	depends on HOTPLUG
-	select FW_LOADER
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_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.
@@ -147,8 +144,6 @@ config MEDIA_TUNER_XC2028
 config MEDIA_TUNER_XC5000
 config MEDIA_TUNER_XC5000
 	tristate "Xceive XC5000 silicon tuner"
 	tristate "Xceive XC5000 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
 	depends on VIDEO_MEDIA && I2C
-	depends on HOTPLUG
-	select FW_LOADER
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
 	  A driver for the silicon tuner XC5000 from Xceive.
@@ -162,4 +157,11 @@ config MEDIA_TUNER_MXL5005S
 	help
 	help
 	  A driver for the silicon tuner MXL5005S from MaxLinear.
 	  A driver for the silicon tuner MXL5005S from MaxLinear.
 
 
+config MEDIA_TUNER_MXL5007T
+	tristate "MaxLinear MxL5007T silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A driver for the silicon tuner MxL5007T from MaxLinear.
+
 endif # MEDIA_TUNER_CUSTOMIZE
 endif # MEDIA_TUNER_CUSTOMIZE

+ 1 - 0
drivers/media/common/tuners/Makefile

@@ -21,6 +21,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
 
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends

+ 2 - 1
drivers/media/common/tuners/mt20xx.c

@@ -148,7 +148,8 @@ static int mt2032_compute_freq(struct dvb_frontend *fe,
 	tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
 	tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
 		  rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
 		  rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
 
 
-	if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
+	if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
+			lo2n > 30) {
 		tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
 		tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
 			   lo1a, lo1n, lo2a,lo2n);
 			   lo1a, lo1n, lo2a,lo2n);
 		return(-1);
 		return(-1);

+ 1030 - 0
drivers/media/common/tuners/mxl5007t.c

@@ -0,0 +1,1030 @@
+/*
+ *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "mxl5007t.h"
+
+static DEFINE_MUTEX(mxl5007t_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+static int mxl5007t_debug;
+module_param_named(debug, mxl5007t_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level");
+
+/* ------------------------------------------------------------------------- */
+
+#define mxl_printk(kern, fmt, arg...) \
+	printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define mxl_err(fmt, arg...) \
+	mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
+
+#define mxl_warn(fmt, arg...) \
+	mxl_printk(KERN_WARNING, fmt, ##arg)
+
+#define mxl_info(fmt, arg...) \
+	mxl_printk(KERN_INFO, fmt, ##arg)
+
+#define mxl_debug(fmt, arg...)				\
+({							\
+	if (mxl5007t_debug)				\
+		mxl_printk(KERN_DEBUG, fmt, ##arg);	\
+})
+
+#define mxl_fail(ret)							\
+({									\
+	int __ret;							\
+	__ret = (ret < 0);						\
+	if (__ret)							\
+		mxl_printk(KERN_ERR, "error %d on line %d",		\
+			   ret, __LINE__);				\
+	__ret;								\
+})
+
+/* ------------------------------------------------------------------------- */
+
+#define MHz 1000000
+
+enum mxl5007t_mode {
+	MxL_MODE_OTA_DVBT_ATSC        =    0,
+	MxL_MODE_OTA_NTSC_PAL_GH      =    1,
+	MxL_MODE_OTA_PAL_IB           =    2,
+	MxL_MODE_OTA_PAL_D_SECAM_KL   =    3,
+	MxL_MODE_OTA_ISDBT            =    4,
+	MxL_MODE_CABLE_DIGITAL        = 0x10,
+	MxL_MODE_CABLE_NTSC_PAL_GH    = 0x11,
+	MxL_MODE_CABLE_PAL_IB         = 0x12,
+	MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
+	MxL_MODE_CABLE_SCTE40         = 0x14,
+};
+
+enum mxl5007t_chip_version {
+	MxL_UNKNOWN_ID     = 0x00,
+	MxL_5007_V1_F1     = 0x11,
+	MxL_5007_V1_F2     = 0x12,
+	MxL_5007_V2_100_F1 = 0x21,
+	MxL_5007_V2_100_F2 = 0x22,
+	MxL_5007_V2_200_F1 = 0x23,
+	MxL_5007_V2_200_F2 = 0x24,
+};
+
+struct reg_pair_t {
+	u8 reg;
+	u8 val;
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t init_tab[] = {
+	{ 0x0b, 0x44 }, /* XTAL */
+	{ 0x0c, 0x60 }, /* IF */
+	{ 0x10, 0x00 }, /* MISC */
+	{ 0x12, 0xca }, /* IDAC */
+	{ 0x16, 0x90 }, /* MODE */
+	{ 0x32, 0x38 }, /* MODE Analog/Digital */
+	{ 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
+	{ 0x2c, 0x34 }, /* OVERRIDE */
+	{ 0x4d, 0x40 }, /* OVERRIDE */
+	{ 0x7f, 0x02 }, /* OVERRIDE */
+	{ 0x9a, 0x52 }, /* OVERRIDE */
+	{ 0x48, 0x5a }, /* OVERRIDE */
+	{ 0x76, 0x1a }, /* OVERRIDE */
+	{ 0x6a, 0x48 }, /* OVERRIDE */
+	{ 0x64, 0x28 }, /* OVERRIDE */
+	{ 0x66, 0xe6 }, /* OVERRIDE */
+	{ 0x35, 0x0e }, /* OVERRIDE */
+	{ 0x7e, 0x01 }, /* OVERRIDE */
+	{ 0x83, 0x00 }, /* OVERRIDE */
+	{ 0x04, 0x0b }, /* OVERRIDE */
+	{ 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+	{ 0, 0 }
+};
+
+static struct reg_pair_t init_tab_cable[] = {
+	{ 0x0b, 0x44 }, /* XTAL */
+	{ 0x0c, 0x60 }, /* IF */
+	{ 0x10, 0x00 }, /* MISC */
+	{ 0x12, 0xca }, /* IDAC */
+	{ 0x16, 0x90 }, /* MODE */
+	{ 0x32, 0x38 }, /* MODE A/D */
+	{ 0x71, 0x3f }, /* TOP1 */
+	{ 0x72, 0x3f }, /* TOP2 */
+	{ 0x74, 0x3f }, /* TOP3 */
+	{ 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
+	{ 0x2c, 0x34 }, /* OVERRIDE */
+	{ 0x4d, 0x40 }, /* OVERRIDE */
+	{ 0x7f, 0x02 }, /* OVERRIDE */
+	{ 0x9a, 0x52 }, /* OVERRIDE */
+	{ 0x48, 0x5a }, /* OVERRIDE */
+	{ 0x76, 0x1a }, /* OVERRIDE */
+	{ 0x6a, 0x48 }, /* OVERRIDE */
+	{ 0x64, 0x28 }, /* OVERRIDE */
+	{ 0x66, 0xe6 }, /* OVERRIDE */
+	{ 0x35, 0x0e }, /* OVERRIDE */
+	{ 0x7e, 0x01 }, /* OVERRIDE */
+	{ 0x04, 0x0b }, /* OVERRIDE */
+	{ 0x68, 0xb4 }, /* OVERRIDE */
+	{ 0x36, 0x00 }, /* OVERRIDE */
+	{ 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+	{ 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t reg_pair_rftune[] = {
+	{ 0x11, 0x00 }, /* abort tune */
+	{ 0x13, 0x15 },
+	{ 0x14, 0x40 },
+	{ 0x15, 0x0e },
+	{ 0x11, 0x02 }, /* start tune */
+	{ 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+struct mxl5007t_state {
+	struct list_head hybrid_tuner_instance_list;
+	struct tuner_i2c_props i2c_props;
+
+	struct mutex lock;
+
+	struct mxl5007t_config *config;
+
+	enum mxl5007t_chip_version chip_id;
+
+	struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
+	struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
+	struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
+
+	u32 frequency;
+	u32 bandwidth;
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* called by _init and _rftun to manipulate the register arrays */
+
+static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
+{
+	unsigned int i = 0;
+
+	while (reg_pair[i].reg || reg_pair[i].val) {
+		if (reg_pair[i].reg == reg) {
+			reg_pair[i].val &= ~mask;
+			reg_pair[i].val |= val;
+		}
+		i++;
+
+	}
+	return;
+}
+
+static void copy_reg_bits(struct reg_pair_t *reg_pair1,
+			  struct reg_pair_t *reg_pair2)
+{
+	unsigned int i, j;
+
+	i = j = 0;
+
+	while (reg_pair1[i].reg || reg_pair1[i].val) {
+		while (reg_pair2[j].reg || reg_pair2[j].reg) {
+			if (reg_pair1[i].reg != reg_pair2[j].reg) {
+				j++;
+				continue;
+			}
+			reg_pair2[j].val = reg_pair1[i].val;
+			break;
+		}
+		i++;
+	}
+	return;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
+				   enum mxl5007t_mode mode,
+				   s32 if_diff_out_level)
+{
+	switch (mode) {
+	case MxL_MODE_OTA_DVBT_ATSC:
+		set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
+		set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
+		break;
+	case MxL_MODE_OTA_ISDBT:
+		set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
+		set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
+		break;
+	case MxL_MODE_OTA_NTSC_PAL_GH:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		break;
+	case MxL_MODE_OTA_PAL_IB:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		break;
+	case MxL_MODE_OTA_PAL_D_SECAM_KL:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		break;
+	case MxL_MODE_CABLE_DIGITAL:
+		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+			     8 - if_diff_out_level);
+		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		break;
+	case MxL_MODE_CABLE_NTSC_PAL_GH:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+			     8 - if_diff_out_level);
+		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		break;
+	case MxL_MODE_CABLE_PAL_IB:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+			     8 - if_diff_out_level);
+		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		break;
+	case MxL_MODE_CABLE_PAL_D_SECAM_KL:
+		set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
+		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+			     8 - if_diff_out_level);
+		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		break;
+	case MxL_MODE_CABLE_SCTE40:
+		set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
+		set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
+		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+			     8 - if_diff_out_level);
+		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		break;
+	default:
+		mxl_fail(-EINVAL);
+	}
+	return;
+}
+
+static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
+				      enum mxl5007t_if_freq if_freq,
+				      int invert_if)
+{
+	u8 val;
+
+	switch (if_freq) {
+	case MxL_IF_4_MHZ:
+		val = 0x00;
+		break;
+	case MxL_IF_4_5_MHZ:
+		val = 0x20;
+		break;
+	case MxL_IF_4_57_MHZ:
+		val = 0x30;
+		break;
+	case MxL_IF_5_MHZ:
+		val = 0x40;
+		break;
+	case MxL_IF_5_38_MHZ:
+		val = 0x50;
+		break;
+	case MxL_IF_6_MHZ:
+		val = 0x60;
+		break;
+	case MxL_IF_6_28_MHZ:
+		val = 0x70;
+		break;
+	case MxL_IF_9_1915_MHZ:
+		val = 0x80;
+		break;
+	case MxL_IF_35_25_MHZ:
+		val = 0x90;
+		break;
+	case MxL_IF_36_15_MHZ:
+		val = 0xa0;
+		break;
+	case MxL_IF_44_MHZ:
+		val = 0xb0;
+		break;
+	default:
+		mxl_fail(-EINVAL);
+		return;
+	}
+	set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+
+	/* set inverted IF or normal IF */
+	set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+
+	return;
+}
+
+static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
+					enum mxl5007t_xtal_freq xtal_freq)
+{
+	u8 val;
+
+	switch (xtal_freq) {
+	case MxL_XTAL_16_MHZ:
+		val = 0x00; /* select xtal freq & Ref Freq */
+		break;
+	case MxL_XTAL_20_MHZ:
+		val = 0x11;
+		break;
+	case MxL_XTAL_20_25_MHZ:
+		val = 0x22;
+		break;
+	case MxL_XTAL_20_48_MHZ:
+		val = 0x33;
+		break;
+	case MxL_XTAL_24_MHZ:
+		val = 0x44;
+		break;
+	case MxL_XTAL_25_MHZ:
+		val = 0x55;
+		break;
+	case MxL_XTAL_25_14_MHZ:
+		val = 0x66;
+		break;
+	case MxL_XTAL_27_MHZ:
+		val = 0x77;
+		break;
+	case MxL_XTAL_28_8_MHZ:
+		val = 0x88;
+		break;
+	case MxL_XTAL_32_MHZ:
+		val = 0x99;
+		break;
+	case MxL_XTAL_40_MHZ:
+		val = 0xaa;
+		break;
+	case MxL_XTAL_44_MHZ:
+		val = 0xbb;
+		break;
+	case MxL_XTAL_48_MHZ:
+		val = 0xcc;
+		break;
+	case MxL_XTAL_49_3811_MHZ:
+		val = 0xdd;
+		break;
+	default:
+		mxl_fail(-EINVAL);
+		return;
+	}
+	set_reg_bits(state->tab_init, 0x0b, 0xff, val);
+
+	return;
+}
+
+static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
+						  enum mxl5007t_mode mode)
+{
+	struct mxl5007t_config *cfg = state->config;
+
+	memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
+	memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
+
+	mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
+	mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
+	mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
+
+	set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
+
+	set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
+
+	set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
+
+	/* set IDAC to automatic mode control by AGC */
+	set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
+
+	if (mode >= MxL_MODE_CABLE_DIGITAL) {
+		copy_reg_bits(state->tab_init, state->tab_init_cable);
+		return state->tab_init_cable;
+	} else
+		return state->tab_init;
+}
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_bw_mhz {
+	MxL_BW_6MHz = 6,
+	MxL_BW_7MHz = 7,
+	MxL_BW_8MHz = 8,
+};
+
+static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
+				 enum mxl5007t_bw_mhz bw)
+{
+	u8 val;
+
+	switch (bw) {
+	case MxL_BW_6MHz:
+		val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
+			     * and DIG_MODEINDEX_CSF */
+		break;
+	case MxL_BW_7MHz:
+		val = 0x21;
+		break;
+	case MxL_BW_8MHz:
+		val = 0x3f;
+		break;
+	default:
+		mxl_fail(-EINVAL);
+		return;
+	}
+	set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+
+	return;
+}
+
+static struct
+reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
+				       u32 rf_freq, enum mxl5007t_bw_mhz bw)
+{
+	u32 dig_rf_freq = 0;
+	u32 temp;
+	u32 frac_divider = 1000000;
+	unsigned int i;
+
+	memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
+
+	mxl5007t_set_bw_bits(state, bw);
+
+	/* Convert RF frequency into 16 bits =>
+	 * 10 bit integer (MHz) + 6 bit fraction */
+	dig_rf_freq = rf_freq / MHz;
+
+	temp = rf_freq % MHz;
+
+	for (i = 0; i < 6; i++) {
+		dig_rf_freq <<= 1;
+		frac_divider /= 2;
+		if (temp > frac_divider) {
+			temp -= frac_divider;
+			dig_rf_freq++;
+		}
+	}
+
+	/* add to have shift center point by 7.8124 kHz */
+	if (temp > 7812)
+		dig_rf_freq++;
+
+	set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
+	set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+
+	return state->tab_rftune;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
+{
+	u8 buf[] = { reg, val };
+	struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
+			       .buf = buf, .len = 2 };
+	int ret;
+
+	ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+	if (ret != 1) {
+		mxl_err("failed!");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int mxl5007t_write_regs(struct mxl5007t_state *state,
+			       struct reg_pair_t *reg_pair)
+{
+	unsigned int i = 0;
+	int ret = 0;
+
+	while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
+		ret = mxl5007t_write_reg(state,
+					 reg_pair[i].reg, reg_pair[i].val);
+		i++;
+	}
+	return ret;
+}
+
+static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[] = {
+		{ .addr = state->i2c_props.addr, .flags = 0,
+		  .buf = &reg, .len = 1 },
+		{ .addr = state->i2c_props.addr, .flags = I2C_M_RD,
+		  .buf = val, .len = 1 },
+	};
+	int ret;
+
+	ret = i2c_transfer(state->i2c_props.adap, msg, 2);
+	if (ret != 2) {
+		mxl_err("failed!");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int mxl5007t_soft_reset(struct mxl5007t_state *state)
+{
+	u8 d = 0xff;
+	struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
+			       .buf = &d, .len = 1 };
+
+	int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+
+	if (ret != 1) {
+		mxl_err("failed!");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int mxl5007t_tuner_init(struct mxl5007t_state *state,
+			       enum mxl5007t_mode mode)
+{
+	struct reg_pair_t *init_regs;
+	int ret;
+
+	ret = mxl5007t_soft_reset(state);
+	if (mxl_fail(ret))
+		goto fail;
+
+	/* calculate initialization reg array */
+	init_regs = mxl5007t_calc_init_regs(state, mode);
+
+	ret = mxl5007t_write_regs(state, init_regs);
+	if (mxl_fail(ret))
+		goto fail;
+	mdelay(1);
+
+	ret = mxl5007t_write_reg(state, 0x2c, 0x35);
+	mxl_fail(ret);
+fail:
+	return ret;
+}
+
+static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
+				  enum mxl5007t_bw_mhz bw)
+{
+	struct reg_pair_t *rf_tune_regs;
+	int ret;
+
+	/* calculate channel change reg array */
+	rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
+
+	ret = mxl5007t_write_regs(state, rf_tune_regs);
+	if (mxl_fail(ret))
+		goto fail;
+	msleep(3);
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
+				      int *rf_locked, int *ref_locked)
+{
+	u8 d;
+	int ret;
+
+	*rf_locked = 0;
+	*ref_locked = 0;
+
+	ret = mxl5007t_read_reg(state, 0xcf, &d);
+	if (mxl_fail(ret))
+		goto fail;
+
+	if ((d & 0x0c) == 0x0c)
+		*rf_locked = 1;
+
+	if ((d & 0x03) == 0x03)
+		*ref_locked = 1;
+fail:
+	return ret;
+}
+
+static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
+					 s32 *rf_input_level)
+{
+	u8 d1, d2;
+	int ret;
+
+	ret = mxl5007t_read_reg(state, 0xb7, &d1);
+	if (mxl_fail(ret))
+		goto fail;
+
+	ret = mxl5007t_read_reg(state, 0xbf, &d2);
+	if (mxl_fail(ret))
+		goto fail;
+
+	d2 = d2 >> 4;
+	if (d2 > 7)
+		d2 += 0xf0;
+
+	*rf_input_level = (s32)(d1 + d2 - 113);
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	int rf_locked, ref_locked;
+	s32 rf_input_level;
+	int ret;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
+	if (mxl_fail(ret))
+		goto fail;
+	mxl_debug("%s%s", rf_locked ? "rf locked " : "",
+		  ref_locked ? "ref locked" : "");
+
+	ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
+	if (mxl_fail(ret))
+		goto fail;
+	mxl_debug("rf input power: %d", rf_input_level);
+fail:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_set_params(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *params)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	enum mxl5007t_bw_mhz bw;
+	enum mxl5007t_mode mode;
+	int ret;
+	u32 freq = params->frequency;
+
+	if (fe->ops.info.type == FE_ATSC) {
+		switch (params->u.vsb.modulation) {
+		case VSB_8:
+		case VSB_16:
+			mode = MxL_MODE_OTA_DVBT_ATSC;
+			break;
+		case QAM_64:
+		case QAM_256:
+			mode = MxL_MODE_CABLE_DIGITAL;
+			break;
+		default:
+			mxl_err("modulation not set!");
+			return -EINVAL;
+		}
+		bw = MxL_BW_6MHz;
+	} else if (fe->ops.info.type == FE_OFDM) {
+		switch (params->u.ofdm.bandwidth) {
+		case BANDWIDTH_6_MHZ:
+			bw = MxL_BW_6MHz;
+			break;
+		case BANDWIDTH_7_MHZ:
+			bw = MxL_BW_7MHz;
+			break;
+		case BANDWIDTH_8_MHZ:
+			bw = MxL_BW_8MHz;
+			break;
+		default:
+			mxl_err("bandwidth not set!");
+			return -EINVAL;
+		}
+		mode = MxL_MODE_OTA_DVBT_ATSC;
+	} else {
+		mxl_err("modulation type not supported!");
+		return -EINVAL;
+	}
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	mutex_lock(&state->lock);
+
+	ret = mxl5007t_tuner_init(state, mode);
+	if (mxl_fail(ret))
+		goto fail;
+
+	ret = mxl5007t_tuner_rf_tune(state, freq, bw);
+	if (mxl_fail(ret))
+		goto fail;
+
+	state->frequency = freq;
+	state->bandwidth = (fe->ops.info.type == FE_OFDM) ?
+		params->u.ofdm.bandwidth : 0;
+fail:
+	mutex_unlock(&state->lock);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
+				      struct analog_parameters *params)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	enum mxl5007t_bw_mhz bw = 0; /* FIXME */
+	enum mxl5007t_mode cbl_mode;
+	enum mxl5007t_mode ota_mode;
+	char *mode_name;
+	int ret;
+	u32 freq = params->frequency * 62500;
+
+#define cable 1
+	if (params->std & V4L2_STD_MN) {
+		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+		mode_name = "MN";
+	} else if (params->std & V4L2_STD_B) {
+		cbl_mode = MxL_MODE_CABLE_PAL_IB;
+		ota_mode = MxL_MODE_OTA_PAL_IB;
+		mode_name = "B";
+	} else if (params->std & V4L2_STD_GH) {
+		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+		mode_name = "GH";
+	} else if (params->std & V4L2_STD_PAL_I) {
+		cbl_mode = MxL_MODE_CABLE_PAL_IB;
+		ota_mode = MxL_MODE_OTA_PAL_IB;
+		mode_name = "I";
+	} else if (params->std & V4L2_STD_DK) {
+		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+		mode_name = "DK";
+	} else if (params->std & V4L2_STD_SECAM_L) {
+		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+		mode_name = "L";
+	} else if (params->std & V4L2_STD_SECAM_LC) {
+		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+		mode_name = "L'";
+	} else {
+		mode_name = "xx";
+		/* FIXME */
+		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+	}
+	mxl_debug("setting mxl5007 to system %s", mode_name);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	mutex_lock(&state->lock);
+
+	ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
+	if (mxl_fail(ret))
+		goto fail;
+
+	ret = mxl5007t_tuner_rf_tune(state, freq, bw);
+	if (mxl_fail(ret))
+		goto fail;
+
+	state->frequency = freq;
+	state->bandwidth = 0;
+fail:
+	mutex_unlock(&state->lock);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_init(struct dvb_frontend *fe)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	int ret;
+	u8 d;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	ret = mxl5007t_read_reg(state, 0x05, &d);
+	if (mxl_fail(ret))
+		goto fail;
+
+	ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+	mxl_fail(ret);
+fail:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+static int mxl5007t_sleep(struct dvb_frontend *fe)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	int ret;
+	u8 d;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	ret = mxl5007t_read_reg(state, 0x05, &d);
+	if (mxl_fail(ret))
+		goto fail;
+
+	ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+	mxl_fail(ret);
+fail:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	*frequency = state->frequency;
+	return 0;
+}
+
+static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+	*bandwidth = state->bandwidth;
+	return 0;
+}
+
+static int mxl5007t_release(struct dvb_frontend *fe)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+
+	mutex_lock(&mxl5007t_list_mutex);
+
+	if (state)
+		hybrid_tuner_release_state(state);
+
+	mutex_unlock(&mxl5007t_list_mutex);
+
+	fe->tuner_priv = NULL;
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct dvb_tuner_ops mxl5007t_tuner_ops = {
+	.info = {
+		.name = "MaxLinear MxL5007T",
+	},
+	.init              = mxl5007t_init,
+	.sleep             = mxl5007t_sleep,
+	.set_params        = mxl5007t_set_params,
+	.set_analog_params = mxl5007t_set_analog_params,
+	.get_status        = mxl5007t_get_status,
+	.get_frequency     = mxl5007t_get_frequency,
+	.get_bandwidth     = mxl5007t_get_bandwidth,
+	.release           = mxl5007t_release,
+};
+
+static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
+{
+	char *name;
+	int ret;
+	u8 id;
+
+	ret = mxl5007t_read_reg(state, 0xd3, &id);
+	if (mxl_fail(ret))
+		goto fail;
+
+	switch (id) {
+	case MxL_5007_V1_F1:
+		name = "MxL5007.v1.f1";
+		break;
+	case MxL_5007_V1_F2:
+		name = "MxL5007.v1.f2";
+		break;
+	case MxL_5007_V2_100_F1:
+		name = "MxL5007.v2.100.f1";
+		break;
+	case MxL_5007_V2_100_F2:
+		name = "MxL5007.v2.100.f2";
+		break;
+	case MxL_5007_V2_200_F1:
+		name = "MxL5007.v2.200.f1";
+		break;
+	case MxL_5007_V2_200_F2:
+		name = "MxL5007.v2.200.f2";
+		break;
+	default:
+		name = "MxL5007T";
+		id = MxL_UNKNOWN_ID;
+	}
+	state->chip_id = id;
+	mxl_info("%s detected @ %d-%04x", name,
+		 i2c_adapter_id(state->i2c_props.adap),
+		 state->i2c_props.addr);
+	return 0;
+fail:
+	mxl_warn("unable to identify device @ %d-%04x",
+		 i2c_adapter_id(state->i2c_props.adap),
+		 state->i2c_props.addr);
+
+	state->chip_id = MxL_UNKNOWN_ID;
+	return ret;
+}
+
+struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+				     struct i2c_adapter *i2c, u8 addr,
+				     struct mxl5007t_config *cfg)
+{
+	struct mxl5007t_state *state = NULL;
+	int instance, ret;
+
+	mutex_lock(&mxl5007t_list_mutex);
+	instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
+					      hybrid_tuner_instance_list,
+					      i2c, addr, "mxl5007");
+	switch (instance) {
+	case 0:
+		goto fail;
+		break;
+	case 1:
+		/* new tuner instance */
+		state->config = cfg;
+
+		mutex_init(&state->lock);
+
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+
+		ret = mxl5007t_get_chip_id(state);
+
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+		/* check return value of mxl5007t_get_chip_id */
+		if (mxl_fail(ret))
+			goto fail;
+		break;
+	default:
+		/* existing tuner instance */
+		break;
+	}
+	fe->tuner_priv = state;
+	mutex_unlock(&mxl5007t_list_mutex);
+
+	memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
+	       sizeof(struct dvb_tuner_ops));
+
+	return fe;
+fail:
+	mutex_unlock(&mxl5007t_list_mutex);
+
+	mxl5007t_release(fe);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(mxl5007t_attach);
+MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */

+ 104 - 0
drivers/media/common/tuners/mxl5007t.h

@@ -0,0 +1,104 @@
+/*
+ *  mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MXL5007T_H__
+#define __MXL5007T_H__
+
+#include "dvb_frontend.h"
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_if_freq {
+	MxL_IF_4_MHZ,      /*  4000000 */
+	MxL_IF_4_5_MHZ,    /*  4500000 */
+	MxL_IF_4_57_MHZ,   /*  4570000 */
+	MxL_IF_5_MHZ,      /*  5000000 */
+	MxL_IF_5_38_MHZ,   /*  5380000 */
+	MxL_IF_6_MHZ,      /*  6000000 */
+	MxL_IF_6_28_MHZ,   /*  6280000 */
+	MxL_IF_9_1915_MHZ, /*  9191500 */
+	MxL_IF_35_25_MHZ,  /* 35250000 */
+	MxL_IF_36_15_MHZ,  /* 36150000 */
+	MxL_IF_44_MHZ,     /* 44000000 */
+};
+
+enum mxl5007t_xtal_freq {
+	MxL_XTAL_16_MHZ,      /* 16000000 */
+	MxL_XTAL_20_MHZ,      /* 20000000 */
+	MxL_XTAL_20_25_MHZ,   /* 20250000 */
+	MxL_XTAL_20_48_MHZ,   /* 20480000 */
+	MxL_XTAL_24_MHZ,      /* 24000000 */
+	MxL_XTAL_25_MHZ,      /* 25000000 */
+	MxL_XTAL_25_14_MHZ,   /* 25140000 */
+	MxL_XTAL_27_MHZ,      /* 27000000 */
+	MxL_XTAL_28_8_MHZ,    /* 28800000 */
+	MxL_XTAL_32_MHZ,      /* 32000000 */
+	MxL_XTAL_40_MHZ,      /* 40000000 */
+	MxL_XTAL_44_MHZ,      /* 44000000 */
+	MxL_XTAL_48_MHZ,      /* 48000000 */
+	MxL_XTAL_49_3811_MHZ, /* 49381100 */
+};
+
+enum mxl5007t_clkout_amp {
+	MxL_CLKOUT_AMP_0_94V = 0,
+	MxL_CLKOUT_AMP_0_53V = 1,
+	MxL_CLKOUT_AMP_0_37V = 2,
+	MxL_CLKOUT_AMP_0_28V = 3,
+	MxL_CLKOUT_AMP_0_23V = 4,
+	MxL_CLKOUT_AMP_0_20V = 5,
+	MxL_CLKOUT_AMP_0_17V = 6,
+	MxL_CLKOUT_AMP_0_15V = 7,
+};
+
+struct mxl5007t_config {
+	s32 if_diff_out_level;
+	enum mxl5007t_clkout_amp clk_out_amp;
+	enum mxl5007t_xtal_freq xtal_freq_hz;
+	enum mxl5007t_if_freq if_freq_hz;
+	unsigned int invert_if:1;
+	unsigned int loop_thru_enable:1;
+	unsigned int clk_out_enable:1;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+					    struct i2c_adapter *i2c, u8 addr,
+					    struct mxl5007t_config *cfg);
+#else
+static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+						   struct i2c_adapter *i2c,
+						   u8 addr,
+						   struct mxl5007t_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif /* __MXL5007T_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+

+ 1 - 1
drivers/media/common/tuners/tda9887.c

@@ -6,7 +6,7 @@
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 #include <media/tuner.h>
 #include "tuner-i2c.h"
 #include "tuner-i2c.h"

+ 1 - 1
drivers/media/common/tuners/tuner-simple.c

@@ -6,7 +6,7 @@
  */
  */
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/tuner.h>
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/tuner-types.h>
 #include <media/tuner-types.h>

+ 0 - 2
drivers/media/dvb/bt8xx/Kconfig

@@ -1,7 +1,6 @@
 config DVB_BT8XX
 config DVB_BT8XX
 	tristate "BT8xx based PCI cards"
 	tristate "BT8xx based PCI cards"
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
-	depends on HOTPLUG	# due to FW_LOADER
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
@@ -10,7 +9,6 @@ config DVB_BT8XX
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
 	  the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,

+ 8 - 2
drivers/media/dvb/dvb-usb/Kconfig

@@ -1,8 +1,6 @@
 config DVB_USB
 config DVB_USB
 	tristate "Support for various USB DVB devices"
 	tristate "Support for various USB DVB devices"
 	depends on DVB_CORE && USB && I2C && INPUT
 	depends on DVB_CORE && USB && I2C && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
-	select FW_LOADER
 	help
 	help
 	  By enabling this you will be able to choose the various supported
 	  By enabling this you will be able to choose the various supported
 	  USB1.1 and USB2.0 DVB devices.
 	  USB1.1 and USB2.0 DVB devices.
@@ -246,6 +244,14 @@ config DVB_USB_AF9005_REMOTE
 	  Say Y here to support the default remote control decoding for the
 	  Say Y here to support the default remote control decoding for the
 	  Afatech AF9005 based receiver.
 	  Afatech AF9005 based receiver.
 
 
+config DVB_USB_DW2102
+	tristate "DvbWorld 2102 DVB-S USB2.0 receiver"
+	depends on DVB_USB
+	select DVB_STV0299 if !DVB_FE_CUSTOMISE
+	select DVB_PLL if !DVB_FE_CUSTOMISE
+	help
+	   Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver.
+
 config DVB_USB_ANYSEE
 config DVB_USB_ANYSEE
 	tristate "Anysee DVB-T/C USB2.0 support"
 	tristate "Anysee DVB-T/C USB2.0 support"
 	depends on DVB_USB
 	depends on DVB_USB

+ 3 - 0
drivers/media/dvb/dvb-usb/Makefile

@@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
 dvb-usb-anysee-objs = anysee.o
 dvb-usb-anysee-objs = anysee.o
 obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
 obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
 
 
+dvb-usb-dw2102-objs = dw2102.o
+obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
 EXTRA_CFLAGS += -Idrivers/media/common/tuners

+ 1 - 1
drivers/media/dvb/dvb-usb/anysee.c

@@ -43,7 +43,7 @@ module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
 MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
-struct mutex anysee_usb_mutex;
+static struct mutex anysee_usb_mutex;
 
 
 static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
 static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
 	u8 *rbuf, u8 rlen)
 	u8 *rbuf, u8 rlen)

+ 1 - 0
drivers/media/dvb/dvb-usb/dvb-usb-ids.h

@@ -204,5 +204,6 @@
 #define USB_PID_ASUS_U3000				0x171f
 #define USB_PID_ASUS_U3000				0x171f
 #define USB_PID_ASUS_U3100				0x173f
 #define USB_PID_ASUS_U3100				0x173f
 #define USB_PID_YUAN_EC372S				0x1edc
 #define USB_PID_YUAN_EC372S				0x1edc
+#define USB_PID_DW2102					0x2102
 
 
 #endif
 #endif

+ 425 - 0
drivers/media/dvb/dvb-usb/dw2102.c

@@ -0,0 +1,425 @@
+/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+*	This program is free software; you can redistribute it and/or modify it
+*	under the terms of the GNU General Public License as published by the
+*	Free Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+#include <linux/version.h>
+#include "dw2102.h"
+#include "stv0299.h"
+#include "z0194a.h"
+
+#ifndef USB_PID_DW2102
+#define USB_PID_DW2102 0x2102
+#endif
+
+#define DW2102_READ_MSG 0
+#define DW2102_WRITE_MSG 1
+
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+
+#define DW2102_VOLTAGE_CTRL (0x1800)
+#define DW2102_RC_QUERY (0x1a00)
+
+struct dw2102_state {
+	u32 last_key_pressed;
+};
+struct dw2102_rc_keys {
+	u32 keycode;
+	u32 event;
+};
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value,
+		u8 *data, u16 len, int flags)
+{
+	int ret;
+	u8 u8buf[len];
+
+	unsigned int pipe = (flags == DW2102_READ_MSG) ?
+		usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
+	u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+	if (flags == DW2102_WRITE_MSG)
+		memcpy(u8buf, data, len);
+	ret = usb_control_msg(dev, pipe, request,
+		request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000);
+
+	if (flags == DW2102_READ_MSG)
+		memcpy(data, u8buf, len);
+	return ret;
+}
+
+/* I2C */
+
+static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+		int num)
+{
+struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i = 0, ret = 0;
+	u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
+	u8 request;
+	u16 value;
+
+	if (!d)
+		return -ENODEV;
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	switch (num) {
+	case 2:
+		/* read stv0299 register */
+		request = 0xb5;
+		value = msg[0].buf[0];/* register */
+		for (i = 0; i < msg[1].len; i++) {
+			value = value + i;
+			ret = dw2102_op_rw(d->udev, 0xb5,
+				value, buf6, 2, DW2102_READ_MSG);
+			msg[1].buf[i] = buf6[0];
+
+		}
+		break;
+	case 1:
+		switch (msg[0].addr) {
+		case 0x68:
+			/* write to stv0299 register */
+			buf6[0] = 0x2a;
+			buf6[1] = msg[0].buf[0];
+			buf6[2] = msg[0].buf[1];
+			ret = dw2102_op_rw(d->udev, 0xb2,
+				0, buf6, 3, DW2102_WRITE_MSG);
+			break;
+		case 0x60:
+			if (msg[0].flags == 0) {
+			/* write to tuner pll */
+				buf6[0] = 0x2c;
+				buf6[1] = 5;
+				buf6[2] = 0xc0;
+				buf6[3] = msg[0].buf[0];
+				buf6[4] = msg[0].buf[1];
+				buf6[5] = msg[0].buf[2];
+				buf6[6] = msg[0].buf[3];
+				ret = dw2102_op_rw(d->udev, 0xb2,
+				0, buf6, 7, DW2102_WRITE_MSG);
+			} else {
+			/* write to tuner pll */
+				ret = dw2102_op_rw(d->udev, 0xb5,
+				0, buf6, 1, DW2102_READ_MSG);
+				msg[0].buf[0] = buf6[0];
+			}
+			break;
+		case (DW2102_RC_QUERY):
+			ret  = dw2102_op_rw(d->udev, 0xb8,
+				0, buf6, 2, DW2102_READ_MSG);
+			msg[0].buf[0] = buf6[0];
+			msg[0].buf[1] = buf6[1];
+			break;
+		case (DW2102_VOLTAGE_CTRL):
+			buf6[0] = 0x30;
+			buf6[1] = msg[0].buf[0];
+			ret = dw2102_op_rw(d->udev, 0xb2,
+				0, buf6, 2, DW2102_WRITE_MSG);
+			break;
+		}
+
+		break;
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return num;
+}
+
+static u32 dw2102_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dw2102_i2c_algo = {
+	.master_xfer = dw2102_i2c_transfer,
+	.functionality = dw2102_i2c_func,
+};
+
+static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	static u8 command_13v[1] = {0x00};
+	static u8 command_18v[1] = {0x01};
+	struct i2c_msg msg[] = {
+		{.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
+			.buf = command_13v, .len = 1},
+	};
+
+	struct dvb_usb_adapter *udev_adap =
+		(struct dvb_usb_adapter *)(fe->dvb->priv);
+	if (voltage == SEC_VOLTAGE_18)
+		msg[0].buf = command_18v;
+	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+	return 0;
+}
+
+static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
+{
+	d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
+		&d->dev->i2c_adap);
+	if (d->fe != NULL) {
+		d->fe->ops.set_voltage = dw2102_set_voltage;
+		info("Attached stv0299!\n");
+		return 0;
+	}
+	return -EIO;
+}
+
+static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
+		&adap->dev->i2c_adap, DVB_PLL_OPERA1);
+	return 0;
+}
+
+static struct dvb_usb_rc_key dw2102_rc_keys[] = {
+	{ 0xf8,	0x0a, KEY_Q },		/*power*/
+	{ 0xf8,	0x0c, KEY_M },		/*mute*/
+	{ 0xf8,	0x11, KEY_1 },
+	{ 0xf8,	0x12, KEY_2 },
+	{ 0xf8,	0x13, KEY_3 },
+	{ 0xf8,	0x14, KEY_4 },
+	{ 0xf8,	0x15, KEY_5 },
+	{ 0xf8,	0x16, KEY_6 },
+	{ 0xf8,	0x17, KEY_7 },
+	{ 0xf8,	0x18, KEY_8 },
+	{ 0xf8,	0x19, KEY_9 },
+	{ 0xf8, 0x10, KEY_0 },
+	{ 0xf8, 0x1c, KEY_PAGEUP },	/*ch+*/
+	{ 0xf8, 0x0f, KEY_PAGEDOWN },	/*ch-*/
+	{ 0xf8, 0x1a, KEY_O },		/*vol+*/
+	{ 0xf8, 0x0e, KEY_Z },		/*vol-*/
+	{ 0xf8, 0x04, KEY_R },		/*rec*/
+	{ 0xf8, 0x09, KEY_D },		/*fav*/
+	{ 0xf8, 0x08, KEY_BACKSPACE },	/*rewind*/
+	{ 0xf8, 0x07, KEY_A },		/*fast*/
+	{ 0xf8, 0x0b, KEY_P },		/*pause*/
+	{ 0xf8, 0x02, KEY_ESC },	/*cancel*/
+	{ 0xf8, 0x03, KEY_G },		/*tab*/
+	{ 0xf8, 0x00, KEY_UP },		/*up*/
+	{ 0xf8, 0x1f, KEY_ENTER },	/*ok*/
+	{ 0xf8, 0x01, KEY_DOWN },	/*down*/
+	{ 0xf8, 0x05, KEY_C },		/*cap*/
+	{ 0xf8, 0x06, KEY_S },		/*stop*/
+	{ 0xf8, 0x40, KEY_F },		/*full*/
+	{ 0xf8, 0x1e, KEY_W },		/*tvmode*/
+	{ 0xf8, 0x1b, KEY_B },		/*recall*/
+
+};
+
+
+
+static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	struct dw2102_state *st = d->priv;
+	u8 key[2];
+	struct i2c_msg msg[] = {
+		{.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
+		.len = 2},
+	};
+	int i;
+
+	*state = REMOTE_NO_KEY_PRESSED;
+	if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
+		for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) {
+			if (dw2102_rc_keys[i].data == msg[0].buf[0]) {
+				*state = REMOTE_KEY_PRESSED;
+				*event = dw2102_rc_keys[i].event;
+				st->last_key_pressed =
+					dw2102_rc_keys[i].event;
+				break;
+			}
+		st->last_key_pressed = 0;
+		}
+	}
+	/* info("key: %x %x\n",key[0],key[1]); */
+	return 0;
+}
+
+static struct usb_device_id dw2102_table[] = {
+	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
+	{USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, dw2102_table);
+
+static int dw2102_load_firmware(struct usb_device *dev,
+			const struct firmware *frmwr)
+{
+	u8 *b, *p;
+	int ret = 0, i;
+	u8 reset;
+	u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0};
+	const struct firmware *fw;
+	const char *filename = "dvb-usb-dw2101.fw";
+	switch (dev->descriptor.idProduct) {
+	case 0x2101:
+		ret = request_firmware(&fw, filename, &dev->dev);
+		if (ret != 0) {
+			err("did not find the firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details "
+			"on firmware-problems.", filename);
+			return ret;
+		}
+		break;
+	case USB_PID_DW2102:
+		fw = frmwr;
+		break;
+	}
+	info("start downloading DW2102 firmware");
+	p = kmalloc(fw->size, GFP_KERNEL);
+	reset = 1;
+	/*stop the CPU*/
+	dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG);
+	dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG);
+
+	if (p != NULL) {
+		memcpy(p, fw->data, fw->size);
+		for (i = 0; i < fw->size; i += 0x40) {
+			b = (u8 *) p + i;
+			if (dw2102_op_rw
+				(dev, 0xa0, i, b , 0x40,
+					DW2102_WRITE_MSG) != 0x40
+				) {
+				err("error while transferring firmware");
+				ret = -EINVAL;
+				break;
+			}
+		}
+		/* restart the CPU */
+		reset = 0;
+		if (ret || dw2102_op_rw
+			(dev, 0xa0, 0x7f92, &reset, 1,
+			DW2102_WRITE_MSG) != 1) {
+			err("could not restart the USB controller CPU.");
+			ret = -EINVAL;
+		}
+		if (ret || dw2102_op_rw
+			(dev, 0xa0, 0xe600, &reset, 1,
+			DW2102_WRITE_MSG) != 1) {
+			err("could not restart the USB controller CPU.");
+			ret = -EINVAL;
+		}
+		/* init registers */
+		switch (dev->descriptor.idProduct) {
+		case USB_PID_DW2102:
+			dw2102_op_rw
+				(dev, 0xbf, 0x0040, &reset, 0,
+				DW2102_WRITE_MSG);
+			dw2102_op_rw
+				(dev, 0xb9, 0x0000, &reset16[0], 2,
+				DW2102_READ_MSG);
+			break;
+		case 0x2101:
+			dw2102_op_rw
+				(dev, 0xbc, 0x0030, &reset16[0], 2,
+				DW2102_READ_MSG);
+			dw2102_op_rw
+				(dev, 0xba, 0x0000, &reset16[0], 7,
+				DW2102_READ_MSG);
+			dw2102_op_rw
+				(dev, 0xba, 0x0000, &reset16[0], 7,
+				DW2102_READ_MSG);
+			dw2102_op_rw
+				(dev, 0xb9, 0x0000, &reset16[0], 2,
+				DW2102_READ_MSG);
+			break;
+		}
+		kfree(p);
+	}
+	return ret;
+}
+
+static struct dvb_usb_device_properties dw2102_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.firmware = "dvb-usb-dw2102.fw",
+	.size_of_priv = sizeof(struct dw2102_state),
+	.no_reconnect = 1,
+
+	.i2c_algo = &dw2102_i2c_algo,
+	.rc_key_map = dw2102_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys),
+	.rc_interval = 150,
+	.rc_query = dw2102_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x81,
+	/* parameter for the MPEG2-data transfer */
+	.num_adapters = 1,
+	.download_firmware = dw2102_load_firmware,
+	.adapter = {
+		{
+			.frontend_attach = dw2102_frontend_attach,
+			.streaming_ctrl = NULL,
+			.tuner_attach = dw2102_tuner_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 8,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			},
+		}
+	},
+	.num_device_descs = 2,
+	.devices = {
+		{"DVBWorld DVB-S 2102 USB2.0",
+			{&dw2102_table[0], NULL},
+			{NULL},
+		},
+		{"DVBWorld DVB-S 2101 USB2.0",
+			{&dw2102_table[1], NULL},
+			{NULL},
+		},
+	}
+};
+
+static int dw2102_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf, &dw2102_properties,
+		THIS_MODULE, NULL, adapter_nr);
+}
+
+static struct usb_driver dw2102_driver = {
+	.name = "dw2102",
+	.probe = dw2102_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table = dw2102_table,
+};
+
+static int __init dw2102_module_init(void)
+{
+	int ret =  usb_register(&dw2102_driver);
+	if (ret)
+		err("usb_register failed. Error number %d", ret);
+
+	return ret;
+}
+
+static void __exit dw2102_module_exit(void)
+{
+	usb_deregister(&dw2102_driver);
+}
+
+module_init(dw2102_module_init);
+module_exit(dw2102_module_exit);
+
+MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
+MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");

+ 9 - 0
drivers/media/dvb/dvb-usb/dw2102.h

@@ -0,0 +1,9 @@
+#ifndef _DW2102_H_
+#define _DW2102_H_
+
+#define DVB_USB_LOG_PREFIX "dw2102"
+#include "dvb-usb.h"
+
+extern int dvb_usb_dw2102_debug;
+#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
+#endif

+ 22 - 16
drivers/media/dvb/frontends/Kconfig

@@ -97,9 +97,8 @@ comment "DVB-T (terrestrial) frontends"
 
 
 config DVB_SP8870
 config DVB_SP8870
 	tristate "Spase sp8870 based"
 	tristate "Spase sp8870 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 
@@ -110,9 +109,8 @@ config DVB_SP8870
 
 
 config DVB_SP887X
 config DVB_SP887X
 	tristate "Spase sp887x based"
 	tristate "Spase sp887x based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 
@@ -135,6 +133,20 @@ config DVB_CX22702
 	help
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 
+config DVB_DRX397XD
+	tristate "Micronas DRX3975D/DRX3977D based"
+	depends on DVB_CORE && I2C && HOTPLUG
+	default m if DVB_FE_CUSTOMISE
+	select FW_LOADER
+	help
+	  A DVB-T tuner module. Say Y when you want to support this frontend.
+
+	  TODO:
+	  This driver needs external firmware. Please use the command
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to
+	  download/extract them, and then copy them to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
+
 config DVB_L64781
 config DVB_L64781
 	tristate "LSI L64781"
 	tristate "LSI L64781"
 	depends on DVB_CORE && I2C
 	depends on DVB_CORE && I2C
@@ -144,9 +156,8 @@ config DVB_L64781
 
 
 config DVB_TDA1004X
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
 	tristate "Philips TDA10045H/TDA10046H based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 
@@ -211,9 +222,8 @@ config DVB_DIB7000P
 
 
 config DVB_TDA10048
 config DVB_TDA10048
 	tristate "Philips TDA10048HN based"
 	tristate "Philips TDA10048HN based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 
@@ -253,9 +263,8 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
 
 
 config DVB_NXT200X
 config DVB_NXT200X
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 	  to support this frontend.
@@ -268,9 +277,8 @@ config DVB_NXT200X
 
 
 config DVB_OR51211
 config DVB_OR51211
 	tristate "Oren OR51211 based"
 	tristate "Oren OR51211 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
 
@@ -281,9 +289,8 @@ config DVB_OR51211
 
 
 config DVB_OR51132
 config DVB_OR51132
 	tristate "Oren OR51132 based"
 	tristate "Oren OR51132 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 	  to support this frontend.
@@ -297,9 +304,8 @@ config DVB_OR51132
 
 
 config DVB_BCM3510
 config DVB_BCM3510
 	tristate "Broadcom BCM3510"
 	tristate "Broadcom BCM3510"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
 	  An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
 	  support this frontend.
 	  support this frontend.

+ 1 - 0
drivers/media/dvb/frontends/Makefile

@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
+obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_TDA10023) += tda10023.o
 obj-$(CONFIG_DVB_TDA10023) += tda10023.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o

+ 1504 - 0
drivers/media/dvb/frontends/drx397xD.c

@@ -0,0 +1,1504 @@
+/*
+ * Driver for Micronas drx397xD demodulator
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DEBUG			/* uncomment if you want debugging output */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/firmware.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drx397xD.h"
+
+static const char mod_name[] = "drx397xD";
+
+#define MAX_CLOCK_DRIFT		200	/* maximal 200 PPM allowed */
+
+#define F_SET_0D0h	1
+#define F_SET_0D4h	2
+
+typedef enum fw_ix {
+#define _FW_ENTRY(a, b)		b
+#include "drx397xD_fw.h"
+} fw_ix_t;
+
+/* chip specifics */
+struct drx397xD_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend frontend;
+	struct drx397xD_config config;
+	fw_ix_t chip_rev;
+	int flags;
+	u32 bandwidth_parm;	/* internal bandwidth conversions */
+	u32 f_osc;		/* w90: actual osc frequency [Hz] */
+};
+
+/*******************************************************************************
+ * Firmware
+ ******************************************************************************/
+
+static const char *blob_name[] = {
+#define _BLOB_ENTRY(a, b)		a
+#include "drx397xD_fw.h"
+};
+
+typedef enum blob_ix {
+#define _BLOB_ENTRY(a, b)		b
+#include "drx397xD_fw.h"
+} blob_ix_t;
+
+static struct {
+	const char *name;
+	const struct firmware *file;
+	rwlock_t lock;
+	int refcnt;
+	const u8 *data[ARRAY_SIZE(blob_name)];
+} fw[] = {
+#define _FW_ENTRY(a, b)		{			\
+			.name	= a,			\
+			.file	= 0,			\
+			.lock	= RW_LOCK_UNLOCKED,	\
+			.refcnt = 0,			\
+			.data	= { }		}
+#include "drx397xD_fw.h"
+};
+
+/* use only with writer lock aquired */
+static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+	if (fw[ix].file)
+		release_firmware(fw[ix].file);
+}
+
+static void drx_release_fw(struct drx397xD_state *s)
+{
+	fw_ix_t ix = s->chip_rev;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	write_lock(&fw[ix].lock);
+	if (fw[ix].refcnt) {
+		fw[ix].refcnt--;
+		if (fw[ix].refcnt == 0)
+			_drx_release_fw(s, ix);
+	}
+	write_unlock(&fw[ix].lock);
+}
+
+static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+	const u8 *data;
+	size_t size, len;
+	int i = 0, j, rc = -EINVAL;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	if (ix < 0 || ix >= ARRAY_SIZE(fw))
+		return -EINVAL;
+	s->chip_rev = ix;
+
+	write_lock(&fw[ix].lock);
+	if (fw[ix].file) {
+		rc = 0;
+		goto exit_ok;
+	}
+	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+
+	if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) {
+		printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
+		       mod_name, fw[ix].name);
+		rc = -ENOENT;
+		goto exit_err;
+	}
+
+	if (!fw[ix].file->data || fw[ix].file->size < 10)
+		goto exit_corrupt;
+
+	data = fw[ix].file->data;
+	size = fw[ix].file->size;
+
+	if (data[i++] != 2)	/* check firmware version */
+		goto exit_corrupt;
+
+	do {
+		switch (data[i++]) {
+		case 0x00:	/* bytecode */
+			if (i >= size)
+				break;
+			i += data[i];
+		case 0x01:	/* reset */
+		case 0x02:	/* sleep */
+			i++;
+			break;
+		case 0xfe:	/* name */
+			len = strnlen(&data[i], size - i);
+			if (i + len + 1 >= size)
+				goto exit_corrupt;
+			if (data[i + len + 1] != 0)
+				goto exit_corrupt;
+			for (j = 0; j < ARRAY_SIZE(blob_name); j++) {
+				if (strcmp(blob_name[j], &data[i]) == 0) {
+					fw[ix].data[j] = &data[i + len + 1];
+					pr_debug("Loading %s\n", blob_name[j]);
+				}
+			}
+			i += len + 1;
+			break;
+		case 0xff:	/* file terminator */
+			if (i == size) {
+				rc = 0;
+				goto exit_ok;
+			}
+		default:
+			goto exit_corrupt;
+		}
+	} while (i < size);
+      exit_corrupt:
+	printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
+      exit_err:
+	_drx_release_fw(s, ix);
+	fw[ix].refcnt--;
+      exit_ok:
+	fw[ix].refcnt++;
+	write_unlock(&fw[ix].lock);
+	return rc;
+}
+
+/*******************************************************************************
+ * i2c bus IO
+ ******************************************************************************/
+
+static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
+{
+	struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 };
+	const u8 *data;
+	int len, rc = 0, i = 0;
+
+	if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
+		pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]);
+
+	read_lock(&fw[s->chip_rev].lock);
+	data = fw[s->chip_rev].data[ix];
+	if (!data) {
+		rc = -EINVAL;
+		goto exit_rc;
+	}
+
+	for (;;) {
+		switch (data[i++]) {
+		case 0:	/* bytecode */
+			len = data[i++];
+			msg.len = len;
+			msg.buf = (__u8 *) &data[i];
+			if (i2c_transfer(s->i2c, &msg, 1) != 1) {
+				rc = -EIO;
+				goto exit_rc;
+			}
+			i += len;
+			break;
+		case 1:	/* reset */
+		case 2:	/* sleep */
+			i++;
+			break;
+		default:
+			goto exit_rc;
+		}
+	}
+      exit_rc:
+	read_unlock(&fw[s->chip_rev].lock);
+	return 0;
+}
+
+/* Function is not endian safe, use the RD16 wrapper below */
+static int _read16(struct drx397xD_state *s, u32 i2c_adr)
+{
+	int rc;
+	u8 a[4];
+	u16 v;
+	struct i2c_msg msg[2] = {
+		{
+		 .addr = s->config.demod_address,
+		 .flags = 0,
+		 .buf = a,
+		 .len = sizeof(a)
+		 }
+		, {
+		   .addr = s->config.demod_address,
+		   .flags = I2C_M_RD,
+		   .buf = (u8 *) & v,
+		   .len = sizeof(v)
+		   }
+	};
+
+	*(u32 *) a = i2c_adr;
+
+	rc = i2c_transfer(s->i2c, msg, 2);
+	if (rc != 2)
+		return -EIO;
+
+	return le16_to_cpu(v);
+}
+
+/* Function is not endian safe, use the WR16.. wrappers below */
+static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val)
+{
+	u8 a[6];
+	int rc;
+	struct i2c_msg msg = {
+		.addr = s->config.demod_address,
+		.flags = 0,
+		.buf = a,
+		.len = sizeof(a)
+	};
+
+	*(u32 *) a = i2c_adr;
+	*(u16 *) & a[4] = val;
+
+	rc = i2c_transfer(s->i2c, &msg, 1);
+	if (rc != 1)
+		return -EIO;
+	return 0;
+}
+
+#define WR16(ss,adr, val) \
+		_write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
+#define WR16_E0(ss,adr, val) \
+		_write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
+#define RD16(ss,adr) \
+		_read16(ss, I2C_ADR_C0(adr))
+
+#define EXIT_RC( cmd )	if ( (rc = (cmd)) < 0) goto exit_rc
+
+/*******************************************************************************
+ * Tuner callback
+ ******************************************************************************/
+
+static int PLL_Set(struct drx397xD_state *s,
+		   struct dvb_frontend_parameters *fep, int *df_tuner)
+{
+	struct dvb_frontend *fe = &s->frontend;
+	u32 f_tuner, f = fep->frequency;
+	int rc;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
+	    (f < s->frontend.ops.tuner_ops.info.frequency_min))
+		return -EINVAL;
+
+	*df_tuner = 0;
+	if (!s->frontend.ops.tuner_ops.set_params ||
+	    !s->frontend.ops.tuner_ops.get_frequency)
+		return -ENOSYS;
+
+	rc = s->frontend.ops.tuner_ops.set_params(fe, fep);
+	if (rc < 0)
+		return rc;
+
+	rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner);
+	if (rc < 0)
+		return rc;
+
+	*df_tuner = f_tuner - f;
+	pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f,
+		 f_tuner);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Demodulator helper functions
+ ******************************************************************************/
+
+static int SC_WaitForReady(struct drx397xD_state *s)
+{
+	int cnt = 1000;
+	int rc;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	while (cnt--) {
+		rc = RD16(s, 0x820043);
+		if (rc == 0)
+			return 0;
+	}
+	return -1;
+}
+
+static int SC_SendCommand(struct drx397xD_state *s, int cmd)
+{
+	int rc;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	WR16(s, 0x820043, cmd);
+	SC_WaitForReady(s);
+	rc = RD16(s, 0x820042);
+	if ((rc & 0xffff) == 0xffff)
+		return -1;
+	return 0;
+}
+
+static int HI_Command(struct drx397xD_state *s, u16 cmd)
+{
+	int rc, cnt = 1000;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	rc = WR16(s, 0x420032, cmd);
+	if (rc < 0)
+		return rc;
+
+	do {
+		rc = RD16(s, 0x420032);
+		if (rc == 0) {
+			rc = RD16(s, 0x420031);
+			return rc;
+		}
+		if (rc < 0)
+			return rc;
+	} while (--cnt);
+	return rc;
+}
+
+static int HI_CfgCommand(struct drx397xD_state *s)
+{
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	WR16(s, 0x420033, 0x3973);
+	WR16(s, 0x420034, s->config.w50);	// code 4, log 4
+	WR16(s, 0x420035, s->config.w52);	// code 15,  log 9
+	WR16(s, 0x420036, s->config.demod_address << 1);
+	WR16(s, 0x420037, s->config.w56);	// code (set_i2c ??  initX 1 ), log 1
+//      WR16(s, 0x420033, 0x3973);
+	if ((s->config.w56 & 8) == 0)
+		return HI_Command(s, 3);
+	return WR16(s, 0x420032, 0x3);
+}
+
+static const u8 fastIncrDecLUT_15273[] = {
+	0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14,
+	0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f
+};
+
+static const u8 slowIncrDecLUT_15272[] = {
+	3, 4, 4, 5, 6
+};
+
+static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
+{
+	u16 w06 = agc->w06;
+	u16 w08 = agc->w08;
+	u16 w0A = agc->w0A;
+	u16 w0C = agc->w0C;
+	int quot, rem, i, rc = -EINVAL;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	if (agc->w04 > 0x3ff)
+		goto exit_rc;
+
+	if (agc->d00 == 1) {
+		EXIT_RC(RD16(s, 0x0c20010));
+		rc &= ~0x10;
+		EXIT_RC(WR16(s, 0x0c20010, rc));
+		return WR16(s, 0x0c20030, agc->w04 & 0x7ff);
+	}
+
+	if (agc->d00 != 0)
+		goto exit_rc;
+	if (w0A < w08)
+		goto exit_rc;
+	if (w0A > 0x3ff)
+		goto exit_rc;
+	if (w0C > 0x3ff)
+		goto exit_rc;
+	if (w06 > 0x3ff)
+		goto exit_rc;
+
+	EXIT_RC(RD16(s, 0x0c20010));
+	rc |= 0x10;
+	EXIT_RC(WR16(s, 0x0c20010, rc));
+
+	EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff));
+	EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1));
+	EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff));
+
+	quot = w0C / 113;
+	rem = w0C % 113;
+	if (quot <= 8) {
+		quot = 8 - quot;
+	} else {
+		quot = 0;
+		rem += 113;
+	}
+
+	EXIT_RC(WR16(s, 0x0c20024, quot));
+
+	i = fastIncrDecLUT_15273[rem / 8];
+	EXIT_RC(WR16(s, 0x0c2002d, i));
+	EXIT_RC(WR16(s, 0x0c2002e, i));
+
+	i = slowIncrDecLUT_15272[rem / 28];
+	EXIT_RC(WR16(s, 0x0c2002b, i));
+	rc = WR16(s, 0x0c2002c, i);
+      exit_rc:
+	return rc;
+}
+
+static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
+{
+	u16 w04 = agc->w04;
+	u16 w06 = agc->w06;
+	int rc = -1;
+
+	pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06);
+
+	if (w04 > 0x3ff)
+		goto exit_rc;
+
+	switch (agc->d00) {
+	case 1:
+		if (w04 == 0x3ff)
+			w04 = 0x400;
+
+		EXIT_RC(WR16(s, 0x0c20036, w04));
+		s->config.w9C &= ~2;
+		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+		EXIT_RC(RD16(s, 0x0c20010));
+		rc &= 0xbfdf;
+		EXIT_RC(WR16(s, 0x0c20010, rc));
+		EXIT_RC(RD16(s, 0x0c20013));
+		rc &= ~2;
+		break;
+	case 0:
+		// loc_8000659
+		s->config.w9C &= ~2;
+		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+		EXIT_RC(RD16(s, 0x0c20010));
+		rc &= 0xbfdf;
+		rc |= 0x4000;
+		EXIT_RC(WR16(s, 0x0c20010, rc));
+		EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f));
+		EXIT_RC(RD16(s, 0x0c20013));
+		rc &= ~2;
+		break;
+	default:
+		s->config.w9C |= 2;
+		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+		EXIT_RC(RD16(s, 0x0c20010));
+		rc &= 0xbfdf;
+		EXIT_RC(WR16(s, 0x0c20010, rc));
+
+		EXIT_RC(WR16(s, 0x0c20036, 0));
+
+		EXIT_RC(RD16(s, 0x0c20013));
+		rc |= 2;
+	}
+	rc = WR16(s, 0x0c20013, rc);
+      exit_rc:
+	return rc;
+}
+
+static int GetLockStatus(struct drx397xD_state *s, int *lockstat)
+{
+	int rc;
+
+	*lockstat = 0;
+
+	rc = RD16(s, 0x082004b);
+	if (rc < 0)
+		return rc;
+
+	if (s->config.d60 != 2)
+		return 0;
+
+	if ((rc & 7) == 7)
+		*lockstat |= 1;
+	if ((rc & 3) == 3)
+		*lockstat |= 2;
+	if (rc & 1)
+		*lockstat |= 4;
+	return 0;
+}
+
+static int CorrectSysClockDeviation(struct drx397xD_state *s)
+{
+	int rc = -EINVAL;
+	int lockstat;
+	u32 clk, clk_limit;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	if (s->config.d5C == 0) {
+		EXIT_RC(WR16(s, 0x08200e8, 0x010));
+		EXIT_RC(WR16(s, 0x08200e9, 0x113));
+		s->config.d5C = 1;
+		return rc;
+	}
+	if (s->config.d5C != 1)
+		goto exit_rc;
+
+	rc = RD16(s, 0x0820048);
+
+	rc = GetLockStatus(s, &lockstat);
+	if (rc < 0)
+		goto exit_rc;
+	if ((lockstat & 1) == 0)
+		goto exit_rc;
+
+	EXIT_RC(WR16(s, 0x0420033, 0x200));
+	EXIT_RC(WR16(s, 0x0420034, 0xc5));
+	EXIT_RC(WR16(s, 0x0420035, 0x10));
+	EXIT_RC(WR16(s, 0x0420036, 0x1));
+	EXIT_RC(WR16(s, 0x0420037, 0xa));
+	EXIT_RC(HI_Command(s, 6));
+	EXIT_RC(RD16(s, 0x0420040));
+	clk = rc;
+	EXIT_RC(RD16(s, 0x0420041));
+	clk |= rc << 16;
+
+	if (clk <= 0x26ffff)
+		goto exit_rc;
+	if (clk > 0x610000)
+		goto exit_rc;
+
+	if (!s->bandwidth_parm)
+		return -EINVAL;
+
+	/* round & convert to Hz */
+	clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21;
+	clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000;
+
+	if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
+		s->f_osc = clk;
+		pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__,
+			 s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
+	}
+	rc = WR16(s, 0x08200e8, 0);
+      exit_rc:
+	return rc;
+}
+
+static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
+{
+	int rc, si, bp;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	si = s->config.wA0;
+	if (s->config.w98 == 0) {
+		si |= 1;
+		bp = 0;
+	} else {
+		si &= ~1;
+		bp = 0x200;
+	}
+	if (s->config.w9A == 0) {
+		si |= 0x80;
+	} else {
+		si &= ~0x80;
+	}
+
+	EXIT_RC(WR16(s, 0x2150045, 0));
+	EXIT_RC(WR16(s, 0x2150010, si));
+	EXIT_RC(WR16(s, 0x2150011, bp));
+	rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
+      exit_rc:
+	return rc;
+}
+
+static int drx_tune(struct drx397xD_state *s,
+		    struct dvb_frontend_parameters *fep)
+{
+	u16 v22 = 0;
+	u16 v1C = 0;
+	u16 v1A = 0;
+	u16 v18 = 0;
+	u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
+	u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
+
+	int rc, df_tuner;
+	int a, b, c, d;
+	pr_debug("%s %d\n", __FUNCTION__, s->config.d60);
+
+	if (s->config.d60 != 2)
+		goto set_tuner;
+	rc = CorrectSysClockDeviation(s);
+	if (rc < 0)
+		goto set_tuner;
+
+	s->config.d60 = 1;
+	rc = ConfigureMPEGOutput(s, 0);
+	if (rc < 0)
+		goto set_tuner;
+      set_tuner:
+
+	rc = PLL_Set(s, fep, &df_tuner);
+	if (rc < 0) {
+		printk(KERN_ERR "Error in pll_set\n");
+		goto exit_rc;
+	}
+	msleep(200);
+
+	a = rc = RD16(s, 0x2150016);
+	if (rc < 0)
+		goto exit_rc;
+	b = rc = RD16(s, 0x2150010);
+	if (rc < 0)
+		goto exit_rc;
+	c = rc = RD16(s, 0x2150034);
+	if (rc < 0)
+		goto exit_rc;
+	d = rc = RD16(s, 0x2150035);
+	if (rc < 0)
+		goto exit_rc;
+	rc = WR16(s, 0x2150014, c);
+	rc = WR16(s, 0x2150015, d);
+	rc = WR16(s, 0x2150010, 0);
+	rc = WR16(s, 0x2150000, 2);
+	rc = WR16(s, 0x2150036, 0x0fff);
+	rc = WR16(s, 0x2150016, a);
+
+	rc = WR16(s, 0x2150010, 2);
+	rc = WR16(s, 0x2150007, 0);
+	rc = WR16(s, 0x2150000, 1);
+	rc = WR16(s, 0x2110000, 0);
+	rc = WR16(s, 0x0800000, 0);
+	rc = WR16(s, 0x2800000, 0);
+	rc = WR16(s, 0x2110010, 0x664);
+
+	rc = write_fw(s, DRXD_ResetECRAM);
+	rc = WR16(s, 0x2110000, 1);
+
+	rc = write_fw(s, DRXD_InitSC);
+	if (rc < 0)
+		goto exit_rc;
+
+	rc = SetCfgIfAgc(s, &s->config.ifagc);
+	if (rc < 0)
+		goto exit_rc;
+
+	rc = SetCfgRfAgc(s, &s->config.rfagc);
+	if (rc < 0)
+		goto exit_rc;
+
+	if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K)
+		v22 = 1;
+	switch (fep->u.ofdm.transmission_mode) {
+	case TRANSMISSION_MODE_8K:
+		edi = 1;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+
+		rc = WR16(s, 0x2010010, 0);
+		if (rc < 0)
+			break;
+		v1C = 0x63;
+		v1A = 0x53;
+		v18 = 0x43;
+		break;
+	default:
+		edi = 0;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+
+		rc = WR16(s, 0x2010010, 1);
+		if (rc < 0)
+			break;
+
+		v1C = 0x61;
+		v1A = 0x47;
+		v18 = 0x41;
+	}
+
+	switch (fep->u.ofdm.guard_interval) {
+	case GUARD_INTERVAL_1_4:
+		edi |= 0x0c;
+		break;
+	case GUARD_INTERVAL_1_8:
+		edi |= 0x08;
+		break;
+	case GUARD_INTERVAL_1_16:
+		edi |= 0x04;
+		break;
+	case GUARD_INTERVAL_1_32:
+		break;
+	default:
+		v22 |= 2;
+	}
+
+	ebx = 0;
+	ebp = 0;
+	v20 = 0;
+	v1E = 0;
+	v16 = 0;
+	v14 = 0;
+	v12 = 0;
+	v10 = 0;
+	v0E = 0;
+
+	switch (fep->u.ofdm.hierarchy_information) {
+	case HIERARCHY_1:
+		edi |= 0x40;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x1c10047, 1);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010012, 1);
+		if (rc < 0)
+			goto exit_rc;
+		ebx = 0x19f;
+		ebp = 0x1fb;
+		v20 = 0x0c0;
+		v1E = 0x195;
+		v16 = 0x1d6;
+		v14 = 0x1ef;
+		v12 = 4;
+		v10 = 5;
+		v0E = 5;
+		break;
+	case HIERARCHY_2:
+		edi |= 0x80;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x1c10047, 2);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010012, 2);
+		if (rc < 0)
+			goto exit_rc;
+		ebx = 0x08f;
+		ebp = 0x12f;
+		v20 = 0x0c0;
+		v1E = 0x11e;
+		v16 = 0x1d6;
+		v14 = 0x15e;
+		v12 = 4;
+		v10 = 5;
+		v0E = 5;
+		break;
+	case HIERARCHY_4:
+		edi |= 0xc0;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x1c10047, 3);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010012, 3);
+		if (rc < 0)
+			goto exit_rc;
+		ebx = 0x14d;
+		ebp = 0x197;
+		v20 = 0x0c0;
+		v1E = 0x1ce;
+		v16 = 0x1d6;
+		v14 = 0x11a;
+		v12 = 4;
+		v10 = 6;
+		v0E = 5;
+		break;
+	default:
+		v22 |= 8;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x1c10047, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010012, 0);
+		if (rc < 0)
+			goto exit_rc;
+		//              QPSK    QAM16   QAM64
+		ebx = 0x19f;	//                 62
+		ebp = 0x1fb;	//                 15
+		v20 = 0x16a;	//  62
+		v1E = 0x195;	//         62
+		v16 = 0x1bb;	//  15
+		v14 = 0x1ef;	//         15
+		v12 = 5;	//  16
+		v10 = 5;	//         16
+		v0E = 5;	//                 16
+	}
+
+	switch (fep->u.ofdm.constellation) {
+	default:
+		v22 |= 4;
+	case QPSK:
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+
+		rc = WR16(s, 0x1c10046, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010011, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001a, 0x10);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001b, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001c, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10062, v20);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c1002a, v1C);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10015, v16);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10016, v12);
+		if (rc < 0)
+			goto exit_rc;
+		break;
+	case QAM_16:
+		edi |= 0x10;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+
+		rc = WR16(s, 0x1c10046, 1);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010011, 1);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001a, 0x10);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001b, 4);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001c, 0);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10062, v1E);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c1002a, v1A);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10015, v14);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10016, v10);
+		if (rc < 0)
+			goto exit_rc;
+		break;
+	case QAM_64:
+		edi |= 0x20;
+		rc = WR16(s, 0x1c10046, 2);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x2010011, 2);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001a, 0x20);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001b, 8);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x201001c, 2);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10062, ebx);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c1002a, v18);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10015, ebp);
+		if (rc < 0)
+			goto exit_rc;
+		rc = WR16(s, 0x1c10016, v0E);
+		if (rc < 0)
+			goto exit_rc;
+		break;
+	}
+
+	if (s->config.s20d24 == 1) {
+		rc = WR16(s, 0x2010013, 0);
+	} else {
+		rc = WR16(s, 0x2010013, 1);
+		edi |= 0x1000;
+	}
+
+	switch (fep->u.ofdm.code_rate_HP) {
+	default:
+		v22 |= 0x10;
+	case FEC_1_2:
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x2090011, 0);
+		break;
+	case FEC_2_3:
+		edi |= 0x200;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x2090011, 1);
+		break;
+	case FEC_3_4:
+		edi |= 0x400;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x2090011, 2);
+		break;
+	case FEC_5_6:		/* 5 */
+		edi |= 0x600;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x2090011, 3);
+		break;
+	case FEC_7_8:		/* 7 */
+		edi |= 0x800;
+		if (s->chip_rev == DRXD_FW_B1)
+			break;
+		rc = WR16(s, 0x2090011, 4);
+		break;
+	};
+	if (rc < 0)
+		goto exit_rc;
+
+	switch (fep->u.ofdm.bandwidth) {
+	default:
+		rc = -EINVAL;
+		goto exit_rc;
+	case BANDWIDTH_8_MHZ:	/* 0 */
+	case BANDWIDTH_AUTO:
+		rc = WR16(s, 0x0c2003f, 0x32);
+		s->bandwidth_parm = ebx = 0x8b8249;	// 9142857
+		edx = 0;
+		break;
+	case BANDWIDTH_7_MHZ:
+		rc = WR16(s, 0x0c2003f, 0x3b);
+		s->bandwidth_parm = ebx = 0x7a1200;	// 8000000
+		edx = 0x4807;
+		break;
+	case BANDWIDTH_6_MHZ:
+		rc = WR16(s, 0x0c2003f, 0x47);
+		s->bandwidth_parm = ebx = 0x68a1b6;	// 6857142
+		edx = 0x0f07;
+		break;
+	};
+
+	if (rc < 0)
+		goto exit_rc;
+
+	rc = WR16(s, 0x08200ec, edx);
+	if (rc < 0)
+		goto exit_rc;
+
+	rc = RD16(s, 0x0820050);
+	if (rc < 0)
+		goto exit_rc;
+	rc = WR16(s, 0x0820050, rc);
+
+	{
+		/* Configure bandwidth specific factor */
+		ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1),
+				     (u64)ebx) - 0x800000;
+		EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff));
+		EXIT_RC(WR16(s, 0x0c50011, ebx >> 16));
+
+		/* drx397xD oscillator calibration */
+		ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) +
+				     (s->f_osc >> 1), (u64)s->f_osc);
+	}
+	ebx &= 0xfffffff;
+	if (fep->inversion == INVERSION_ON)
+		ebx = 0x10000000 - ebx;
+
+	EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff));
+	EXIT_RC(WR16(s, 0x0c30011, ebx >> 16));
+
+	EXIT_RC(WR16(s, 0x0800000, 1));
+	EXIT_RC(RD16(s, 0x0800000));
+
+
+	EXIT_RC(SC_WaitForReady(s));
+	EXIT_RC(WR16(s, 0x0820042, 0));
+	EXIT_RC(WR16(s, 0x0820041, v22));
+	EXIT_RC(WR16(s, 0x0820040, edi));
+	EXIT_RC(SC_SendCommand(s, 3));
+
+	rc = RD16(s, 0x0800000);
+
+	SC_WaitForReady(s);
+	WR16(s, 0x0820042, 0);
+	WR16(s, 0x0820041, 1);
+	WR16(s, 0x0820040, 1);
+	SC_SendCommand(s, 1);
+
+//      rc = WR16(s, 0x2150000, 1);
+//      if (rc < 0) goto exit_rc;
+
+	rc = WR16(s, 0x2150000, 2);
+	rc = WR16(s, 0x2150016, a);
+	rc = WR16(s, 0x2150010, 4);
+	rc = WR16(s, 0x2150036, 0);
+	rc = WR16(s, 0x2150000, 1);
+	s->config.d60 = 2;
+      exit_rc:
+	return rc;
+}
+
+/*******************************************************************************
+ * DVB interface
+ ******************************************************************************/
+
+static int drx397x_init(struct dvb_frontend *fe)
+{
+	struct drx397xD_state *s = fe->demodulator_priv;
+	int rc;
+
+	pr_debug("%s\n", __FUNCTION__);
+
+	s->config.rfagc.d00 = 2;	/* 0x7c */
+	s->config.rfagc.w04 = 0;
+	s->config.rfagc.w06 = 0x3ff;
+
+	s->config.ifagc.d00 = 0;	/* 0x68 */
+	s->config.ifagc.w04 = 0;
+	s->config.ifagc.w06 = 140;
+	s->config.ifagc.w08 = 0;
+	s->config.ifagc.w0A = 0x3ff;
+	s->config.ifagc.w0C = 0x388;
+
+	/* for signal strenght calculations */
+	s->config.ss76 = 820;
+	s->config.ss78 = 2200;
+	s->config.ss7A = 150;
+
+	/* HI_CfgCommand */
+	s->config.w50 = 4;
+	s->config.w52 = 9;	// 0xf;
+
+	s->config.f_if = 42800000;	/* d14: intermediate frequency [Hz]     */
+	s->config.f_osc = 48000;	/* s66 : oscillator frequency [kHz]     */
+	s->config.w92 = 12000;	// 20000;
+
+	s->config.w9C = 0x000e;
+	s->config.w9E = 0x0000;
+
+	/* ConfigureMPEGOutput params */
+	s->config.wA0 = 4;
+	s->config.w98 = 1;	// 0;
+	s->config.w9A = 1;
+
+	/* get chip revision */
+	rc = RD16(s, 0x2410019);
+	if (rc < 0)
+		return -ENODEV;
+
+	if (rc == 0) {
+		printk(KERN_INFO "%s: chip revision A2\n", mod_name);
+		rc = drx_load_fw(s, DRXD_FW_A2);
+	} else {
+
+		rc = (rc >> 12) - 3;
+		switch (rc) {
+		case 1:
+			s->flags |= F_SET_0D4h;
+		case 0:
+		case 4:
+			s->flags |= F_SET_0D0h;
+			break;
+		case 2:
+		case 5:
+			break;
+		case 3:
+			s->flags |= F_SET_0D4h;
+			break;
+		default:
+			return -ENODEV;
+		};
+		printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc);
+		rc = drx_load_fw(s, DRXD_FW_B1);
+	}
+	if (rc < 0)
+		goto error;
+
+	rc = WR16(s, 0x0420033, 0x3973);
+	if (rc < 0)
+		goto error;
+
+	rc = HI_Command(s, 2);
+
+	msleep(1);
+
+	if (s->chip_rev == DRXD_FW_A2) {
+		rc = WR16(s, 0x043012d, 0x47F);
+		if (rc < 0)
+			goto error;
+	}
+	rc = WR16_E0(s, 0x0400000, 0);
+	if (rc < 0)
+		goto error;
+
+	if (s->config.w92 > 20000 || s->config.w92 % 4000) {
+		printk(KERN_ERR "%s: invalid osc frequency\n", mod_name);
+		rc = -1;
+		goto error;
+	}
+
+	rc = WR16(s, 0x2410010, 1);
+	if (rc < 0)
+		goto error;
+	rc = WR16(s, 0x2410011, 0x15);
+	if (rc < 0)
+		goto error;
+	rc = WR16(s, 0x2410012, s->config.w92 / 4000);
+	if (rc < 0)
+		goto error;
+#ifdef ORIG_FW
+	rc = WR16(s, 0x2410015, 2);
+	if (rc < 0)
+		goto error;
+#endif
+	rc = WR16(s, 0x2410017, 0x3973);
+	if (rc < 0)
+		goto error;
+
+	s->f_osc = s->config.f_osc * 1000;	/* initial estimator */
+
+	s->config.w56 = 1;
+
+	rc = HI_CfgCommand(s);
+	if (rc < 0)
+		goto error;
+
+	rc = write_fw(s, DRXD_InitAtomicRead);
+	if (rc < 0)
+		goto error;
+
+	if (s->chip_rev == DRXD_FW_A2) {
+		rc = WR16(s, 0x2150013, 0);
+		if (rc < 0)
+			goto error;
+	}
+
+	rc = WR16_E0(s, 0x0400002, 0);
+	if (rc < 0)
+		goto error;
+	rc = WR16(s, 0x0400002, 0);
+	if (rc < 0)
+		goto error;
+
+	if (s->chip_rev == DRXD_FW_A2) {
+		rc = write_fw(s, DRXD_ResetCEFR);
+		if (rc < 0)
+			goto error;
+	}
+	rc = write_fw(s, DRXD_microcode);
+	if (rc < 0)
+		goto error;
+
+	s->config.w9C = 0x0e;
+	if (s->flags & F_SET_0D0h) {
+		s->config.w9C = 0;
+		rc = RD16(s, 0x0c20010);
+		if (rc < 0)
+			goto write_DRXD_InitFE_1;
+
+		rc &= ~0x1000;
+		rc = WR16(s, 0x0c20010, rc);
+		if (rc < 0)
+			goto write_DRXD_InitFE_1;
+
+		rc = RD16(s, 0x0c20011);
+		if (rc < 0)
+			goto write_DRXD_InitFE_1;
+
+		rc &= ~0x8;
+		rc = WR16(s, 0x0c20011, rc);
+		if (rc < 0)
+			goto write_DRXD_InitFE_1;
+
+		rc = WR16(s, 0x0c20012, 1);
+	}
+
+      write_DRXD_InitFE_1:
+
+	rc = write_fw(s, DRXD_InitFE_1);
+	if (rc < 0)
+		goto error;
+
+	rc = 1;
+	if (s->chip_rev == DRXD_FW_B1) {
+		if (s->flags & F_SET_0D0h)
+			rc = 0;
+	} else {
+		if (s->flags & F_SET_0D0h)
+			rc = 4;
+	}
+
+	rc = WR16(s, 0x0C20012, rc);
+	if (rc < 0)
+		goto error;
+
+	rc = WR16(s, 0x0C20013, s->config.w9E);
+	if (rc < 0)
+		goto error;
+	rc = WR16(s, 0x0C20015, s->config.w9C);
+	if (rc < 0)
+		goto error;
+
+	rc = write_fw(s, DRXD_InitFE_2);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitFT);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitCP);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitCE);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitEQ);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitEC);
+	if (rc < 0)
+		goto error;
+	rc = write_fw(s, DRXD_InitSC);
+	if (rc < 0)
+		goto error;
+
+	rc = SetCfgIfAgc(s, &s->config.ifagc);
+	if (rc < 0)
+		goto error;
+
+	rc = SetCfgRfAgc(s, &s->config.rfagc);
+	if (rc < 0)
+		goto error;
+
+	rc = ConfigureMPEGOutput(s, 1);
+	rc = WR16(s, 0x08201fe, 0x0017);
+	rc = WR16(s, 0x08201ff, 0x0101);
+
+	s->config.d5C = 0;
+	s->config.d60 = 1;
+	s->config.d48 = 1;
+      error:
+	return rc;
+}
+
+static int drx397x_get_frontend(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *params)
+{
+	return 0;
+}
+
+static int drx397x_set_frontend(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *params)
+{
+	struct drx397xD_state *s = fe->demodulator_priv;
+
+	s->config.s20d24 = 1;	// 0;
+	return drx_tune(s, params);
+}
+
+static int drx397x_get_tune_settings(struct dvb_frontend *fe,
+				     struct dvb_frontend_tune_settings
+				     *fe_tune_settings)
+{
+	fe_tune_settings->min_delay_ms = 10000;
+	fe_tune_settings->step_size = 0;
+	fe_tune_settings->max_drift = 0;
+	return 0;
+}
+
+static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+	struct drx397xD_state *s = fe->demodulator_priv;
+	int lockstat;
+
+	GetLockStatus(s, &lockstat);
+	/* TODO */
+//      if (lockstat & 1)
+//      CorrectSysClockDeviation(s);
+
+	*status = 0;
+	if (lockstat & 2) {
+		CorrectSysClockDeviation(s);
+		ConfigureMPEGOutput(s, 1);
+		*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+	}
+	if (lockstat & 4) {
+		*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+	}
+
+	return 0;
+}
+
+static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
+{
+	*ber = 0;
+	return 0;
+}
+
+static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+	*snr = 0;
+	return 0;
+}
+
+static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+	struct drx397xD_state *s = fe->demodulator_priv;
+	int rc;
+
+	if (s->config.ifagc.d00 == 2) {
+		*strength = 0xffff;
+		return 0;
+	}
+	rc = RD16(s, 0x0c20035);
+	if (rc < 0) {
+		*strength = 0;
+		return 0;
+	}
+	rc &= 0x3ff;
+	/* Signal strength is calculated using the following formula:
+	 *
+	 * a = 2200 * 150 / (2200 + 150);
+	 * a = a * 3300 /  (a + 820);
+	 * b = 2200 * 3300 / (2200 + 820);
+	 * c = (((b-a) * rc) >> 10  + a) << 4;
+	 * strength = ~c & 0xffff;
+	 *
+	 * The following does the same but with less rounding errors:
+	 */
+	*strength = ~(7720 + (rc * 30744 >> 10));
+	return 0;
+}
+
+static int drx397x_read_ucblocks(struct dvb_frontend *fe,
+				 unsigned int *ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+static int drx397x_sleep(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static void drx397x_release(struct dvb_frontend *fe)
+{
+	struct drx397xD_state *s = fe->demodulator_priv;
+	printk(KERN_INFO "%s: release demodulator\n", mod_name);
+	if (s) {
+		drx_release_fw(s);
+		kfree(s);
+	}
+
+}
+
+static struct dvb_frontend_ops drx397x_ops = {
+
+	.info = {
+		 .name			= "Micronas DRX397xD DVB-T Frontend",
+		 .type			= FE_OFDM,
+		 .frequency_min		= 47125000,
+		 .frequency_max		= 855250000,
+		 .frequency_stepsize	= 166667,
+		 .frequency_tolerance	= 0,
+		 .caps =					/* 0x0C01B2EAE */
+			 FE_CAN_FEC_1_2			|	// = 0x2,
+			 FE_CAN_FEC_2_3			|	// = 0x4,
+			 FE_CAN_FEC_3_4			|	// = 0x8,
+			 FE_CAN_FEC_5_6			|	// = 0x20,
+			 FE_CAN_FEC_7_8			|	// = 0x80,
+			 FE_CAN_FEC_AUTO		|	// = 0x200,
+			 FE_CAN_QPSK			|	// = 0x400,
+			 FE_CAN_QAM_16			|	// = 0x800,
+			 FE_CAN_QAM_64			|	// = 0x2000,
+			 FE_CAN_QAM_AUTO		|	// = 0x10000,
+			 FE_CAN_TRANSMISSION_MODE_AUTO	|	// = 0x20000,
+			 FE_CAN_GUARD_INTERVAL_AUTO	|	// = 0x80000,
+			 FE_CAN_HIERARCHY_AUTO		|	// = 0x100000,
+			 FE_CAN_RECOVER			|	// = 0x40000000,
+			 FE_CAN_MUTE_TS				// = 0x80000000
+	 },
+
+	.release = drx397x_release,
+	.init = drx397x_init,
+	.sleep = drx397x_sleep,
+
+	.set_frontend = drx397x_set_frontend,
+	.get_tune_settings = drx397x_get_tune_settings,
+	.get_frontend = drx397x_get_frontend,
+
+	.read_status = drx397x_read_status,
+	.read_snr = drx397x_read_snr,
+	.read_signal_strength = drx397x_read_signal_strength,
+	.read_ber = drx397x_read_ber,
+	.read_ucblocks = drx397x_read_ucblocks,
+};
+
+struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
+				     struct i2c_adapter *i2c)
+{
+	struct drx397xD_state *s = NULL;
+
+	/* allocate memory for the internal state */
+	s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
+	if (s == NULL)
+		goto error;
+
+	/* setup the state */
+	s->i2c = i2c;
+	memcpy(&s->config, config, sizeof(struct drx397xD_config));
+
+	/* check if the demod is there */
+	if (RD16(s, 0x2410019) < 0)
+		goto error;
+
+	/* create dvb_frontend */
+	memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops));
+	s->frontend.demodulator_priv = s;
+
+	return &s->frontend;
+      error:
+	kfree(s);
+	return NULL;
+}
+
+MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(drx397xD_attach);

+ 130 - 0
drivers/media/dvb/frontends/drx397xD.h

@@ -0,0 +1,130 @@
+/*
+ *  Driver for Micronas DVB-T drx397xD demodulator
+ *
+ *  Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef _DRX397XD_H_INCLUDED
+#define _DRX397XD_H_INCLUDED
+
+#include <linux/dvb/frontend.h>
+
+#define DRX_F_STEPSIZE	166667
+#define DRX_F_OFFSET	36000000
+
+#define I2C_ADR_C0(x) \
+(	(u32)cpu_to_le32( \
+		(u32)( \
+			(((u32)(x) & (u32)0x000000ffUL)      ) | \
+			(((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+			(((u32)(x) & (u32)0x0fff0000UL) >>  8) | \
+			 (	     (u32)0x00c00000UL)          \
+		      )) \
+)
+
+#define I2C_ADR_E0(x) \
+(	(u32)cpu_to_le32( \
+		(u32)( \
+			(((u32)(x) & (u32)0x000000ffUL)      ) | \
+			(((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+			(((u32)(x) & (u32)0x0fff0000UL) >>  8) | \
+			 (	     (u32)0x00e00000UL)          \
+		      )) \
+)
+
+struct drx397xD_CfgRfAgc	/* 0x7c */
+{
+	int d00;	/* 2 */
+	u16 w04;
+	u16 w06;
+};
+
+struct drx397xD_CfgIfAgc	/* 0x68 */
+{
+	int d00;	/* 0 */
+	u16 w04;	/* 0 */
+	u16 w06;
+	u16 w08;
+	u16 w0A;
+	u16 w0C;
+};
+
+struct drx397xD_s20 {
+	int d04;
+	u32 d18;
+	u32 d1C;
+	u32 d20;
+	u32 d14;
+	u32 d24;
+	u32 d0C;
+	u32 d08;
+};
+
+struct drx397xD_config
+{
+	/* demodulator's I2C address */
+	u8	demod_address;		/* 0x0f */
+
+	struct drx397xD_CfgIfAgc  ifagc;  /* 0x68 */
+	struct drx397xD_CfgRfAgc  rfagc;  /* 0x7c */
+	u32	s20d24;
+
+	/* HI_CfgCommand parameters */
+	u16	w50, w52, /* w54, */ w56;
+
+	int	d5C;
+	int	d60;
+	int	d48;
+	int	d28;
+
+	u32	f_if;	/* d14: intermediate frequency [Hz]		*/
+			/*	36000000 on Cinergy 2400i DT		*/
+			/*	42800000 on Pinnacle Hybrid PRO 330e	*/
+
+	u16	f_osc;	/* s66: 48000 oscillator frequency [kHz]	*/
+
+	u16	w92;	/* 20000 */
+
+	u16	wA0;
+	u16	w98;
+	u16	w9A;
+
+	u16	w9C;	/* 0xe0 */
+	u16	w9E;	/* 0x00 */
+
+	/* used for signal strength calculations in
+	   drx397x_read_signal_strength
+	*/
+	u16	ss78;	// 2200
+	u16	ss7A;	// 150
+	u16	ss76;	// 820
+};
+
+#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE))
+extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+					   struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+					   struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_DRX397XD */
+
+#endif /* _DRX397XD_H_INCLUDED */

+ 40 - 0
drivers/media/dvb/frontends/drx397xD_fw.h

@@ -0,0 +1,40 @@
+/*
+ * Firmware definitions for Micronas drx397xD
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef _FW_ENTRY
+	_FW_ENTRY("drx397xD.A2.fw",	DRXD_FW_A2 = 0		),
+	_FW_ENTRY("drx397xD.B1.fw",	DRXD_FW_B1		),
+#undef _FW_ENTRY
+#endif /* _FW_ENTRY */
+
+#ifdef _BLOB_ENTRY
+	_BLOB_ENTRY("InitAtomicRead",	DRXD_InitAtomicRead = 0	),
+	_BLOB_ENTRY("InitCE",		DRXD_InitCE		),
+	_BLOB_ENTRY("InitCP",		DRXD_InitCP		),
+	_BLOB_ENTRY("InitEC",		DRXD_InitEC		),
+	_BLOB_ENTRY("InitEQ",		DRXD_InitEQ		),
+	_BLOB_ENTRY("InitFE_1",		DRXD_InitFE_1		),
+	_BLOB_ENTRY("InitFE_2",		DRXD_InitFE_2		),
+	_BLOB_ENTRY("InitFT",		DRXD_InitFT		),
+	_BLOB_ENTRY("InitSC",		DRXD_InitSC		),
+	_BLOB_ENTRY("ResetCEFR",	DRXD_ResetCEFR		),
+	_BLOB_ENTRY("ResetECRAM",	DRXD_ResetECRAM		),
+	_BLOB_ENTRY("microcode",	DRXD_microcode		),
+#undef _BLOB_ENTRY
+#endif /* _BLOB_ENTRY */

+ 97 - 0
drivers/media/dvb/frontends/z0194a.h

@@ -0,0 +1,97 @@
+/* z0194a.h Sharp z0194a tuner support
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+*	This program is free software; you can redistribute it and/or modify it
+*	under the terms of the GNU General Public License as published by the
+*	Free Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#ifndef Z0194A
+#define Z0194A
+
+static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
+					 u32 srate, u32 ratio)
+{
+	u8 aclk = 0;
+	u8 bclk = 0;
+
+	if (srate < 1500000) {
+		aclk = 0xb7; bclk = 0x47; }
+	else if (srate < 3000000) {
+		aclk = 0xb7; bclk = 0x4b; }
+	else if (srate < 7000000) {
+		aclk = 0xb7; bclk = 0x4f; }
+	else if (srate < 14000000) {
+		aclk = 0xb7; bclk = 0x53; }
+	else if (srate < 30000000) {
+		aclk = 0xb6; bclk = 0x53; }
+	else if (srate < 45000000) {
+		aclk = 0xb4; bclk = 0x51; }
+
+	stv0299_writereg(fe, 0x13, aclk);
+	stv0299_writereg(fe, 0x14, bclk);
+	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+
+	return 0;
+}
+
+static u8 sharp_z0194a__inittab[] = {
+	0x01, 0x15,
+	0x02, 0x00,
+	0x03, 0x00,
+	0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+	0x06, 0x40,   /* DAC not used, set to high impendance mode */
+	0x07, 0x00,   /* DAC LSB */
+	0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+	0x09, 0x00,   /* FIFO */
+	0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+	0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+	0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+	0x10, 0x3f,   /* AGC2  0x3d */
+	0x11, 0x84,
+	0x12, 0xb9,
+	0x15, 0xc9,   /* lock detector threshold */
+	0x16, 0x00,
+	0x17, 0x00,
+	0x18, 0x00,
+	0x19, 0x00,
+	0x1a, 0x00,
+	0x1f, 0x50,
+	0x20, 0x00,
+	0x21, 0x00,
+	0x22, 0x00,
+	0x23, 0x00,
+	0x28, 0x00,  /* out imp: normal  out type: parallel FEC mode:0 */
+	0x29, 0x1e,  /* 1/2 threshold */
+	0x2a, 0x14,  /* 2/3 threshold */
+	0x2b, 0x0f,  /* 3/4 threshold */
+	0x2c, 0x09,  /* 5/6 threshold */
+	0x2d, 0x05,  /* 7/8 threshold */
+	0x2e, 0x01,
+	0x31, 0x1f,  /* test all FECs */
+	0x32, 0x19,  /* viterbi and synchro search */
+	0x33, 0xfc,  /* rs control */
+	0x34, 0x93,  /* error control */
+	0x0f, 0x52,
+	0xff, 0xff
+};
+
+static struct stv0299_config sharp_z0194a_config = {
+	.demod_address = 0x68,
+	.inittab = sharp_z0194a__inittab,
+	.mclk = 88000000UL,
+	.invert = 1,
+	.skip_reinit = 0,
+	.lock_output = STV0299_LOCKOUTPUT_1,
+	.volt13_op0_op1 = STV0299_VOLT13_OP1,
+	.min_delay_ms = 100,
+	.set_symbol_rate = sharp_z0194a__set_symbol_rate,
+};
+
+#endif

+ 7 - 7
drivers/media/dvb/siano/smscoreapi.c

@@ -110,12 +110,12 @@ struct smscore_registry_entry_t {
 	enum sms_device_type_st	type;
 	enum sms_device_type_st	type;
 };
 };
 
 
-struct list_head g_smscore_notifyees;
-struct list_head g_smscore_devices;
-struct mutex g_smscore_deviceslock;
+static struct list_head g_smscore_notifyees;
+static struct list_head g_smscore_devices;
+static struct mutex g_smscore_deviceslock;
 
 
-struct list_head g_smscore_registry;
-struct mutex g_smscore_registrylock;
+static struct list_head g_smscore_registry;
+static struct mutex g_smscore_registrylock;
 
 
 static int default_mode = 4;
 static int default_mode = 4;
 
 
@@ -1187,7 +1187,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
 }
 }
 
 
 
 
-int smscore_module_init(void)
+static int __init smscore_module_init(void)
 {
 {
 	int rc = 0;
 	int rc = 0;
 
 
@@ -1209,7 +1209,7 @@ int smscore_module_init(void)
 	return rc;
 	return rc;
 }
 }
 
 
-void smscore_module_exit(void)
+static void __exit smscore_module_exit(void)
 {
 {
 
 
 	kmutex_lock(&g_smscore_deviceslock);
 	kmutex_lock(&g_smscore_deviceslock);

+ 2 - 2
drivers/media/dvb/siano/smsdvb.c

@@ -27,8 +27,8 @@
 
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
-struct list_head g_smsdvb_clients;
-struct mutex g_smsdvb_clientslock;
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
 
 
 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 {
 {

+ 0 - 4
drivers/media/dvb/ttpci/Kconfig

@@ -5,8 +5,6 @@ config TTPCI_EEPROM
 config DVB_AV7110
 config DVB_AV7110
 	tristate "AV7110 cards"
 	tristate "AV7110 cards"
 	depends on DVB_CORE && PCI && I2C
 	depends on DVB_CORE && PCI && I2C
-	depends on HOTPLUG
-	select FW_LOADER if !DVB_AV7110_FIRMWARE
 	select TTPCI_EEPROM
 	select TTPCI_EEPROM
 	select VIDEO_SAA7146_VV
 	select VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
@@ -127,14 +125,12 @@ config DVB_BUDGET_AV
 	depends on DVB_BUDGET_CORE && I2C
 	depends on DVB_BUDGET_CORE && I2C
 	select VIDEO_SAA7146_VV
 	select VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
-	depends on HOTPLUG	# dependency of FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
 	select DVB_TDA10021 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10021 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select DVB_TUA6100 if !DVB_FE_CUSTOMISE
 	select DVB_TUA6100 if !DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	help
 	  Support for simple SAA7146 based DVB cards
 	  Support for simple SAA7146 based DVB cards
 	  (so called Budget- or Nova-PCI cards) without onboard
 	  (so called Budget- or Nova-PCI cards) without onboard

+ 0 - 2
drivers/media/dvb/ttusb-dec/Kconfig

@@ -1,8 +1,6 @@
 config DVB_TTUSB_DEC
 config DVB_TTUSB_DEC
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	depends on DVB_CORE && USB && INPUT
 	depends on DVB_CORE && USB && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
-	select FW_LOADER
 	select CRC32
 	select CRC32
 	help
 	help
 	  Support for external USB adapters designed by Technotrend and
 	  Support for external USB adapters designed by Technotrend and

+ 10 - 8
drivers/media/radio/dsbr100.c

@@ -85,6 +85,7 @@
 #include <linux/input.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 #include <linux/usb.h>
 
 
 /*
 /*
@@ -444,14 +445,7 @@ static const struct file_operations usb_dsbr100_fops = {
 	.llseek		= no_llseek,
 	.llseek		= no_llseek,
 };
 };
 
 
-/* V4L2 interface */
-static struct video_device dsbr100_videodev_template =
-{
-	.owner		= THIS_MODULE,
-	.name		= "D-Link DSB-R 100",
-	.type		= VID_TYPE_TUNER,
-	.fops		= &usb_dsbr100_fops,
-	.release	= video_device_release,
+static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -466,6 +460,14 @@ static struct video_device dsbr100_videodev_template =
 	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_s_input     = vidioc_s_input,
 };
 };
 
 
+/* V4L2 interface */
+static struct video_device dsbr100_videodev_template = {
+	.name		= "D-Link DSB-R 100",
+	.fops		= &usb_dsbr100_fops,
+	.ioctl_ops 	= &usb_dsbr100_ioctl_ops,
+	.release	= video_device_release,
+};
+
 /* check if the device is present and register with v4l and
 /* check if the device is present and register with v4l and
 usb if it is */
 usb if it is */
 static int usb_dsbr100_probe(struct usb_interface *intf,
 static int usb_dsbr100_probe(struct usb_interface *intf,

+ 1 - 2
drivers/media/radio/miropcm20-radio.c

@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/videodev.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include "oss/aci.h"
 #include "oss/aci.h"
 #include "miropcm20-rds-core.h"
 #include "miropcm20-rds-core.h"
 
 
@@ -228,9 +229,7 @@ static const struct file_operations pcm20_fops = {
 };
 };
 
 
 static struct video_device pcm20_radio = {
 static struct video_device pcm20_radio = {
-	.owner		= THIS_MODULE,
 	.name		= "Miro PCM 20 radio",
 	.name		= "Miro PCM 20 radio",
-	.type		= VID_TYPE_TUNER,
 	.fops           = &pcm20_fops,
 	.fops           = &pcm20_fops,
 	.priv		= &pcm20_unit
 	.priv		= &pcm20_unit
 };
 };

+ 8 - 6
drivers/media/radio/radio-aimslab.c

@@ -36,6 +36,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -388,12 +389,7 @@ static const struct file_operations rtrack_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device rtrack_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "RadioTrack radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &rtrack_fops,
+static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -408,6 +404,12 @@ static struct video_device rtrack_radio=
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device rtrack_radio = {
+	.name		= "RadioTrack radio",
+	.fops           = &rtrack_fops,
+	.ioctl_ops 	= &rtrack_ioctl_ops,
+};
+
 static int __init rtrack_init(void)
 static int __init rtrack_init(void)
 {
 {
 	if(io==-1)
 	if(io==-1)

+ 8 - 6
drivers/media/radio/radio-aztech.c

@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -352,12 +353,7 @@ static const struct file_operations aztech_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device aztech_radio=
-{
-	.owner		    = THIS_MODULE,
-	.name		    = "Aztech radio",
-	.type		    = VID_TYPE_TUNER,
-	.fops               = &aztech_fops,
+static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -372,6 +368,12 @@ static struct video_device aztech_radio=
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device aztech_radio = {
+	.name		    = "Aztech radio",
+	.fops               = &aztech_fops,
+	.ioctl_ops 	    = &aztech_ioctl_ops,
+};
+
 module_param_named(debug,aztech_radio.debug, int, 0644);
 module_param_named(debug,aztech_radio.debug, int, 0644);
 MODULE_PARM_DESC(debug,"activates debug info");
 MODULE_PARM_DESC(debug,"activates debug info");
 
 

+ 8 - 6
drivers/media/radio/radio-cadet.c

@@ -39,6 +39,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* V4L2 API defs		*/
 #include <linux/videodev2.h>	/* V4L2 API defs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/param.h>
 #include <linux/param.h>
 #include <linux/pnp.h>
 #include <linux/pnp.h>
 
 
@@ -569,12 +570,7 @@ static const struct file_operations cadet_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device cadet_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "Cadet radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &cadet_fops,
+static const struct v4l2_ioctl_ops cadet_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -589,6 +585,12 @@ static struct video_device cadet_radio=
 	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_s_input     = vidioc_s_input,
 };
 };
 
 
+static struct video_device cadet_radio = {
+	.name		= "Cadet radio",
+	.fops           = &cadet_fops,
+	.ioctl_ops 	= &cadet_ioctl_ops,
+};
+
 #ifdef CONFIG_PNP
 #ifdef CONFIG_PNP
 
 
 static struct pnp_device_id cadet_pnp_devices[] = {
 static struct pnp_device_id cadet_pnp_devices[] = {

+ 8 - 5
drivers/media/radio/radio-gemtek-pci.c

@@ -46,6 +46,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -374,11 +375,7 @@ static const struct file_operations gemtek_pci_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device vdev_template = {
-	.owner         = THIS_MODULE,
-	.name          = "Gemtek PCI Radio",
-	.type          = VID_TYPE_TUNER,
-	.fops          = &gemtek_pci_fops,
+static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -393,6 +390,12 @@ static struct video_device vdev_template = {
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device vdev_template = {
+	.name          = "Gemtek PCI Radio",
+	.fops          = &gemtek_pci_fops,
+	.ioctl_ops     = &gemtek_pci_ioctl_ops,
+};
+
 static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
 static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
 {
 {
 	struct gemtek_pci_card *card;
 	struct gemtek_pci_card *card;

+ 8 - 5
drivers/media/radio/radio-gemtek.c

@@ -23,6 +23,7 @@
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 
 
@@ -552,11 +553,7 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct video_device gemtek_radio = {
-	.owner			= THIS_MODULE,
-	.name			= "GemTek Radio card",
-	.type			= VID_TYPE_TUNER,
-	.fops			= &gemtek_fops,
+static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_g_tuner		= vidioc_g_tuner,
 	.vidioc_g_tuner		= vidioc_g_tuner,
 	.vidioc_s_tuner		= vidioc_s_tuner,
 	.vidioc_s_tuner		= vidioc_s_tuner,
@@ -571,6 +568,12 @@ static struct video_device gemtek_radio = {
 	.vidioc_s_ctrl		= vidioc_s_ctrl
 	.vidioc_s_ctrl		= vidioc_s_ctrl
 };
 };
 
 
+static struct video_device gemtek_radio = {
+	.name			= "GemTek Radio card",
+	.fops			= &gemtek_fops,
+	.ioctl_ops 		= &gemtek_ioctl_ops,
+};
+
 /*
 /*
  * Initialization / cleanup related stuff.
  * Initialization / cleanup related stuff.
  */
  */

+ 8 - 4
drivers/media/radio/radio-maestro.c

@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,6)
 #define RADIO_VERSION KERNEL_VERSION(0,0,6)
@@ -354,10 +355,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
 	return (ofreq == radio_bits_get(dev));
 	return (ofreq == radio_bits_get(dev));
 }
 }
 
 
-static struct video_device maestro_radio = {
-	.name           = "Maestro radio",
-	.type           = VID_TYPE_TUNER,
-	.fops           = &maestro_fops,
+static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -372,6 +370,12 @@ static struct video_device maestro_radio = {
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device maestro_radio = {
+	.name           = "Maestro radio",
+	.fops           = &maestro_fops,
+	.ioctl_ops 	= &maestro_ioctl_ops,
+};
+
 static int __devinit maestro_probe(struct pci_dev *pdev,
 static int __devinit maestro_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 	const struct pci_device_id *ent)
 {
 {

+ 8 - 7
drivers/media/radio/radio-maxiradio.c

@@ -44,6 +44,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #define DRIVER_VERSION	"0.77"
 #define DRIVER_VERSION	"0.77"
 
 
@@ -373,13 +374,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
-static struct video_device maxiradio_radio =
-{
-	.owner		    = THIS_MODULE,
-	.name		    = "Maxi Radio FM2000 radio",
-	.type		    = VID_TYPE_TUNER,
-	.fops               = &maxiradio_fops,
-
+static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -394,6 +389,12 @@ static struct video_device maxiradio_radio =
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device maxiradio_radio = {
+	.name		    = "Maxi Radio FM2000 radio",
+	.fops               = &maxiradio_fops,
+	.ioctl_ops 	    = &maxiradio_ioctl_ops,
+};
+
 static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 {
 	if(!request_region(pci_resource_start(pdev, 0),
 	if(!request_region(pci_resource_start(pdev, 0),

+ 8 - 6
drivers/media/radio/radio-rtrack2.c

@@ -17,6 +17,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -294,12 +295,7 @@ static const struct file_operations rtrack2_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device rtrack2_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "RadioTrack II radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &rtrack2_fops,
+static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -314,6 +310,12 @@ static struct video_device rtrack2_radio=
 	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_s_input     = vidioc_s_input,
 };
 };
 
 
+static struct video_device rtrack2_radio = {
+	.name		= "RadioTrack II radio",
+	.fops           = &rtrack2_fops,
+	.ioctl_ops 	= &rtrack2_ioctl_ops,
+};
+
 static int __init rtrack2_init(void)
 static int __init rtrack2_init(void)
 {
 {
 	if(io==-1)
 	if(io==-1)

+ 8 - 6
drivers/media/radio/radio-sf16fmi.c

@@ -24,6 +24,7 @@
 #include <linux/delay.h>	/* udelay			*/
 #include <linux/delay.h>	/* udelay			*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/isapnp.h>
 #include <linux/isapnp.h>
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
@@ -294,12 +295,7 @@ static const struct file_operations fmi_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device fmi_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "SF16FMx radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &fmi_fops,
+static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -314,6 +310,12 @@ static struct video_device fmi_radio=
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device fmi_radio = {
+	.name		= "SF16FMx radio",
+	.fops           = &fmi_fops,
+	.ioctl_ops 	= &fmi_ioctl_ops,
+};
+
 /* ladis: this is my card. does any other types exist? */
 /* ladis: this is my card. does any other types exist? */
 static struct isapnp_device_id id_table[] __devinitdata = {
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,

+ 8 - 6
drivers/media/radio/radio-sf16fmr2.c

@@ -22,6 +22,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 
 
 static struct mutex lock;
 static struct mutex lock;
@@ -410,12 +411,7 @@ static const struct file_operations fmr2_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device fmr2_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "SF16FMR2 radio",
-	. type		= VID_TYPE_TUNER,
-	.fops		= &fmr2_fops,
+static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -430,6 +426,12 @@ static struct video_device fmr2_radio=
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device fmr2_radio = {
+	.name		= "SF16FMR2 radio",
+	.fops		= &fmr2_fops,
+	.ioctl_ops 	= &fmr2_ioctl_ops,
+};
+
 static int __init fmr2_init(void)
 static int __init fmr2_init(void)
 {
 {
 	fmr2_unit.port = io;
 	fmr2_unit.port = io;

+ 12 - 10
drivers/media/radio/radio-si470x.c

@@ -133,6 +133,7 @@
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/rds.h>
 #include <media/rds.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 
 
@@ -1585,15 +1586,7 @@ done:
 	return retval;
 	return retval;
 }
 }
 
 
-
-/*
- * si470x_viddev_tamples - video device interface
- */
-static struct video_device si470x_viddev_template = {
-	.fops			= &si470x_fops,
-	.name			= DRIVER_NAME,
-	.type			= VID_TYPE_TUNER,
-	.release		= video_device_release,
+static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
 	.vidioc_querycap	= si470x_vidioc_querycap,
 	.vidioc_querycap	= si470x_vidioc_querycap,
 	.vidioc_g_input		= si470x_vidioc_g_input,
 	.vidioc_g_input		= si470x_vidioc_g_input,
 	.vidioc_s_input		= si470x_vidioc_s_input,
 	.vidioc_s_input		= si470x_vidioc_s_input,
@@ -1607,7 +1600,16 @@ static struct video_device si470x_viddev_template = {
 	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
 	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
 	.vidioc_s_frequency	= si470x_vidioc_s_frequency,
 	.vidioc_s_frequency	= si470x_vidioc_s_frequency,
 	.vidioc_s_hw_freq_seek	= si470x_vidioc_s_hw_freq_seek,
 	.vidioc_s_hw_freq_seek	= si470x_vidioc_s_hw_freq_seek,
-	.owner			= THIS_MODULE,
+};
+
+/*
+ * si470x_viddev_tamples - video device interface
+ */
+static struct video_device si470x_viddev_template = {
+	.fops			= &si470x_fops,
+	.ioctl_ops 		= &si470x_ioctl_ops,
+	.name			= DRIVER_NAME,
+	.release		= video_device_release,
 };
 };
 
 
 
 

+ 8 - 6
drivers/media/radio/radio-terratec.c

@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -366,12 +367,7 @@ static const struct file_operations terratec_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device terratec_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "TerraTec ActiveRadio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &terratec_fops,
+static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -386,6 +382,12 @@ static struct video_device terratec_radio=
 	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_s_input     = vidioc_s_input,
 };
 };
 
 
+static struct video_device terratec_radio = {
+	.name		= "TerraTec ActiveRadio",
+	.fops           = &terratec_fops,
+	.ioctl_ops 	= &terratec_ioctl_ops,
+};
+
 static int __init terratec_init(void)
 static int __init terratec_init(void)
 {
 {
 	if(io==-1)
 	if(io==-1)

+ 8 - 6
drivers/media/radio/radio-trust.c

@@ -23,6 +23,7 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -346,12 +347,7 @@ static const struct file_operations trust_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device trust_radio=
-{
-	.owner		= THIS_MODULE,
-	.name		= "Trust FM Radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &trust_fops,
+static const struct v4l2_ioctl_ops trust_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -366,6 +362,12 @@ static struct video_device trust_radio=
 	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_s_input     = vidioc_s_input,
 };
 };
 
 
+static struct video_device trust_radio = {
+	.name		= "Trust FM Radio",
+	.fops           = &trust_fops,
+	.ioctl_ops 	= &trust_ioctl_ops,
+};
+
 static int __init trust_init(void)
 static int __init trust_init(void)
 {
 {
 	if(io == -1) {
 	if(io == -1) {

+ 8 - 6
drivers/media/radio/radio-typhoon.c

@@ -40,6 +40,7 @@
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,1,1)
 #define RADIO_VERSION KERNEL_VERSION(0,1,1)
@@ -344,12 +345,7 @@ static const struct file_operations typhoon_fops = {
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device typhoon_radio =
-{
-	.owner		= THIS_MODULE,
-	.name		= "Typhoon Radio",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &typhoon_fops,
+static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -364,6 +360,12 @@ static struct video_device typhoon_radio =
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device typhoon_radio = {
+	.name		= "Typhoon Radio",
+	.fops           = &typhoon_fops,
+	.ioctl_ops 	= &typhoon_ioctl_ops,
+};
+
 #ifdef CONFIG_RADIO_TYPHOON_PROC_FS
 #ifdef CONFIG_RADIO_TYPHOON_PROC_FS
 
 
 static int typhoon_proc_show(struct seq_file *m, void *v)
 static int typhoon_proc_show(struct seq_file *m, void *v)

+ 8 - 6
drivers/media/radio/radio-zoltrix.c

@@ -37,6 +37,7 @@
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -407,12 +408,7 @@ static const struct file_operations zoltrix_fops =
 	.llseek         = no_llseek,
 	.llseek         = no_llseek,
 };
 };
 
 
-static struct video_device zoltrix_radio =
-{
-	.owner		= THIS_MODULE,
-	.name		= "Zoltrix Radio Plus",
-	.type		= VID_TYPE_TUNER,
-	.fops           = &zoltrix_fops,
+static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -427,6 +423,12 @@ static struct video_device zoltrix_radio =
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 };
 
 
+static struct video_device zoltrix_radio = {
+	.name		= "Zoltrix Radio Plus",
+	.fops           = &zoltrix_fops,
+	.ioctl_ops 	= &zoltrix_ioctl_ops,
+};
+
 static int __init zoltrix_init(void)
 static int __init zoltrix_init(void)
 {
 {
 	if (io == -1) {
 	if (io == -1) {

+ 1 - 18
drivers/media/video/Kconfig

@@ -487,17 +487,6 @@ config VIDEO_PMS
 	  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 pms.
 	  module will be called pms.
 
 
-config VIDEO_PLANB
-	tristate "PlanB Video-In on PowerMac"
-	depends on PPC_PMAC && VIDEO_V4L1 && BROKEN
-	help
-	  PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
-	  input hardware. If you want to experiment with this, say Y.
-	  Otherwise, or if you don't understand a word, say N. See
-	  <http://www.cpu.lu/~mlan/linux/dev/planb.html> for more info.
-
-	  Saying M will compile this driver as a module (planb).
-
 config VIDEO_BWQCAM
 config VIDEO_BWQCAM
 	tristate "Quickcam BW Video For Linux"
 	tristate "Quickcam BW Video For Linux"
 	depends on PARPORT && VIDEO_V4L1
 	depends on PARPORT && VIDEO_V4L1
@@ -806,13 +795,7 @@ menuconfig V4L_USB_DRIVERS
 
 
 if V4L_USB_DRIVERS && USB
 if V4L_USB_DRIVERS && USB
 
 
-config USB_VIDEO_CLASS
-	tristate "USB Video Class (UVC)"
-	---help---
-	  Support for the USB Video Class (UVC).  Currently only video
-	  input devices, such as webcams, are supported.
-
-	  For more information see: <http://linux-uvc.berlios.de/>
+source "drivers/media/video/uvc/Kconfig"
 
 
 source "drivers/media/video/gspca/Kconfig"
 source "drivers/media/video/gspca/Kconfig"
 
 

+ 2 - 1
drivers/media/video/Makefile

@@ -10,6 +10,8 @@ msp3400-objs	:=	msp3400-driver.o msp3400-kthreads.o
 
 
 stkwebcam-objs	:=	stk-webcam.o stk-sensor.o
 stkwebcam-objs	:=	stk-webcam.o stk-sensor.o
 
 
+videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o
+
 obj-$(CONFIG_VIDEO_DEV) += videodev.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
 obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
@@ -55,7 +57,6 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
 obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
 obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
 
 
 obj-$(CONFIG_VIDEO_PMS) += pms.o
 obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_PLANB) += planb.o
 obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
 obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
 obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
 obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o

+ 0 - 1
drivers/media/video/arv.c

@@ -754,7 +754,6 @@ static const struct file_operations ar_fops = {
 };
 };
 
 
 static struct video_device ar_template = {
 static struct video_device ar_template = {
-	.owner		= THIS_MODULE,
 	.name		= "Colour AR VGA",
 	.name		= "Colour AR VGA",
 	.type		= VID_TYPE_CAPTURE,
 	.type		= VID_TYPE_CAPTURE,
 	.fops		= &ar_fops,
 	.fops		= &ar_fops,

+ 1 - 0
drivers/media/video/au0828/Kconfig

@@ -6,6 +6,7 @@ config VIDEO_AU0828
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+	select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
 	---help---
 	---help---
 	  This is a video4linux driver for Auvitek's USB device.
 	  This is a video4linux driver for Auvitek's USB device.
 
 

+ 12 - 0
drivers/media/video/au0828/au0828-cards.c

@@ -32,6 +32,9 @@ struct au0828_board au0828_boards[] = {
 	[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
 	[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
 		.name	= "Hauppauge HVR950Q",
 		.name	= "Hauppauge HVR950Q",
 	},
 	},
+	[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
+		.name	= "Hauppauge HVR950Q rev xxF8",
+	},
 	[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
 	[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
 		.name	= "DViCO FusionHDTV USB",
 		.name	= "DViCO FusionHDTV USB",
 	},
 	},
@@ -49,6 +52,7 @@ int au0828_tuner_callback(void *priv, int command, int arg)
 	switch (dev->board) {
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 	case AU0828_BOARD_DVICO_FUSIONHDTV7:
 	case AU0828_BOARD_DVICO_FUSIONHDTV7:
 		if (command == 0) {
 		if (command == 0) {
 			/* Tuner Reset Command from xc5000 */
 			/* Tuner Reset Command from xc5000 */
@@ -110,6 +114,7 @@ void au0828_card_setup(struct au0828_dev *dev)
 	switch (dev->board) {
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 		if (dev->i2c_rc == 0)
 		if (dev->i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xa0);
 			hauppauge_eeprom(dev, eeprom+0xa0);
 		break;
 		break;
@@ -128,6 +133,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
 	switch (dev->board) {
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 		/* GPIO's
 		/* GPIO's
 		 * 4 - CS5340
 		 * 4 - CS5340
 		 * 5 - AU8522 Demodulator
 		 * 5 - AU8522 Demodulator
@@ -193,6 +199,12 @@ struct usb_device_id au0828_usb_id_table [] = {
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x0fd9, 0x0008),
 	{ USB_DEVICE(0x0fd9, 0x0008),
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+	{ USB_DEVICE(0x2040, 0x7201),
+		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
+	{ USB_DEVICE(0x2040, 0x7211),
+		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
+	{ USB_DEVICE(0x2040, 0x7281),
+		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
 	{ },
 	{ },
 };
 };
 
 

+ 1 - 0
drivers/media/video/au0828/au0828-cards.h

@@ -23,3 +23,4 @@
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q	1
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q	1
 #define AU0828_BOARD_HAUPPAUGE_HVR850 	2
 #define AU0828_BOARD_HAUPPAUGE_HVR850 	2
 #define AU0828_BOARD_DVICO_FUSIONHDTV7	3
 #define AU0828_BOARD_DVICO_FUSIONHDTV7	3
+#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL	4

+ 15 - 0
drivers/media/video/au0828/au0828-dvb.c

@@ -28,6 +28,7 @@
 #include "au0828.h"
 #include "au0828.h"
 #include "au8522.h"
 #include "au8522.h"
 #include "xc5000.h"
 #include "xc5000.h"
+#include "mxl5007t.h"
 
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
@@ -45,6 +46,11 @@ static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
 	.tuner_callback   = au0828_tuner_callback
 	.tuner_callback   = au0828_tuner_callback
 };
 };
 
 
+static struct mxl5007t_config mxl5007t_hvr950q_config = {
+	.xtal_freq_hz = MxL_XTAL_24_MHZ,
+	.if_freq_hz = MxL_IF_6_MHZ,
+};
+
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
 static void urb_completion(struct urb *purb)
 static void urb_completion(struct urb *purb)
 {
 {
@@ -342,6 +348,15 @@ int au0828_dvb_register(struct au0828_dev *dev)
 				&dev->i2c_adap,
 				&dev->i2c_adap,
 				&hauppauge_hvr950q_tunerconfig, dev);
 				&hauppauge_hvr950q_tunerconfig, dev);
 		break;
 		break;
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
+		dvb->frontend = dvb_attach(au8522_attach,
+				&hauppauge_hvr950q_config,
+				&dev->i2c_adap);
+		if (dvb->frontend != NULL)
+			dvb_attach(mxl5007t_attach, dvb->frontend,
+				   &dev->i2c_adap, 0x60,
+				   &mxl5007t_hvr950q_config);
+		break;
 	default:
 	default:
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 		       "isn't supported yet\n");
 		       "isn't supported yet\n");

+ 0 - 2
drivers/media/video/bt8xx/Kconfig

@@ -1,9 +1,7 @@
 config VIDEO_BT848
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
 	tristate "BT848 Video For Linux"
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
 	select VIDEO_IR

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

@@ -45,6 +45,7 @@
 #include <linux/kdev_t.h>
 #include <linux/kdev_t.h>
 #include "bttvp.h"
 #include "bttvp.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tvaudio.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
 #include <media/msp3400.h>
 
 
@@ -163,8 +164,8 @@ MODULE_LICENSE("GPL");
 static ssize_t show_card(struct device *cd,
 static ssize_t show_card(struct device *cd,
 			 struct device_attribute *attr, char *buf)
 			 struct device_attribute *attr, char *buf)
 {
 {
-	struct video_device *vfd = container_of(cd, struct video_device, class_dev);
-	struct bttv *btv = dev_get_drvdata(vfd->dev);
+	struct video_device *vfd = container_of(cd, struct video_device, dev);
+	struct bttv *btv = dev_get_drvdata(vfd->parent);
 	return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 	return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 }
 }
 static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
 static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -3357,10 +3358,7 @@ static const struct file_operations bttv_fops =
 	.poll     = bttv_poll,
 	.poll     = bttv_poll,
 };
 };
 
 
-static struct video_device bttv_video_template =
-{
-	.fops     = &bttv_fops,
-	.minor    = -1,
+static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
 	.vidioc_querycap                = bttv_querycap,
 	.vidioc_querycap                = bttv_querycap,
 	.vidioc_enum_fmt_vid_cap        = bttv_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap        = bttv_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap           = bttv_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap           = bttv_g_fmt_vid_cap,
@@ -3411,8 +3409,14 @@ static struct video_device bttv_video_template =
 	.vidioc_g_register		= bttv_g_register,
 	.vidioc_g_register		= bttv_g_register,
 	.vidioc_s_register		= bttv_s_register,
 	.vidioc_s_register		= bttv_s_register,
 #endif
 #endif
-	.tvnorms                        = BTTV_NORMS,
-	.current_norm                   = V4L2_STD_PAL,
+};
+
+static struct video_device bttv_video_template = {
+	.fops         = &bttv_fops,
+	.minor        = -1,
+	.ioctl_ops    = &bttv_ioctl_ops,
+	.tvnorms      = BTTV_NORMS,
+	.current_norm = V4L2_STD_PAL,
 };
 };
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
@@ -3635,10 +3639,7 @@ static const struct file_operations radio_fops =
 	.poll     = radio_poll,
 	.poll     = radio_poll,
 };
 };
 
 
-static struct video_device radio_template =
-{
-	.fops     = &radio_fops,
-	.minor    = -1,
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 	.vidioc_querycap        = radio_querycap,
 	.vidioc_querycap        = radio_querycap,
 	.vidioc_g_tuner         = radio_g_tuner,
 	.vidioc_g_tuner         = radio_g_tuner,
 	.vidioc_enum_input      = radio_enum_input,
 	.vidioc_enum_input      = radio_enum_input,
@@ -3655,6 +3656,12 @@ static struct video_device radio_template =
 	.vidioc_s_frequency     = bttv_s_frequency,
 	.vidioc_s_frequency     = bttv_s_frequency,
 };
 };
 
 
+static struct video_device radio_template = {
+	.fops      = &radio_fops,
+	.minor     = -1,
+	.ioctl_ops = &radio_ioctl_ops,
+};
+
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 /* some debug code                                                         */
 /* some debug code                                                         */
 
 
@@ -4175,8 +4182,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
 
 
 static struct video_device *vdev_init(struct bttv *btv,
 static struct video_device *vdev_init(struct bttv *btv,
 				      const struct video_device *template,
 				      const struct video_device *template,
-				      const char *type_name,
-				      const int type)
+				      const char *type_name)
 {
 {
 	struct video_device *vfd;
 	struct video_device *vfd;
 
 
@@ -4185,9 +4191,8 @@ static struct video_device *vdev_init(struct bttv *btv,
 		return NULL;
 		return NULL;
 	*vfd = *template;
 	*vfd = *template;
 	vfd->minor   = -1;
 	vfd->minor   = -1;
-	vfd->dev     = &btv->c.pci->dev;
+	vfd->parent  = &btv->c.pci->dev;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
-	vfd->type    = type;
 	vfd->debug   = bttv_debug;
 	vfd->debug   = bttv_debug;
 	snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
 	snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
 		 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
 		 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
@@ -4223,20 +4228,11 @@ static void bttv_unregister_video(struct bttv *btv)
 /* register video4linux devices */
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 static int __devinit bttv_register_video(struct bttv *btv)
 {
 {
-	int video_type = VID_TYPE_CAPTURE |
-			 VID_TYPE_TUNER   |
-			 VID_TYPE_CLIPPING|
-			 VID_TYPE_SCALES;
-
-	if (no_overlay <= 0) {
-		bttv_video_template.type |= VID_TYPE_OVERLAY;
-	} else {
+	if (no_overlay > 0)
 		printk("bttv: Overlay support disabled.\n");
 		printk("bttv: Overlay support disabled.\n");
-	}
 
 
 	/* video */
 	/* video */
-	btv->video_dev = vdev_init(btv, &bttv_video_template,
-				   "video", video_type);
+	btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
 
 
 	if (NULL == btv->video_dev)
 	if (NULL == btv->video_dev)
 		goto err;
 		goto err;
@@ -4244,7 +4240,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
 		goto err;
 		goto err;
 	printk(KERN_INFO "bttv%d: registered device video%d\n",
 	printk(KERN_INFO "bttv%d: registered device video%d\n",
 	       btv->c.nr,btv->video_dev->minor & 0x1f);
 	       btv->c.nr,btv->video_dev->minor & 0x1f);
-	if (device_create_file(&btv->video_dev->class_dev,
+	if (device_create_file(&btv->video_dev->dev,
 				     &dev_attr_card)<0) {
 				     &dev_attr_card)<0) {
 		printk(KERN_ERR "bttv%d: device_create_file 'card' "
 		printk(KERN_ERR "bttv%d: device_create_file 'card' "
 		       "failed\n", btv->c.nr);
 		       "failed\n", btv->c.nr);
@@ -4252,8 +4248,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
 	}
 	}
 
 
 	/* vbi */
 	/* vbi */
-	btv->vbi_dev = vdev_init(btv, &bttv_video_template,
-				 "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT);
+	btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi");
 
 
 	if (NULL == btv->vbi_dev)
 	if (NULL == btv->vbi_dev)
 		goto err;
 		goto err;
@@ -4265,8 +4260,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
 	if (!btv->has_radio)
 	if (!btv->has_radio)
 		return 0;
 		return 0;
 	/* radio */
 	/* radio */
-	btv->radio_dev = vdev_init(btv, &radio_template,
-				   "radio", VID_TYPE_TUNER);
+	btv->radio_dev = vdev_init(btv, &radio_template, "radio");
 	if (NULL == btv->radio_dev)
 	if (NULL == btv->radio_dev)
 		goto err;
 		goto err;
 	if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
 	if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)

+ 1 - 0
drivers/media/video/bt8xx/bttv-risc.c

@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include "bttvp.h"
 #include "bttvp.h"
 
 

+ 1 - 0
drivers/media/video/bt8xx/bttv-vbi.c

@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include <linux/kdev_t.h>
+#include <media/v4l2-ioctl.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include "bttvp.h"
 #include "bttvp.h"
 
 

+ 1 - 2
drivers/media/video/bw-qcam.c

@@ -74,6 +74,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
@@ -906,9 +907,7 @@ static const struct file_operations qcam_fops = {
 };
 };
 static struct video_device qcam_template=
 static struct video_device qcam_template=
 {
 {
-	.owner		= THIS_MODULE,
 	.name		= "Connectix Quickcam",
 	.name		= "Connectix Quickcam",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &qcam_fops,
 	.fops           = &qcam_fops,
 };
 };
 
 

+ 1 - 2
drivers/media/video/c-qcam.c

@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
 
 
@@ -701,9 +702,7 @@ static const struct file_operations qcam_fops = {
 
 
 static struct video_device qcam_template=
 static struct video_device qcam_template=
 {
 {
-	.owner		= THIS_MODULE,
 	.name		= "Colour QuickCam",
 	.name		= "Colour QuickCam",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &qcam_fops,
 	.fops           = &qcam_fops,
 };
 };
 
 

+ 14 - 12
drivers/media/video/cafe_ccic.c

@@ -25,6 +25,7 @@
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
@@ -1768,17 +1769,7 @@ static const struct file_operations cafe_v4l_fops = {
 	.llseek = no_llseek,
 	.llseek = no_llseek,
 };
 };
 
 
-static struct video_device cafe_v4l_template = {
-	.name = "cafe",
-	.type = VFL_TYPE_GRABBER,
-	.type2 = VID_TYPE_CAPTURE,
-	.minor = -1, /* Get one dynamically */
-	.tvnorms = V4L2_STD_NTSC_M,
-	.current_norm = V4L2_STD_NTSC_M,  /* make mplayer happy */
-
-	.fops = &cafe_v4l_fops,
-	.release = cafe_v4l_dev_release,
-
+static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
 	.vidioc_querycap 	= cafe_vidioc_querycap,
 	.vidioc_querycap 	= cafe_vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	= cafe_vidioc_try_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	= cafe_vidioc_try_fmt_vid_cap,
@@ -1801,6 +1792,17 @@ static struct video_device cafe_v4l_template = {
 	.vidioc_s_parm		= cafe_vidioc_s_parm,
 	.vidioc_s_parm		= cafe_vidioc_s_parm,
 };
 };
 
 
+static struct video_device cafe_v4l_template = {
+	.name = "cafe",
+	.minor = -1, /* Get one dynamically */
+	.tvnorms = V4L2_STD_NTSC_M,
+	.current_norm = V4L2_STD_NTSC_M,  /* make mplayer happy */
+
+	.fops = &cafe_v4l_fops,
+	.ioctl_ops = &cafe_v4l_ioctl_ops,
+	.release = cafe_v4l_dev_release,
+};
+
 
 
 
 
 
 
@@ -2157,7 +2159,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	cam->v4ldev = cafe_v4l_template;
 	cam->v4ldev = cafe_v4l_template;
 	cam->v4ldev.debug = 0;
 	cam->v4ldev.debug = 0;
 //	cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
 //	cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
-	cam->v4ldev.dev = &pdev->dev;
+	cam->v4ldev.parent = &pdev->dev;
 	ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
 	ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
 	if (ret)
 	if (ret)
 		goto out_smbus;
 		goto out_smbus;

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

@@ -17,7 +17,7 @@
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/smp_lock.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 
 

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

@@ -3799,9 +3799,7 @@ static const struct file_operations cpia_fops = {
 };
 };
 
 
 static struct video_device cpia_template = {
 static struct video_device cpia_template = {
-	.owner		= THIS_MODULE,
 	.name		= "CPiA Camera",
 	.name		= "CPiA Camera",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &cpia_fops,
 	.fops           = &cpia_fops,
 };
 };
 
 

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

@@ -46,6 +46,7 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 
 

+ 1 - 0
drivers/media/video/cpia2/cpia2_core.c

@@ -32,6 +32,7 @@
 #include "cpia2.h"
 #include "cpia2.h"
 
 
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 
 

+ 1 - 4
drivers/media/video/cpia2/cpia2_v4l.c

@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include "cpia2.h"
 #include "cpia2.h"
 #include "cpia2dev.h"
 #include "cpia2dev.h"
@@ -1935,11 +1936,7 @@ static const struct file_operations fops_template = {
 
 
 static struct video_device cpia2_template = {
 static struct video_device cpia2_template = {
 	/* I could not find any place for the old .initialize initializer?? */
 	/* I could not find any place for the old .initialize initializer?? */
-	.owner=		THIS_MODULE,
 	.name=		"CPiA2 Camera",
 	.name=		"CPiA2 Camera",
-	.type=		VID_TYPE_CAPTURE,
-	.type2 = 	V4L2_CAP_VIDEO_CAPTURE |
-			V4L2_CAP_STREAMING,
 	.minor=		-1,
 	.minor=		-1,
 	.fops=		&fops_template,
 	.fops=		&fops_template,
 	.release=	video_device_release,
 	.release=	video_device_release,

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

@@ -111,7 +111,7 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
 		if (cmd == VIDIOC_DBG_G_REGISTER)
 		if (cmd == VIDIOC_DBG_G_REGISTER)
 			reg->val = cs5345_read(client, reg->reg & 0x1f);
 			reg->val = cs5345_read(client, reg->reg & 0x1f);
 		else
 		else
-			cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f);
+			cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff);
 		break;
 		break;
 	}
 	}
 #endif
 #endif

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

@@ -26,7 +26,7 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 #include <media/v4l2-i2c-drv-legacy.h>

+ 0 - 2
drivers/media/video/cx18/Kconfig

@@ -2,9 +2,7 @@ config VIDEO_CX18
 	tristate "Conexant cx23418 MPEG encoder support"
 	tristate "Conexant cx23418 MPEG encoder support"
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
 	depends on INPUT	# due to VIDEO_IR
 	depends on INPUT	# due to VIDEO_IR
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_IR
 	select VIDEO_IR
 	select VIDEO_TUNER
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM

+ 94 - 17
drivers/media/video/cx18/cx18-av-audio.c

@@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 	if (freq != 32000 && freq != 44100 && freq != 48000)
 	if (freq != 32000 && freq != 44100 && freq != 48000)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	/* common for all inputs and rates */
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
 	cx18_av_write(cx, 0x127, 0x50);
 	cx18_av_write(cx, 0x127, 0x50);
 
 
@@ -38,15 +37,30 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 		switch (freq) {
 		switch (freq) {
 		case 32000:
 		case 32000:
 			/* VID_PLL and AUX_PLL */
 			/* VID_PLL and AUX_PLL */
-			cx18_av_write4(cx, 0x108, 0x1006040f);
+			cx18_av_write4(cx, 0x108, 0x1408040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x01bb39ee);
+			/* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */
+			cx18_av_write4(cx, 0x110, 0x012a0863);
 
 
-			/* src3/4/6_ctl = 0x0801f77f */
+			/* src3/4/6_ctl */
+			/* 0x1.f77f = (4 * 15734.26) / 32000 */
 			cx18_av_write4(cx, 0x900, 0x0801f77f);
 			cx18_av_write4(cx, 0x900, 0x0801f77f);
 			cx18_av_write4(cx, 0x904, 0x0801f77f);
 			cx18_av_write4(cx, 0x904, 0x0801f77f);
 			cx18_av_write4(cx, 0x90c, 0x0801f77f);
 			cx18_av_write4(cx, 0x90c, 0x0801f77f);
+
+			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
+			cx18_av_write(cx, 0x127, 0x54);
+
+			/* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x11202fff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
+			 *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa10d2ef8);
 			break;
 			break;
 
 
 		case 44100:
 		case 44100:
@@ -54,12 +68,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 			cx18_av_write4(cx, 0x108, 0x1009040f);
 			cx18_av_write4(cx, 0x108, 0x1009040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x00ec6bd6);
+			/* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */
+			cx18_av_write4(cx, 0x110, 0x00ec6bce);
 
 
-			/* src3/4/6_ctl = 0x08016d59 */
+			/* src3/4/6_ctl */
+			/* 0x1.6d59 = (4 * 15734.26) / 44100 */
 			cx18_av_write4(cx, 0x900, 0x08016d59);
 			cx18_av_write4(cx, 0x900, 0x08016d59);
 			cx18_av_write4(cx, 0x904, 0x08016d59);
 			cx18_av_write4(cx, 0x904, 0x08016d59);
 			cx18_av_write4(cx, 0x90c, 0x08016d59);
 			cx18_av_write4(cx, 0x90c, 0x08016d59);
+
+			/* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x112092ff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
+			 *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa11d4bf8);
 			break;
 			break;
 
 
 		case 48000:
 		case 48000:
@@ -67,12 +93,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 			cx18_av_write4(cx, 0x108, 0x100a040f);
 			cx18_av_write4(cx, 0x108, 0x100a040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x0098d6e5);
+			/* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */
+			cx18_av_write4(cx, 0x110, 0x0098d6dd);
 
 
-			/* src3/4/6_ctl = 0x08014faa */
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 15734.26) / 48000 */
 			cx18_av_write4(cx, 0x900, 0x08014faa);
 			cx18_av_write4(cx, 0x900, 0x08014faa);
 			cx18_av_write4(cx, 0x904, 0x08014faa);
 			cx18_av_write4(cx, 0x904, 0x08014faa);
 			cx18_av_write4(cx, 0x90c, 0x08014faa);
 			cx18_av_write4(cx, 0x90c, 0x08014faa);
+
+			/* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x11205fff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
+			 *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa11193f8);
 			break;
 			break;
 		}
 		}
 	} else {
 	} else {
@@ -82,18 +120,31 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 			cx18_av_write4(cx, 0x108, 0x1e08040f);
 			cx18_av_write4(cx, 0x108, 0x1e08040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x012a0869);
+			/* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */
+			cx18_av_write4(cx, 0x110, 0x012a0863);
 
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.0000 = 32000/32000 */
 			cx18_av_write4(cx, 0x8f8, 0x08010000);
 			cx18_av_write4(cx, 0x8f8, 0x08010000);
 
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
 			cx18_av_write4(cx, 0x900, 0x08020000);
 			cx18_av_write4(cx, 0x900, 0x08020000);
 			cx18_av_write4(cx, 0x904, 0x08020000);
 			cx18_av_write4(cx, 0x904, 0x08020000);
 			cx18_av_write4(cx, 0x90c, 0x08020000);
 			cx18_av_write4(cx, 0x90c, 0x08020000);
 
 
 			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
 			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
 			cx18_av_write(cx, 0x127, 0x54);
 			cx18_av_write(cx, 0x127, 0x54);
+
+			/* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x11201fff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
+			 *  ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa10d2ef8);
 			break;
 			break;
 
 
 		case 44100:
 		case 44100:
@@ -101,15 +152,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 			cx18_av_write4(cx, 0x108, 0x1809040f);
 			cx18_av_write4(cx, 0x108, 0x1809040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x00ec6bd6);
+			/* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */
+			cx18_av_write4(cx, 0x110, 0x00ec6bce);
 
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.60cd = 44100/32000 */
 			cx18_av_write4(cx, 0x8f8, 0x080160cd);
 			cx18_av_write4(cx, 0x8f8, 0x080160cd);
 
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
 			cx18_av_write4(cx, 0x900, 0x08017385);
 			cx18_av_write4(cx, 0x900, 0x08017385);
 			cx18_av_write4(cx, 0x904, 0x08017385);
 			cx18_av_write4(cx, 0x904, 0x08017385);
 			cx18_av_write4(cx, 0x90c, 0x08017385);
 			cx18_av_write4(cx, 0x90c, 0x08017385);
+
+			/* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x112061ff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
+			 *  ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa11d4bf8);
 			break;
 			break;
 
 
 		case 48000:
 		case 48000:
@@ -117,15 +181,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 			cx18_av_write4(cx, 0x108, 0x180a040f);
 			cx18_av_write4(cx, 0x108, 0x180a040f);
 
 
 			/* AUX_PLL_FRAC */
 			/* AUX_PLL_FRAC */
-			cx18_av_write4(cx, 0x110, 0x0098d6e5);
+			/* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */
+			cx18_av_write4(cx, 0x110, 0x0098d6dd);
 
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.8000 = 48000/32000 */
 			cx18_av_write4(cx, 0x8f8, 0x08018000);
 			cx18_av_write4(cx, 0x8f8, 0x08018000);
 
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.5555 = 2 * (32000/48000) */
 			cx18_av_write4(cx, 0x900, 0x08015555);
 			cx18_av_write4(cx, 0x900, 0x08015555);
 			cx18_av_write4(cx, 0x904, 0x08015555);
 			cx18_av_write4(cx, 0x904, 0x08015555);
 			cx18_av_write4(cx, 0x90c, 0x08015555);
 			cx18_av_write4(cx, 0x90c, 0x08015555);
+
+			/* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
+			cx18_av_write4(cx, 0x12c, 0x11203fff);
+
+			/*
+			 * EN_AV_LOCK = 1
+			 * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
+			 *  ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
+			 */
+			cx18_av_write4(cx, 0x128, 0xa11193f8);
 			break;
 			break;
 		}
 		}
 	}
 	}

+ 1 - 0
drivers/media/video/cx18/cx18-driver.h

@@ -46,6 +46,7 @@
 #include <linux/dvb/video.h>
 #include <linux/dvb/video.h>
 #include <linux/dvb/audio.h>
 #include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tuner.h>
 #include <media/tuner.h>
 #include "cx18-mailbox.h"
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
 #include "cx18-av-core.h"

+ 13 - 41
drivers/media/video/cx18/cx18-firmware.c

@@ -86,10 +86,6 @@
 
 
 #define CX18_DSP0_INTERRUPT_MASK     	0xd0004C
 #define CX18_DSP0_INTERRUPT_MASK     	0xd0004C
 
 
-/* Encoder/decoder firmware sizes */
-#define CX18_FW_CPU_SIZE 		(158332)
-#define CX18_FW_APU_SIZE 		(141200)
-
 #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
 #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
 #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
 #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
 
 
@@ -100,35 +96,22 @@ struct cx18_apu_rom_seghdr {
 	u32 size;
 	u32 size;
 };
 };
 
 
-static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size)
+static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
 {
 {
 	const struct firmware *fw = NULL;
 	const struct firmware *fw = NULL;
-	int retries = 3;
 	int i, j;
 	int i, j;
+	unsigned size;
 	u32 __iomem *dst = (u32 __iomem *)mem;
 	u32 __iomem *dst = (u32 __iomem *)mem;
 	const u32 *src;
 	const u32 *src;
 
 
-retry:
-	if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
-		CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n",
-				fn, size);
+	if (request_firmware(&fw, fn, &cx->dev->dev)) {
+		CX18_ERR("Unable to open firmware %s\n", fn);
 		CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
 		CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
 	src = (const u32 *)fw->data;
 	src = (const u32 *)fw->data;
 
 
-	if (fw->size != size) {
-		/* Due to race conditions in firmware loading (esp. with
-		   udev <0.95) the wrong file was sometimes loaded. So we check
-		   filesizes to see if at least the right-sized file was
-		   loaded. If not, then we retry. */
-		CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
-				fn, size, fw->size);
-		release_firmware(fw);
-		retries--;
-		goto retry;
-	}
 	for (i = 0; i < fw->size; i += 4096) {
 	for (i = 0; i < fw->size; i += 4096) {
 		setup_page(i);
 		setup_page(i);
 		for (j = i; j < fw->size && j < i + 4096; j += 4) {
 		for (j = i; j < fw->size && j < i + 4096; j += 4) {
@@ -145,15 +128,16 @@ retry:
 	}
 	}
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 		CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
 		CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
+	size = fw->size;
 	release_firmware(fw);
 	release_firmware(fw);
 	return size;
 	return size;
 }
 }
 
 
-static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size)
+static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
 {
 {
 	const struct firmware *fw = NULL;
 	const struct firmware *fw = NULL;
-	int retries = 3;
 	int i, j;
 	int i, j;
+	unsigned size;
 	const u32 *src;
 	const u32 *src;
 	struct cx18_apu_rom_seghdr seghdr;
 	struct cx18_apu_rom_seghdr seghdr;
 	const u8 *vers;
 	const u8 *vers;
@@ -161,10 +145,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
 	u32 apu_version = 0;
 	u32 apu_version = 0;
 	int sz;
 	int sz;
 
 
-retry:
-	if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
-		CX18_ERR("unable to open firmware %s (must be %ld bytes)\n",
-				fn, size);
+	if (request_firmware(&fw, fn, &cx->dev->dev)) {
+		CX18_ERR("unable to open firmware %s\n", fn);
 		CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
 		CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
@@ -173,19 +155,8 @@ retry:
 	vers = fw->data + sizeof(seghdr);
 	vers = fw->data + sizeof(seghdr);
 	sz = fw->size;
 	sz = fw->size;
 
 
-	if (fw->size != size) {
-		/* Due to race conditions in firmware loading (esp. with
-		   udev <0.95) the wrong file was sometimes loaded. So we check
-		   filesizes to see if at least the right-sized file was
-		   loaded. If not, then we retry. */
-		CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
-			       fn, size, fw->size);
-		release_firmware(fw);
-		retries--;
-		goto retry;
-	}
 	apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
 	apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
-	while (offset + sizeof(seghdr) < size) {
+	while (offset + sizeof(seghdr) < fw->size) {
 		/* TODO: byteswapping */
 		/* TODO: byteswapping */
 		memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
 		memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
 		offset += sizeof(seghdr);
 		offset += sizeof(seghdr);
@@ -215,6 +186,7 @@ retry:
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 		CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
 		CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
 				fn, apu_version, fw->size);
 				fn, apu_version, fw->size);
+	size = fw->size;
 	release_firmware(fw);
 	release_firmware(fw);
 	/* Clear bit0 for APU to start from 0 */
 	/* Clear bit0 for APU to start from 0 */
 	write_reg(read_reg(0xc72030) & ~1, 0xc72030);
 	write_reg(read_reg(0xc72030) & ~1, 0xc72030);
@@ -340,7 +312,7 @@ int cx18_firmware_init(struct cx18 *cx)
 	/* Only if the processor is not running */
 	/* Only if the processor is not running */
 	if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
 	if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
 		int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
 		int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
-			       cx->enc_mem, cx, CX18_FW_APU_SIZE);
+			       cx->enc_mem, cx);
 
 
 		write_enc(0xE51FF004, 0);
 		write_enc(0xE51FF004, 0);
 		write_enc(0xa00000, 4);  /* todo: not hardcoded */
 		write_enc(0xa00000, 4);  /* todo: not hardcoded */
@@ -348,7 +320,7 @@ int cx18_firmware_init(struct cx18 *cx)
 		cx18_msleep_timeout(500, 0);
 		cx18_msleep_timeout(500, 0);
 
 
 		sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
 		sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
-					cx->enc_mem, cx, CX18_FW_CPU_SIZE);
+					cx->enc_mem, cx);
 
 
 		if (sz > 0) {
 		if (sz > 0) {
 			int retries = 0;
 			int retries = 0;

+ 48 - 44
drivers/media/video/cx18/cx18-ioctl.c

@@ -787,50 +787,54 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 	return res;
 	return res;
 }
 }
 
 
-void cx18_set_funcs(struct video_device *vdev)
-{
-	vdev->vidioc_querycap                = cx18_querycap;
-	vdev->vidioc_g_priority              = cx18_g_priority;
-	vdev->vidioc_s_priority              = cx18_s_priority;
-	vdev->vidioc_s_audio                 = cx18_s_audio;
-	vdev->vidioc_g_audio                 = cx18_g_audio;
-	vdev->vidioc_enumaudio               = cx18_enumaudio;
-	vdev->vidioc_enum_input              = cx18_enum_input;
-	vdev->vidioc_cropcap                 = cx18_cropcap;
-	vdev->vidioc_s_crop                  = cx18_s_crop;
-	vdev->vidioc_g_crop                  = cx18_g_crop;
-	vdev->vidioc_g_input                 = cx18_g_input;
-	vdev->vidioc_s_input                 = cx18_s_input;
-	vdev->vidioc_g_frequency             = cx18_g_frequency;
-	vdev->vidioc_s_frequency             = cx18_s_frequency;
-	vdev->vidioc_s_tuner                 = cx18_s_tuner;
-	vdev->vidioc_g_tuner                 = cx18_g_tuner;
-	vdev->vidioc_g_enc_index             = cx18_g_enc_index;
-	vdev->vidioc_g_std                   = cx18_g_std;
-	vdev->vidioc_s_std                   = cx18_s_std;
-	vdev->vidioc_log_status              = cx18_log_status;
-	vdev->vidioc_enum_fmt_vid_cap        = cx18_enum_fmt_vid_cap;
-	vdev->vidioc_encoder_cmd             = cx18_encoder_cmd;
-	vdev->vidioc_try_encoder_cmd         = cx18_try_encoder_cmd;
-	vdev->vidioc_g_fmt_vid_cap           = cx18_g_fmt_vid_cap;
-	vdev->vidioc_g_fmt_vbi_cap           = cx18_g_fmt_vbi_cap;
-	vdev->vidioc_g_fmt_sliced_vbi_cap    = cx18_g_fmt_sliced_vbi_cap;
-	vdev->vidioc_s_fmt_vid_cap           = cx18_s_fmt_vid_cap;
-	vdev->vidioc_s_fmt_vbi_cap           = cx18_s_fmt_vbi_cap;
-	vdev->vidioc_s_fmt_sliced_vbi_cap    = cx18_s_fmt_sliced_vbi_cap;
-	vdev->vidioc_try_fmt_vid_cap         = cx18_try_fmt_vid_cap;
-	vdev->vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap;
-	vdev->vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap;
-	vdev->vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap;
-	vdev->vidioc_g_chip_ident            = cx18_g_chip_ident;
+static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
+	.vidioc_querycap                = cx18_querycap,
+	.vidioc_g_priority              = cx18_g_priority,
+	.vidioc_s_priority              = cx18_s_priority,
+	.vidioc_s_audio                 = cx18_s_audio,
+	.vidioc_g_audio                 = cx18_g_audio,
+	.vidioc_enumaudio               = cx18_enumaudio,
+	.vidioc_enum_input              = cx18_enum_input,
+	.vidioc_cropcap                 = cx18_cropcap,
+	.vidioc_s_crop                  = cx18_s_crop,
+	.vidioc_g_crop                  = cx18_g_crop,
+	.vidioc_g_input                 = cx18_g_input,
+	.vidioc_s_input                 = cx18_s_input,
+	.vidioc_g_frequency             = cx18_g_frequency,
+	.vidioc_s_frequency             = cx18_s_frequency,
+	.vidioc_s_tuner                 = cx18_s_tuner,
+	.vidioc_g_tuner                 = cx18_g_tuner,
+	.vidioc_g_enc_index             = cx18_g_enc_index,
+	.vidioc_g_std                   = cx18_g_std,
+	.vidioc_s_std                   = cx18_s_std,
+	.vidioc_log_status              = cx18_log_status,
+	.vidioc_enum_fmt_vid_cap        = cx18_enum_fmt_vid_cap,
+	.vidioc_encoder_cmd             = cx18_encoder_cmd,
+	.vidioc_try_encoder_cmd         = cx18_try_encoder_cmd,
+	.vidioc_g_fmt_vid_cap           = cx18_g_fmt_vid_cap,
+	.vidioc_g_fmt_vbi_cap           = cx18_g_fmt_vbi_cap,
+	.vidioc_g_fmt_sliced_vbi_cap    = cx18_g_fmt_sliced_vbi_cap,
+	.vidioc_s_fmt_vid_cap           = cx18_s_fmt_vid_cap,
+	.vidioc_s_fmt_vbi_cap           = cx18_s_fmt_vbi_cap,
+	.vidioc_s_fmt_sliced_vbi_cap    = cx18_s_fmt_sliced_vbi_cap,
+	.vidioc_try_fmt_vid_cap         = cx18_try_fmt_vid_cap,
+	.vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
+	.vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
+	.vidioc_g_chip_ident            = cx18_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	vdev->vidioc_g_register              = cx18_g_register;
-	vdev->vidioc_s_register              = cx18_s_register;
+	.vidioc_g_register              = cx18_g_register,
+	.vidioc_s_register              = cx18_s_register,
 #endif
 #endif
-	vdev->vidioc_default                 = cx18_default;
-	vdev->vidioc_queryctrl               = cx18_queryctrl;
-	vdev->vidioc_querymenu               = cx18_querymenu;
-	vdev->vidioc_g_ext_ctrls             = cx18_g_ext_ctrls;
-	vdev->vidioc_s_ext_ctrls             = cx18_s_ext_ctrls;
-	vdev->vidioc_try_ext_ctrls           = cx18_try_ext_ctrls;
+	.vidioc_default                 = cx18_default,
+	.vidioc_queryctrl               = cx18_queryctrl,
+	.vidioc_querymenu               = cx18_querymenu,
+	.vidioc_g_ext_ctrls             = cx18_g_ext_ctrls,
+	.vidioc_s_ext_ctrls             = cx18_s_ext_ctrls,
+	.vidioc_try_ext_ctrls           = cx18_try_ext_ctrls,
+};
+
+void cx18_set_funcs(struct video_device *vdev)
+{
+	vdev->ioctl_ops = &cx18_ioctl_ops;
 }
 }

+ 1 - 4
drivers/media/video/cx18/cx18-streams.c

@@ -187,14 +187,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	s->v4l2dev->type =
-		VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
-		VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
 	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
 	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
 			cx->num);
 			cx->num);
 
 
 	s->v4l2dev->minor = minor;
 	s->v4l2dev->minor = minor;
-	s->v4l2dev->dev = &cx->dev->dev;
+	s->v4l2dev->parent = &cx->dev->dev;
 	s->v4l2dev->fops = cx18_stream_info[type].fops;
 	s->v4l2dev->fops = cx18_stream_info[type].fops;
 	s->v4l2dev->release = video_device_release;
 	s->v4l2dev->release = video_device_release;
 	s->v4l2dev->tvnorms = V4L2_STD_ALL;
 	s->v4l2dev->tvnorms = V4L2_STD_ALL;

+ 0 - 2
drivers/media/video/cx23885/Kconfig

@@ -1,9 +1,7 @@
 config VIDEO_CX23885
 config VIDEO_CX23885
 	tristate "Conexant cx23885 (2388x successor) support"
 	tristate "Conexant cx23885 (2388x successor) support"
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_BTCX
 	select VIDEO_TUNER
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM

+ 10 - 9
drivers/media/video/cx23885/cx23885-417.c

@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
 #include <media/cx2341x.h>
 
 
 #include "cx23885.h"
 #include "cx23885.h"
@@ -1699,14 +1700,7 @@ static struct file_operations mpeg_fops = {
 	.llseek        = no_llseek,
 	.llseek        = no_llseek,
 };
 };
 
 
-static struct video_device cx23885_mpeg_template = {
-	.name          = "cx23885",
-	.type          = VID_TYPE_CAPTURE |
-				VID_TYPE_TUNER |
-				VID_TYPE_SCALES |
-				VID_TYPE_MPEG_ENCODER,
-	.fops          = &mpeg_fops,
-	.minor         = -1,
+static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_std		 = vidioc_s_std,
 	.vidioc_s_std		 = vidioc_s_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
 	.vidioc_g_input		 = vidioc_g_input,
@@ -1735,6 +1729,13 @@ static struct video_device cx23885_mpeg_template = {
 	.vidioc_queryctrl	 = vidioc_queryctrl,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
 };
 };
 
 
+static struct video_device cx23885_mpeg_template = {
+	.name          = "cx23885",
+	.fops          = &mpeg_fops,
+	.ioctl_ops     = &mpeg_ioctl_ops,
+	.minor         = -1,
+};
+
 void cx23885_417_unregister(struct cx23885_dev *dev)
 void cx23885_417_unregister(struct cx23885_dev *dev)
 {
 {
 	dprintk(1, "%s()\n", __func__);
 	dprintk(1, "%s()\n", __func__);
@@ -1766,7 +1767,7 @@ static struct video_device *cx23885_video_dev_alloc(
 	vfd->minor   = -1;
 	vfd->minor   = -1;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, cx23885_boards[tsport->dev->board].name);
 		type, cx23885_boards[tsport->dev->board].name);
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
 	return vfd;
 	return vfd;
 }
 }

+ 42 - 12
drivers/media/video/cx23885/cx23885-cards.c

@@ -145,6 +145,7 @@ struct cx23885_board cx23885_boards[] = {
 	},
 	},
 	[CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
 	[CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
 		.name		= "DViCO FusionHDTV7 Dual Express",
 		.name		= "DViCO FusionHDTV7 Dual Express",
+		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
 	},
 };
 };
@@ -325,25 +326,41 @@ int cx23885_tuner_callback(void *priv, int command, int arg)
 {
 {
 	struct cx23885_i2c *bus = priv;
 	struct cx23885_i2c *bus = priv;
 	struct cx23885_dev *dev = bus->dev;
 	struct cx23885_dev *dev = bus->dev;
+	u32 bitmask = 0;
+
+	if (command != 0) {
+		printk(KERN_ERR "%s(): Unknown command 0x%x.\n",
+			__func__, command);
+		return -EINVAL;
+	}
 
 
 	switch(dev->board) {
 	switch(dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
-		if(command == 0) {	/* Tuner Reset Command from xc5000 */
-			/* Drive the tuner into reset and out */
-			cx_clear(GP0_IO, 0x00000004);
-			mdelay(200);
-			cx_set(GP0_IO, 0x00000004);
-			return 0;
-		}
-		else {
-			printk(KERN_ERR
-				"%s(): Unknow command.\n", __func__);
-			return -EINVAL;
+		/* Tuner Reset Command from xc5000 */
+		if (command == 0)
+			bitmask = 0x04;
+		break;
+	case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+		if (command == 0) {
+
+			/* Two identical tuners on two different i2c buses,
+			 * we need to reset the correct gpio. */
+			if (bus->nr == 0)
+				bitmask = 0x01;
+			else if (bus->nr == 1)
+				bitmask = 0x04;
 		}
 		}
 		break;
 		break;
 	}
 	}
 
 
-	return 0; /* Should never be here */
+	if (bitmask) {
+		/* Drive the tuner into reset and back out */
+		cx_clear(GP0_IO, bitmask);
+		mdelay(200);
+		cx_set(GP0_IO, bitmask);
+	}
+
+	return 0;
 }
 }
 
 
 void cx23885_gpio_setup(struct cx23885_dev *dev)
 void cx23885_gpio_setup(struct cx23885_dev *dev)
@@ -435,6 +452,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		mdelay(20);
 		mdelay(20);
 		cx_set(GP0_IO, 0x00050005);
 		cx_set(GP0_IO, 0x00050005);
 		break;
 		break;
+	case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+		/* GPIO-0 xc5000 tuner reset i2c bus 0 */
+		/* GPIO-1 s5h1409 demod reset i2c bus 0 */
+		/* GPIO-2 xc5000 tuner reset i2c bus 1 */
+		/* GPIO-3 s5h1409 demod reset i2c bus 0 */
+
+		/* Put the parts into reset and back */
+		cx_set(GP0_IO, 0x000f0000);
+		mdelay(20);
+		cx_clear(GP0_IO, 0x0000000f);
+		mdelay(20);
+		cx_set(GP0_IO, 0x000f000f);
+		break;
 	}
 	}
 }
 }
 
 

+ 139 - 8
drivers/media/video/cx23885/cx23885-core.c

@@ -76,6 +76,117 @@ LIST_HEAD(cx23885_devlist);
  * 0x00010ea0 0x00010xxx Free
  * 0x00010ea0 0x00010xxx Free
  */
  */
 
 
+static struct sram_channel cx23885_sram_channels[] = {
+	[SRAM_CH01] = {
+		.name		= "VID A",
+		.cmds_start	= 0x10000,
+		.ctrl_start	= 0x10380,
+		.cdt		= 0x104c0,
+		.fifo_start	= 0x40,
+		.fifo_size	= 0x2800,
+		.ptr1_reg	= DMA1_PTR1,
+		.ptr2_reg	= DMA1_PTR2,
+		.cnt1_reg	= DMA1_CNT1,
+		.cnt2_reg	= DMA1_CNT2,
+	},
+	[SRAM_CH02] = {
+		.name		= "ch2",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA2_PTR1,
+		.ptr2_reg	= DMA2_PTR2,
+		.cnt1_reg	= DMA2_CNT1,
+		.cnt2_reg	= DMA2_CNT2,
+	},
+	[SRAM_CH03] = {
+		.name		= "TS1 B",
+		.cmds_start	= 0x100A0,
+		.ctrl_start	= 0x10400,
+		.cdt		= 0x10580,
+		.fifo_start	= 0x5000,
+		.fifo_size	= 0x1000,
+		.ptr1_reg	= DMA3_PTR1,
+		.ptr2_reg	= DMA3_PTR2,
+		.cnt1_reg	= DMA3_CNT1,
+		.cnt2_reg	= DMA3_CNT2,
+	},
+	[SRAM_CH04] = {
+		.name		= "ch4",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA4_PTR1,
+		.ptr2_reg	= DMA4_PTR2,
+		.cnt1_reg	= DMA4_CNT1,
+		.cnt2_reg	= DMA4_CNT2,
+	},
+	[SRAM_CH05] = {
+		.name		= "ch5",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA5_PTR1,
+		.ptr2_reg	= DMA5_PTR2,
+		.cnt1_reg	= DMA5_CNT1,
+		.cnt2_reg	= DMA5_CNT2,
+	},
+	[SRAM_CH06] = {
+		.name		= "TS2 C",
+		.cmds_start	= 0x10140,
+		.ctrl_start	= 0x10440,
+		.cdt		= 0x105e0,
+		.fifo_start	= 0x6000,
+		.fifo_size	= 0x1000,
+		.ptr1_reg	= DMA5_PTR1,
+		.ptr2_reg	= DMA5_PTR2,
+		.cnt1_reg	= DMA5_CNT1,
+		.cnt2_reg	= DMA5_CNT2,
+	},
+	[SRAM_CH07] = {
+		.name		= "ch7",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA6_PTR1,
+		.ptr2_reg	= DMA6_PTR2,
+		.cnt1_reg	= DMA6_CNT1,
+		.cnt2_reg	= DMA6_CNT2,
+	},
+	[SRAM_CH08] = {
+		.name		= "ch8",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA7_PTR1,
+		.ptr2_reg	= DMA7_PTR2,
+		.cnt1_reg	= DMA7_CNT1,
+		.cnt2_reg	= DMA7_CNT2,
+	},
+	[SRAM_CH09] = {
+		.name		= "ch9",
+		.cmds_start	= 0x0,
+		.ctrl_start	= 0x0,
+		.cdt		= 0x0,
+		.fifo_start	= 0x0,
+		.fifo_size	= 0x0,
+		.ptr1_reg	= DMA8_PTR1,
+		.ptr2_reg	= DMA8_PTR2,
+		.cnt1_reg	= DMA8_CNT1,
+		.cnt2_reg	= DMA8_CNT2,
+	},
+};
+
 static struct sram_channel cx23887_sram_channels[] = {
 static struct sram_channel cx23887_sram_channels[] = {
 	[SRAM_CH01] = {
 	[SRAM_CH01] = {
 		.name		= "VID A",
 		.name		= "VID A",
@@ -104,8 +215,8 @@ static struct sram_channel cx23887_sram_channels[] = {
 	[SRAM_CH03] = {
 	[SRAM_CH03] = {
 		.name		= "TS1 B",
 		.name		= "TS1 B",
 		.cmds_start	= 0x100A0,
 		.cmds_start	= 0x100A0,
-		.ctrl_start	= 0x10780,
-		.cdt		= 0x10400,
+		.ctrl_start	= 0x10630,
+		.cdt		= 0x10870,
 		.fifo_start	= 0x5000,
 		.fifo_start	= 0x5000,
 		.fifo_size	= 0x1000,
 		.fifo_size	= 0x1000,
 		.ptr1_reg	= DMA3_PTR1,
 		.ptr1_reg	= DMA3_PTR1,
@@ -140,7 +251,7 @@ static struct sram_channel cx23887_sram_channels[] = {
 	[SRAM_CH06] = {
 	[SRAM_CH06] = {
 		.name		= "TS2 C",
 		.name		= "TS2 C",
 		.cmds_start	= 0x10140,
 		.cmds_start	= 0x10140,
-		.ctrl_start	= 0x10680,
+		.ctrl_start	= 0x10670,
 		.cdt		= 0x108d0,
 		.cdt		= 0x108d0,
 		.fifo_start	= 0x6000,
 		.fifo_start	= 0x6000,
 		.fifo_size	= 0x1000,
 		.fifo_size	= 0x1000,
@@ -460,6 +571,7 @@ static void cx23885_reset(struct cx23885_dev *dev)
 	cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
 	cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
 	cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
 	cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
 	cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
 	cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
+	cx_write(PAD_CTRL, 0x00500300);
 
 
 	mdelay(100);
 	mdelay(100);
 
 
@@ -625,7 +737,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	atomic_inc(&dev->refcount);
 	atomic_inc(&dev->refcount);
 
 
 	dev->nr = cx23885_devcount++;
 	dev->nr = cx23885_devcount++;
-	dev->sram_channels = cx23887_sram_channels;
 	sprintf(dev->name, "cx23885[%d]", dev->nr);
 	sprintf(dev->name, "cx23885[%d]", dev->nr);
 
 
 	mutex_lock(&devlist);
 	mutex_lock(&devlist);
@@ -637,11 +748,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 		dev->bridge = CX23885_BRIDGE_887;
 		dev->bridge = CX23885_BRIDGE_887;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 25000000;
 		dev->clk_freq = 25000000;
+		dev->sram_channels = cx23887_sram_channels;
 	} else
 	} else
 	if(dev->pci->device == 0x8852) {
 	if(dev->pci->device == 0x8852) {
 		dev->bridge = CX23885_BRIDGE_885;
 		dev->bridge = CX23885_BRIDGE_885;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 28000000;
 		dev->clk_freq = 28000000;
+		dev->sram_channels = cx23885_sram_channels;
 	} else
 	} else
 		BUG();
 		BUG();
 
 
@@ -1010,8 +1123,9 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
 		port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
 		port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
 	dprintk(1, "%s() dma_ctl(0x%08X)        0x%08x\n", __func__,
 	dprintk(1, "%s() dma_ctl(0x%08X)        0x%08x\n", __func__,
 		port->reg_dma_ctl, cx_read(port->reg_dma_ctl));
 		port->reg_dma_ctl, cx_read(port->reg_dma_ctl));
-	dprintk(1, "%s() src_sel(0x%08X)        0x%08x\n", __func__,
-		port->reg_src_sel, cx_read(port->reg_src_sel));
+	if (port->reg_src_sel)
+		dprintk(1, "%s() src_sel(0x%08X)        0x%08x\n", __func__,
+			port->reg_src_sel, cx_read(port->reg_src_sel));
 	dprintk(1, "%s() lngth(0x%08X)          0x%08x\n", __func__,
 	dprintk(1, "%s() lngth(0x%08X)          0x%08x\n", __func__,
 		port->reg_lngth, cx_read(port->reg_lngth));
 		port->reg_lngth, cx_read(port->reg_lngth));
 	dprintk(1, "%s() hw_sop_ctrl(0x%08X)    0x%08x\n", __func__,
 	dprintk(1, "%s() hw_sop_ctrl(0x%08X)    0x%08x\n", __func__,
@@ -1042,6 +1156,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
 	dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
 		buf->vb.width, buf->vb.height, buf->vb.field);
 		buf->vb.width, buf->vb.height, buf->vb.field);
 
 
+	/* Stop the fifo and risc engine for this port */
+	cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
+
 	/* setup fifo + format */
 	/* setup fifo + format */
 	cx23885_sram_channel_setup(dev,
 	cx23885_sram_channel_setup(dev,
 				   &dev->sram_channels[ port->sram_chno ],
 				   &dev->sram_channels[ port->sram_chno ],
@@ -1083,7 +1200,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	cx_write(port->reg_gpcnt_ctl, 3);
 	cx_write(port->reg_gpcnt_ctl, 3);
 	q->count = 1;
 	q->count = 1;
 
 
-	if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) {
+	/* Set VIDB pins to input */
+	if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
+		reg = cx_read(PAD_CTRL);
+		reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */
+		cx_write(PAD_CTRL, reg);
+	}
+
+	/* Set VIDC pins to input */
+	if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
+		reg = cx_read(PAD_CTRL);
+		reg &= ~0x4; /* Clear TS2_SOP_OE */
+		cx_write(PAD_CTRL, reg);
+	}
+
+	if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
 
 
 		reg = cx_read(PAD_CTRL);
 		reg = cx_read(PAD_CTRL);
 		reg = reg & ~0x1;    /* Clear TS1_OE */
 		reg = reg & ~0x1;    /* Clear TS1_OE */
@@ -1133,7 +1264,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
 	cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
 	cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
 	cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
 	cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
 
 
-	if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) {
+	if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
 
 
 		reg = cx_read(PAD_CTRL);
 		reg = cx_read(PAD_CTRL);
 
 

+ 11 - 8
drivers/media/video/cx23885/cx23885-video.c

@@ -33,6 +33,7 @@
 
 
 #include "cx23885.h"
 #include "cx23885.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
 /* Include V4L1 specific functions. Should be removed soon */
@@ -326,7 +327,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
 		return NULL;
 		return NULL;
 	*vfd = *template;
 	*vfd = *template;
 	vfd->minor   = -1;
 	vfd->minor   = -1;
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 dev->name, type, cx23885_boards[dev->board].name);
 		 dev->name, type, cx23885_boards[dev->board].name);
@@ -1433,12 +1434,7 @@ static const struct file_operations video_fops = {
 	.llseek        = no_llseek,
 	.llseek        = no_llseek,
 };
 };
 
 
-static struct video_device cx23885_vbi_template;
-static struct video_device cx23885_video_template = {
-	.name                 = "cx23885-video",
-	.type                 = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
-	.fops                 = &video_fops,
-	.minor                = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1471,6 +1467,14 @@ static struct video_device cx23885_video_template = {
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
 	.vidioc_s_register    = vidioc_s_register,
 #endif
 #endif
+};
+
+static struct video_device cx23885_vbi_template;
+static struct video_device cx23885_video_template = {
+	.name                 = "cx23885-video",
+	.fops                 = &video_fops,
+	.minor                = -1,
+	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX23885_NORMS,
 	.tvnorms              = CX23885_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
 };
@@ -1512,7 +1516,6 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	memcpy(&cx23885_vbi_template, &cx23885_video_template,
 	memcpy(&cx23885_vbi_template, &cx23885_video_template,
 		sizeof(cx23885_vbi_template));
 		sizeof(cx23885_vbi_template));
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
-	cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
 
 
 	dev->tvnorm = cx23885_video_template.current_norm;
 	dev->tvnorm = cx23885_video_template.current_norm;
 
 

+ 0 - 2
drivers/media/video/cx25840/Kconfig

@@ -1,8 +1,6 @@
 config VIDEO_CX25840
 config VIDEO_CX25840
 	tristate "Conexant CX2584x audio/video decoders"
 	tristate "Conexant CX2584x audio/video decoders"
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
-	depends on HOTPLUG # due to FW_LOADER
-	select FW_LOADER
 	---help---
 	---help---
 	  Support for the Conexant CX2584x audio/video decoders.
 	  Support for the Conexant CX2584x audio/video decoders.
 
 

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

@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
 
 
 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
 
-int cx25840_debug;
+static int cx25840_debug;
 
 
 module_param_named(debug,cx25840_debug, int, 0644);
 module_param_named(debug,cx25840_debug, int, 0644);
 
 

+ 0 - 2
drivers/media/video/cx25840/cx25840-core.h

@@ -24,8 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 
 
-extern int cx25840_debug;
-
 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
    present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
    present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
    certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
    certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The

+ 1 - 2
drivers/media/video/cx88/Kconfig

@@ -33,9 +33,8 @@ config VIDEO_CX88_ALSA
 
 
 config VIDEO_CX88_BLACKBIRD
 config VIDEO_CX88_BLACKBIRD
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
-	depends on VIDEO_CX88 && HOTPLUG
+	depends on VIDEO_CX88
 	select VIDEO_CX2341X
 	select VIDEO_CX2341X
-	select FW_LOADER
 	---help---
 	---help---
 	  This adds support for MPEG encoder cards based on the
 	  This adds support for MPEG encoder cards based on the
 	  Blackbird reference design, using the Conexant 2388x
 	  Blackbird reference design, using the Conexant 2388x

+ 9 - 6
drivers/media/video/cx88/cx88-blackbird.c

@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
 #include <media/cx2341x.h>
 
 
 #include "cx88.h"
 #include "cx88.h"
@@ -1174,12 +1175,7 @@ static const struct file_operations mpeg_fops =
 	.llseek        = no_llseek,
 	.llseek        = no_llseek,
 };
 };
 
 
-static struct video_device cx8802_mpeg_template =
-{
-	.name                 = "cx8802",
-	.type                 = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER,
-	.fops                 = &mpeg_fops,
-	.minor                = -1,
+static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_querymenu     = vidioc_querymenu,
 	.vidioc_querymenu     = vidioc_querymenu,
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
@@ -1207,6 +1203,13 @@ static struct video_device cx8802_mpeg_template =
 	.vidioc_g_tuner       = vidioc_g_tuner,
 	.vidioc_g_tuner       = vidioc_g_tuner,
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_s_std         = vidioc_s_std,
 	.vidioc_s_std         = vidioc_s_std,
+};
+
+static struct video_device cx8802_mpeg_template = {
+	.name                 = "cx8802",
+	.fops                 = &mpeg_fops,
+	.ioctl_ops 	      = &mpeg_ioctl_ops,
+	.minor                = -1,
 	.tvnorms              = CX88_NORMS,
 	.tvnorms              = CX88_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
 };

+ 1 - 1
drivers/media/video/cx88/cx88-cards.c

@@ -1348,7 +1348,7 @@ static const struct cx88_board cx88_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,
-		.audio_chip     = AUDIO_CHIP_WM8775,
+		.audio_chip     = V4L2_IDENT_WM8775,
 		.input		= {{
 		.input		= {{
 			.type   = CX88_VMUX_TELEVISION,
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
 			.vmux   = 0,

+ 2 - 1
drivers/media/video/cx88/cx88-core.c

@@ -40,6 +40,7 @@
 
 
 #include "cx88.h"
 #include "cx88.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -1006,7 +1007,7 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
 		return NULL;
 		return NULL;
 	*vfd = *template;
 	*vfd = *template;
 	vfd->minor   = -1;
 	vfd->minor   = -1;
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 core->name, type, core->board.name);
 		 core->name, type, core->board.name);

+ 21 - 16
drivers/media/video/cx88/cx88-video.c

@@ -39,6 +39,7 @@
 
 
 #include "cx88.h"
 #include "cx88.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
 /* Include V4L1 specific functions. Should be removed soon */
@@ -447,7 +448,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
 		   the initialization. Some boards may use different
 		   the initialization. Some boards may use different
 		   routes for different inputs. HVR-1300 surely does */
 		   routes for different inputs. HVR-1300 surely does */
 		if (core->board.audio_chip &&
 		if (core->board.audio_chip &&
-		    core->board.audio_chip == AUDIO_CHIP_WM8775) {
+		    core->board.audio_chip == V4L2_IDENT_WM8775) {
 			struct v4l2_routing route;
 			struct v4l2_routing route;
 
 
 			route.input = INPUT(input).audioroute;
 			route.input = INPUT(input).audioroute;
@@ -1682,13 +1683,7 @@ static const struct file_operations video_fops =
 	.llseek        = no_llseek,
 	.llseek        = no_llseek,
 };
 };
 
 
-static struct video_device cx8800_vbi_template;
-static struct video_device cx8800_video_template =
-{
-	.name                 = "cx8800-video",
-	.type                 = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
-	.fops                 = &video_fops,
-	.minor                = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1721,6 +1716,15 @@ static struct video_device cx8800_video_template =
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
 	.vidioc_s_register    = vidioc_s_register,
 #endif
 #endif
+};
+
+static struct video_device cx8800_vbi_template;
+
+static struct video_device cx8800_video_template = {
+	.name                 = "cx8800-video",
+	.fops                 = &video_fops,
+	.minor                = -1,
+	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX88_NORMS,
 	.tvnorms              = CX88_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
 };
@@ -1735,12 +1739,7 @@ static const struct file_operations radio_fops =
 	.llseek        = no_llseek,
 	.llseek        = no_llseek,
 };
 };
 
 
-static struct video_device cx8800_radio_template =
-{
-	.name                 = "cx8800-radio",
-	.type                 = VID_TYPE_TUNER,
-	.fops                 = &radio_fops,
-	.minor                = -1,
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 	.vidioc_querycap      = radio_querycap,
 	.vidioc_querycap      = radio_querycap,
 	.vidioc_g_tuner       = radio_g_tuner,
 	.vidioc_g_tuner       = radio_g_tuner,
 	.vidioc_enum_input    = radio_enum_input,
 	.vidioc_enum_input    = radio_enum_input,
@@ -1759,6 +1758,13 @@ static struct video_device cx8800_radio_template =
 #endif
 #endif
 };
 };
 
 
+static struct video_device cx8800_radio_template = {
+	.name                 = "cx8800-radio",
+	.fops                 = &radio_fops,
+	.minor                = -1,
+	.ioctl_ops 	      = &radio_ioctl_ops,
+};
+
 /* ----------------------------------------------------------- */
 /* ----------------------------------------------------------- */
 
 
 static void cx8800_unregister_video(struct cx8800_dev *dev)
 static void cx8800_unregister_video(struct cx8800_dev *dev)
@@ -1830,7 +1836,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 	memcpy( &cx8800_vbi_template, &cx8800_video_template,
 	memcpy( &cx8800_vbi_template, &cx8800_video_template,
 		sizeof(cx8800_vbi_template) );
 		sizeof(cx8800_vbi_template) );
 	strcpy(cx8800_vbi_template.name,"cx8800-vbi");
 	strcpy(cx8800_vbi_template.name,"cx8800-vbi");
-	cx8800_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
 
 
 	/* initialize driver struct */
 	/* initialize driver struct */
 	spin_lock_init(&dev->slock);
 	spin_lock_init(&dev->slock);
@@ -1866,7 +1871,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 
 
 	/* load and configure helper modules */
 	/* load and configure helper modules */
 
 
-	if (core->board.audio_chip == AUDIO_CHIP_WM8775)
+	if (core->board.audio_chip == V4L2_IDENT_WM8775)
 		request_module("wm8775");
 		request_module("wm8775");
 
 
 	switch (core->boardnr) {
 	switch (core->boardnr) {

+ 2 - 2
drivers/media/video/cx88/cx88.h

@@ -29,8 +29,8 @@
 #include <media/tuner.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
 #include <media/videobuf-dma-sg.h>
+#include <media/v4l2-chip-ident.h>
 #include <media/cx2341x.h>
 #include <media/cx2341x.h>
-#include <media/audiochip.h>
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 #include <media/videobuf-dvb.h>
 #include <media/videobuf-dvb.h>
 #endif
 #endif
@@ -252,7 +252,7 @@ struct cx88_board {
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       radio;
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
 	enum cx88_board_type    mpeg;
-	enum audiochip          audio_chip;
+	unsigned int            audio_chip;
 };
 };
 
 
 struct cx88_subid {
 struct cx88_subid {

File diff suppressed because it is too large
+ 781 - 113
drivers/media/video/em28xx/em28xx-cards.c


+ 12 - 1
drivers/media/video/em28xx/em28xx-dvb.c

@@ -6,6 +6,7 @@
  (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
  (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
 	- Fixes for the driver to properly work with HVR-950
 	- Fixes for the driver to properly work with HVR-950
 	- Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
 	- Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
+	- Fixes for the driver to properly work with AMD ATI TV Wonder HD 600
 
 
  (c) 2008 Aidan Thornton <makosoft@googlemail.com>
  (c) 2008 Aidan Thornton <makosoft@googlemail.com>
 
 
@@ -409,8 +410,9 @@ static int dvb_init(struct em28xx *dev)
 	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	/* init frontend */
 	/* init frontend */
 	switch (dev->model) {
 	switch (dev->model) {
-	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
 		dvb->frontend = dvb_attach(lgdt330x_attach,
 		dvb->frontend = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
 					   &em2880_lgdt3303_dev,
 					   &dev->i2c_adap);
 					   &dev->i2c_adap);
@@ -441,6 +443,15 @@ static int dvb_init(struct em28xx *dev)
 		}
 		}
 		break;
 		break;
 #endif
 #endif
+	case EM2880_BOARD_TERRATEC_HYBRID_XS:
+		dvb->frontend = dvb_attach(zl10353_attach,
+						&em28xx_zl10353_with_xc3028,
+						&dev->i2c_adap);
+		if (attach_xc3028(0x61, dev) < 0) {
+			 result = -EINVAL;
+			goto out_free;
+		}
+		break;
 	default:
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
 				" isn't supported yet\n",
 				" isn't supported yet\n",

+ 31 - 30
drivers/media/video/em28xx/em28xx-video.c

@@ -38,6 +38,7 @@
 
 
 #include "em28xx.h"
 #include "em28xx.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/msp3400.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 #include <media/tuner.h>
 
 
@@ -1763,20 +1764,7 @@ static const struct file_operations em28xx_v4l_fops = {
 	.compat_ioctl  = v4l_compat_ioctl32,
 	.compat_ioctl  = v4l_compat_ioctl32,
 };
 };
 
 
-static const struct file_operations radio_fops = {
-	.owner         = THIS_MODULE,
-	.open          = em28xx_v4l2_open,
-	.release       = em28xx_v4l2_close,
-	.ioctl	       = video_ioctl2,
-	.compat_ioctl  = v4l_compat_ioctl32,
-	.llseek        = no_llseek,
-};
-
-static const struct video_device em28xx_video_template = {
-	.fops                       = &em28xx_v4l_fops,
-	.release                    = video_device_release,
-
-	.minor                      = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap            = vidioc_querycap,
 	.vidioc_querycap            = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap    = vidioc_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap    = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap       = vidioc_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap       = vidioc_g_fmt_vid_cap,
@@ -1814,16 +1802,29 @@ static const struct video_device em28xx_video_template = {
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	.vidiocgmbuf                = vidiocgmbuf,
 	.vidiocgmbuf                = vidiocgmbuf,
 #endif
 #endif
+};
+
+static const struct video_device em28xx_video_template = {
+	.fops                       = &em28xx_v4l_fops,
+	.release                    = video_device_release,
+	.ioctl_ops 		    = &video_ioctl_ops,
+
+	.minor                      = -1,
 
 
 	.tvnorms                    = V4L2_STD_ALL,
 	.tvnorms                    = V4L2_STD_ALL,
 	.current_norm               = V4L2_STD_PAL,
 	.current_norm               = V4L2_STD_PAL,
 };
 };
 
 
-static struct video_device em28xx_radio_template = {
-	.name                 = "em28xx-radio",
-	.type                 = VID_TYPE_TUNER,
-	.fops                 = &radio_fops,
-	.minor                = -1,
+static const struct file_operations radio_fops = {
+	.owner         = THIS_MODULE,
+	.open          = em28xx_v4l2_open,
+	.release       = em28xx_v4l2_close,
+	.ioctl	       = video_ioctl2,
+	.compat_ioctl  = v4l_compat_ioctl32,
+	.llseek        = no_llseek,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 	.vidioc_querycap      = radio_querycap,
 	.vidioc_querycap      = radio_querycap,
 	.vidioc_g_tuner       = radio_g_tuner,
 	.vidioc_g_tuner       = radio_g_tuner,
 	.vidioc_enum_input    = radio_enum_input,
 	.vidioc_enum_input    = radio_enum_input,
@@ -1842,6 +1843,13 @@ static struct video_device em28xx_radio_template = {
 #endif
 #endif
 };
 };
 
 
+static struct video_device em28xx_radio_template = {
+	.name                 = "em28xx-radio",
+	.fops                 = &radio_fops,
+	.ioctl_ops 	      = &radio_ioctl_ops,
+	.minor                = -1,
+};
+
 /******************************** usb interface ******************************/
 /******************************** usb interface ******************************/
 
 
 
 
@@ -1882,7 +1890,6 @@ EXPORT_SYMBOL(em28xx_unregister_extension);
 
 
 static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 					     const struct video_device *template,
 					     const struct video_device *template,
-					     const int type,
 					     const char *type_name)
 					     const char *type_name)
 {
 {
 	struct video_device *vfd;
 	struct video_device *vfd;
@@ -1892,9 +1899,8 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 		return NULL;
 		return NULL;
 	*vfd = *template;
 	*vfd = *template;
 	vfd->minor   = -1;
 	vfd->minor   = -1;
-	vfd->dev = &dev->udev->dev;
+	vfd->parent = &dev->udev->dev;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
-	vfd->type = type;
 	vfd->debug = video_debug;
 	vfd->debug = video_debug;
 
 
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
@@ -1972,14 +1978,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 	list_add_tail(&dev->devlist, &em28xx_devlist);
 	list_add_tail(&dev->devlist, &em28xx_devlist);
 
 
 	/* allocate and fill video video_device struct */
 	/* allocate and fill video video_device struct */
-	dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template,
-					  VID_TYPE_CAPTURE, "video");
+	dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
 	if (NULL == dev->vdev) {
 	if (NULL == dev->vdev) {
 		em28xx_errdev("cannot allocate video_device.\n");
 		em28xx_errdev("cannot allocate video_device.\n");
 		goto fail_unreg;
 		goto fail_unreg;
 	}
 	}
-	if (dev->tuner_type != TUNER_ABSENT)
-		dev->vdev->type |= VID_TYPE_TUNER;
 
 
 	/* register v4l2 video video_device */
 	/* register v4l2 video video_device */
 	retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
 	retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
@@ -1991,8 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 	}
 	}
 
 
 	/* Allocate and fill vbi video_device struct */
 	/* Allocate and fill vbi video_device struct */
-	dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
-					  VFL_TYPE_VBI, "vbi");
+	dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
 	/* register v4l2 vbi video_device */
 	/* register v4l2 vbi video_device */
 	if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
 	if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
 					vbi_nr[dev->devno]) < 0) {
 					vbi_nr[dev->devno]) < 0) {
@@ -2002,8 +2004,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 	}
 	}
 
 
 	if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
 	if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
-		dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
-					VFL_TYPE_RADIO, "radio");
+		dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
 		if (NULL == dev->radio_dev) {
 		if (NULL == dev->radio_dev) {
 			em28xx_errdev("cannot allocate video_device.\n");
 			em28xx_errdev("cannot allocate video_device.\n");
 			goto fail_unreg;
 			goto fail_unreg;

+ 47 - 2
drivers/media/video/em28xx/em28xx.h

@@ -54,15 +54,58 @@
 #define EM2880_BOARD_TERRATEC_PRODIGY_XS	13
 #define EM2880_BOARD_TERRATEC_PRODIGY_XS	13
 #define EM2820_BOARD_PROLINK_PLAYTV_USB2	14
 #define EM2820_BOARD_PROLINK_PLAYTV_USB2	14
 #define EM2800_BOARD_VGEAR_POCKETTV             15
 #define EM2800_BOARD_VGEAR_POCKETTV             15
-#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950	16
+#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950	16
 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO	17
 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO	17
 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2	18
 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2	18
 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA  19
 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA  19
+#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600   20
+#define EM2800_BOARD_GRABBEEX_USB2800           21
+#define EM2750_BOARD_UNKNOWN			  22
+#define EM2750_BOARD_DLCW_130			  23
+#define EM2820_BOARD_DLINK_USB_TV		  24
+#define EM2820_BOARD_GADMEI_UTV310		  25
+#define EM2820_BOARD_HERCULES_SMART_TV_USB2	  26
+#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME	  27
+#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
+#define EM2820_BOARD_PINNACLE_DVC_100		  29
+#define EM2820_BOARD_VIDEOLOGY_20K14XUSB	  30
+#define EM2821_BOARD_USBGEAR_VD204		  31
+#define EM2821_BOARD_SUPERCOMP_USB_2		  32
+#define EM2821_BOARD_PROLINK_PLAYTV_USB2	  33
+#define EM2860_BOARD_TERRATEC_HYBRID_XS		  34
+#define EM2860_BOARD_TYPHOON_DVD_MAKER		  35
+#define EM2860_BOARD_NETGMBH_CAM		  36
+#define EM2860_BOARD_GADMEI_UTV330		  37
+#define EM2861_BOARD_YAKUMO_MOVIE_MIXER		  38
+#define EM2861_BOARD_KWORLD_PVRTV_300U		  39
+#define EM2861_BOARD_PLEXTOR_PX_TV100U		  40
+#define EM2870_BOARD_KWORLD_350U		  41
+#define EM2870_BOARD_KWORLD_355U		  42
+#define EM2870_BOARD_TERRATEC_XS		  43
+#define EM2870_BOARD_TERRATEC_XS_MT2060		  44
+#define EM2870_BOARD_PINNACLE_PCTV_DVB		  45
+#define EM2870_BOARD_COMPRO_VIDEOMATE		  46
+#define EM2880_BOARD_KWORLD_DVB_305U		  47
+#define EM2880_BOARD_KWORLD_DVB_310U		  48
+#define EM2880_BOARD_MSI_DIGIVOX_AD		  49
+#define EM2880_BOARD_MSI_DIGIVOX_AD_II		  50
+#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR	  51
+#define EM2881_BOARD_DNT_DA2_HYBRID		  52
+#define EM2881_BOARD_PINNACLE_HYBRID_PRO	  53
+#define EM2882_BOARD_KWORLD_VS_DVBT		  54
+#define EM2882_BOARD_TERRATEC_HYBRID_XS		  55
+#define EM2882_BOARD_PINNACLE_HYBRID_PRO	  56
+#define EM2883_BOARD_KWORLD_HYBRID_A316		  57
+#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU	  58
 
 
 /* Limits minimum and default number of buffers */
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
 #define EM28XX_MIN_BUF 4
 #define EM28XX_DEF_BUF 8
 #define EM28XX_DEF_BUF 8
 
 
+/* Params for validated field */
+#define EM28XX_BOARD_NOT_VALIDATED 1
+#define EM28XX_BOARD_VALIDATED	   0
+
 /* maximum number of em28xx boards */
 /* maximum number of em28xx boards */
 #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 
 
@@ -251,6 +294,7 @@ struct em28xx_board {
 	unsigned int max_range_640_480:1;
 	unsigned int max_range_640_480:1;
 	unsigned int has_dvb:1;
 	unsigned int has_dvb:1;
 	unsigned int has_snapshot_button:1;
 	unsigned int has_snapshot_button:1;
+	unsigned int valid:1;
 
 
 	enum em28xx_decoder decoder;
 	enum em28xx_decoder decoder;
 
 
@@ -331,6 +375,7 @@ struct em28xx {
 	unsigned int max_range_640_480:1;
 	unsigned int max_range_640_480:1;
 	unsigned int has_dvb:1;
 	unsigned int has_dvb:1;
 	unsigned int has_snapshot_button:1;
 	unsigned int has_snapshot_button:1;
+	unsigned int valid:1;		/* report for validated boards */
 
 
 	/* Some older em28xx chips needs a waiting time after writing */
 	/* Some older em28xx chips needs a waiting time after writing */
 	unsigned int wait_after_write;
 	unsigned int wait_after_write;
@@ -360,7 +405,7 @@ struct em28xx {
 	v4l2_std_id norm;	/* selected tv norm */
 	v4l2_std_id norm;	/* selected tv norm */
 	int ctl_freq;		/* selected frequency */
 	int ctl_freq;		/* selected frequency */
 	unsigned int ctl_input;	/* selected input */
 	unsigned int ctl_input;	/* selected input */
-	unsigned int ctl_ainput;	/* slected audio input */
+	unsigned int ctl_ainput;/* selected audio input */
 	int mute;
 	int mute;
 	int volume;
 	int volume;
 	/* frame properties */
 	/* frame properties */

+ 2 - 3
drivers/media/video/et61x251/et61x251_core.c

@@ -34,6 +34,7 @@
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/page-flags.h>
 #include <linux/page-flags.h>
+#include <media/v4l2-ioctl.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
@@ -985,7 +986,7 @@ static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
 
 
 static int et61x251_create_sysfs(struct et61x251_device* cam)
 static int et61x251_create_sysfs(struct et61x251_device* cam)
 {
 {
-	struct device *classdev = &(cam->v4ldev->class_dev);
+	struct device *classdev = &(cam->v4ldev->dev);
 	int err = 0;
 	int err = 0;
 
 
 	if ((err = device_create_file(classdev, &dev_attr_reg)))
 	if ((err = device_create_file(classdev, &dev_attr_reg)))
@@ -2584,8 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 	}
 	}
 
 
 	strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
 	strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
-	cam->v4ldev->owner = THIS_MODULE;
-	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
 	cam->v4ldev->fops = &et61x251_fops;
 	cam->v4ldev->fops = &et61x251_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	cam->v4ldev->release = video_device_release;

+ 2 - 7
drivers/media/video/gspca/conex.c

@@ -25,9 +25,6 @@
 #define CONEX_CAM 1		/* special JPEG header */
 #define CONEX_CAM 1		/* special JPEG header */
 #include "jpeg.h"
 #include "jpeg.h"
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -818,7 +815,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct cam *cam;
 	struct cam *cam;
 
 
 	cam = &gspca_dev->cam;
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -1011,9 +1007,8 @@ static struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
 static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
+	{USB_DEVICE(0x0572, 0x0041)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1038,7 +1033,7 @@ static int __init sd_mod_init(void)
 {
 {
 	if (usb_register(&sd_driver) < 0)
 	if (usb_register(&sd_driver) < 0)
 		return -1;
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 	return 0;
 }
 }
 static void __exit sd_mod_exit(void)
 static void __exit sd_mod_exit(void)

+ 5 - 25
drivers/media/video/gspca/etoms.c

@@ -22,9 +22,6 @@
 
 
 #include "gspca.h"
 #include "gspca.h"
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("Etoms USB Camera Driver");
 MODULE_DESCRIPTION("Etoms USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -602,26 +599,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
-
-	vendor = id->idVendor;
-	product = id->idProduct;
-/*	switch (vendor) { */
-/*	case 0x102c:		* Etoms */
-		switch (product) {
-		case 0x6151:
-			sd->sensor = SENSOR_PAS106;	/* Etoms61x151 */
-			break;
-		case 0x6251:
-			sd->sensor = SENSOR_TAS5130CXX;	/* Etoms61x251 */
-			break;
-/*		} */
-/*		break; */
-	}
+
 	cam = &gspca_dev->cam;
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 1;
 	cam->epaddr = 1;
+	sd->sensor = id->driver_info;
 	if (sd->sensor == SENSOR_PAS106) {
 	if (sd->sensor == SENSOR_PAS106) {
 		cam->cam_mode = sif_mode;
 		cam->cam_mode = sif_mode;
 		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
 		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
@@ -911,12 +892,11 @@ static struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
 static __devinitdata struct usb_device_id device_table[] = {
 #ifndef CONFIG_USB_ET61X251
 #ifndef CONFIG_USB_ET61X251
-	{USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
+	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
 #endif
 #endif
-	{USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
+	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
 	{}
 	{}
 };
 };
 
 
@@ -942,7 +922,7 @@ static int __init sd_mod_init(void)
 {
 {
 	if (usb_register(&sd_driver) < 0)
 	if (usb_register(&sd_driver) < 0)
 		return -1;
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 	return 0;
 }
 }
 
 

+ 30 - 13
drivers/media/video/gspca/gspca.c

@@ -32,6 +32,7 @@
 #include <asm/page.h>
 #include <asm/page.h>
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
+#include <media/v4l2-ioctl.h>
 
 
 #include "gspca.h"
 #include "gspca.h"
 
 
@@ -42,8 +43,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 2, 0)
 
 
 static int video_nr = -1;
 static int video_nr = -1;
 
 
@@ -209,6 +209,8 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
 				   &frame->v4l2_buf.timestamp);
 				   &frame->v4l2_buf.timestamp);
 		frame->v4l2_buf.sequence = ++gspca_dev->sequence;
 		frame->v4l2_buf.sequence = ++gspca_dev->sequence;
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
+		if (packet_type == LAST_PACKET)
+			gspca_dev->last_packet_type = packet_type;
 		return frame;
 		return frame;
 	}
 	}
 
 
@@ -399,7 +401,7 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
  * This routine may be called many times when the bandwidth is too small
  * This routine may be called many times when the bandwidth is too small
  * (the bandwidth is checked on urb submit).
  * (the bandwidth is checked on urb submit).
  */
  */
-struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
+static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
 {
 {
 	struct usb_interface *intf;
 	struct usb_interface *intf;
 	struct usb_host_endpoint *ep;
 	struct usb_host_endpoint *ep;
@@ -832,7 +834,16 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
 
 	memset(cap, 0, sizeof *cap);
 	memset(cap, 0, sizeof *cap);
 	strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
 	strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
-	strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
+/*	strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */
+	if (gspca_dev->dev->product != NULL) {
+		strncpy(cap->card, gspca_dev->dev->product,
+			sizeof cap->card);
+	} else {
+		snprintf(cap->card, sizeof cap->card,
+			"USB Camera (%04x:%04x)",
+			le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
+			le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
+	}
 	strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
 	strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
 		sizeof cap->bus_info);
 		sizeof cap->bus_info);
 	cap->version = DRIVER_VERSION_NUMBER;
 	cap->version = DRIVER_VERSION_NUMBER;
@@ -1649,12 +1660,7 @@ static struct file_operations dev_fops = {
 	.poll	= dev_poll,
 	.poll	= dev_poll,
 };
 };
 
 
-static struct video_device gspca_template = {
-	.name = "gspca main driver",
-	.type = VID_TYPE_CAPTURE,
-	.fops = &dev_fops,
-	.release = dev_release,		/* mandatory */
-	.minor = -1,
+static const struct v4l2_ioctl_ops dev_ioctl_ops = {
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_dqbuf		= vidioc_dqbuf,
 	.vidioc_dqbuf		= vidioc_dqbuf,
 	.vidioc_qbuf		= vidioc_qbuf,
 	.vidioc_qbuf		= vidioc_qbuf,
@@ -1683,6 +1689,14 @@ static struct video_device gspca_template = {
 #endif
 #endif
 };
 };
 
 
+static struct video_device gspca_template = {
+	.name = "gspca main driver",
+	.fops = &dev_fops,
+	.ioctl_ops = &dev_ioctl_ops,
+	.release = dev_release,		/* mandatory */
+	.minor = -1,
+};
+
 /*
 /*
  * probe and create a new gspca device
  * probe and create a new gspca device
  *
  *
@@ -1740,10 +1754,11 @@ int gspca_dev_probe(struct usb_interface *intf,
 
 
 	/* init video stuff */
 	/* init video stuff */
 	memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
 	memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
-	gspca_dev->vdev.dev = &dev->dev;
+	gspca_dev->vdev.parent = &dev->dev;
 	memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
 	memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
 	gspca_dev->vdev.fops = &gspca_dev->fops;
 	gspca_dev->vdev.fops = &gspca_dev->fops;
 	gspca_dev->fops.owner = module;		/* module protection */
 	gspca_dev->fops.owner = module;		/* module protection */
+	gspca_dev->present = 1;
 	ret = video_register_device(&gspca_dev->vdev,
 	ret = video_register_device(&gspca_dev->vdev,
 				  VFL_TYPE_GRABBER,
 				  VFL_TYPE_GRABBER,
 				  video_nr);
 				  video_nr);
@@ -1752,7 +1767,6 @@ int gspca_dev_probe(struct usb_interface *intf,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	gspca_dev->present = 1;
 	usb_set_intfdata(intf, gspca_dev);
 	usb_set_intfdata(intf, gspca_dev);
 	PDEBUG(D_PROBE, "probe ok");
 	PDEBUG(D_PROBE, "probe ok");
 	return 0;
 	return 0;
@@ -1885,7 +1899,10 @@ EXPORT_SYMBOL(gspca_auto_gain_n_exposure);
 /* -- module insert / remove -- */
 /* -- module insert / remove -- */
 static int __init gspca_init(void)
 static int __init gspca_init(void)
 {
 {
-	info("main v%s registered", version);
+	info("main v%d.%d.%d registered",
+		(DRIVER_VERSION_NUMBER >> 16) & 0xff,
+		(DRIVER_VERSION_NUMBER >> 8) & 0xff,
+		DRIVER_VERSION_NUMBER & 0xff);
 	return 0;
 	return 0;
 }
 }
 static void __exit gspca_exit(void)
 static void __exit gspca_exit(void)

+ 2 - 7
drivers/media/video/gspca/mars.c

@@ -24,9 +24,6 @@
 #include "gspca.h"
 #include "gspca.h"
 #include "jpeg.h"
 #include "jpeg.h"
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
 MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -140,7 +137,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct cam *cam;
 	struct cam *cam;
 
 
 	cam = &gspca_dev->cam;
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -424,9 +420,8 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")},
+	{USB_DEVICE(0x093a, 0x050f)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -451,7 +446,7 @@ static int __init sd_mod_init(void)
 {
 {
 	if (usb_register(&sd_driver) < 0)
 	if (usb_register(&sd_driver) < 0)
 		return -1;
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 	return 0;
 }
 }
 static void __exit sd_mod_exit(void)
 static void __exit sd_mod_exit(void)

+ 14 - 19
drivers/media/video/gspca/ov519.c

@@ -24,9 +24,6 @@
 
 
 #include "gspca.h"
 #include "gspca.h"
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("OV519 USB Camera Driver");
 MODULE_DESCRIPTION("OV519 USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -1375,7 +1372,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		cam->cam_mode = sif_mode;
 		cam->cam_mode = sif_mode;
 		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
 		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
 	}
 	}
-	cam->dev_name = (char *) id->driver_info;
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
@@ -2129,21 +2125,20 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")},
-	{USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")},
-	{USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")},
-	{USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")},
-	{USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")},
-	{USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")},
-	{USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")},
-	{USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")},
-	{USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")},
-	{USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")},
-	{USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")},
-	{USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")},
-	{USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")},
+	{USB_DEVICE(0x041e, 0x4052)},
+	{USB_DEVICE(0x041e, 0x405f)},
+	{USB_DEVICE(0x041e, 0x4060)},
+	{USB_DEVICE(0x041e, 0x4061)},
+	{USB_DEVICE(0x041e, 0x4064)},
+	{USB_DEVICE(0x041e, 0x4068)},
+	{USB_DEVICE(0x045e, 0x028c)},
+	{USB_DEVICE(0x054c, 0x0154)},
+	{USB_DEVICE(0x054c, 0x0155)},
+	{USB_DEVICE(0x05a9, 0x0519)},
+	{USB_DEVICE(0x05a9, 0x0530)},
+	{USB_DEVICE(0x05a9, 0x4519)},
+	{USB_DEVICE(0x05a9, 0x8519)},
 	{}
 	{}
 };
 };
 #undef DVNAME
 #undef DVNAME
@@ -2169,7 +2164,7 @@ static int __init sd_mod_init(void)
 {
 {
 	if (usb_register(&sd_driver) < 0)
 	if (usb_register(&sd_driver) < 0)
 		return -1;
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 	return 0;
 }
 }
 static void __exit sd_mod_exit(void)
 static void __exit sd_mod_exit(void)

+ 12 - 17
drivers/media/video/gspca/pac207.c

@@ -27,9 +27,6 @@
 
 
 #include "gspca.h"
 #include "gspca.h"
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
 MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
 MODULE_DESCRIPTION("Pixart PAC207");
 MODULE_DESCRIPTION("Pixart PAC207");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
@@ -208,7 +205,7 @@ static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
 }
 }
 
 
 
 
-int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
+static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
 {
 {
 	struct usb_device *udev = gspca_dev->dev;
 	struct usb_device *udev = gspca_dev->dev;
 	int err;
 	int err;
@@ -223,8 +220,7 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
 	return err;
 	return err;
 }
 }
 
 
-
-int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
+static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
 {
 {
 	struct usb_device *udev = gspca_dev->dev;
 	struct usb_device *udev = gspca_dev->dev;
 	int res;
 	int res;
@@ -574,17 +570,16 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")},
-	{USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")},
-	{USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")},
-	{USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")},
-	{USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")},
-	{USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")},
-	{USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")},
-	{USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")},
-	{USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")},
+	{USB_DEVICE(0x041e, 0x4028)},
+	{USB_DEVICE(0x093a, 0x2460)},
+	{USB_DEVICE(0x093a, 0x2463)},
+	{USB_DEVICE(0x093a, 0x2464)},
+	{USB_DEVICE(0x093a, 0x2468)},
+	{USB_DEVICE(0x093a, 0x2470)},
+	{USB_DEVICE(0x093a, 0x2471)},
+	{USB_DEVICE(0x093a, 0x2472)},
+	{USB_DEVICE(0x2001, 0xf115)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -609,7 +604,7 @@ static int __init sd_mod_init(void)
 {
 {
 	if (usb_register(&sd_driver) < 0)
 	if (usb_register(&sd_driver) < 0)
 		return -1;
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 	return 0;
 }
 }
 static void __exit sd_mod_exit(void)
 static void __exit sd_mod_exit(void)

Some files were not shown because too many files changed in this diff