Merge ../linux-2.6
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 721c71b..c239554 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -47,6 +47,30 @@
 
 ---------------------------
 
+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])
 When:	November 2005
 Files:	drivers/pcmcia/: pcmcia_ioctl.c
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828
index 86d1c8e..eedc399 100644
--- a/Documentation/video4linux/CARDLIST.au0828
+++ b/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]
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
+  4 -> Hauppauge HVR950Q rev xxF8               (au0828)        [2040:7201,2040:7211,2040:7281]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 1059146..89c7f32 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,11 +1,11 @@
   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]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
   5 -> MSI VOX USB 2.0                          (em2820/em2840)
   6 -> Terratec Cinergy 200 USB                 (em2800)
-  7 -> Leadtek Winfast USB II                   (em2800)
+  7 -> Leadtek Winfast USB II                   (em2800)        [0413:6023]
   8 -> Kworld USB2800                           (em2800)
   9 -> Pinnacle Dazzle DVC 90/DVC 100           (em2820/em2840) [2304:0207,2304:021a]
  10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
@@ -14,7 +14,46 @@
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  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]
  18 -> Hauppauge WinTV HVR 900 (R2)             (em2880)        [2040:6502]
  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]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 0c4880a..bcaf4ab 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/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:
 	gspca_main	main driver
diff --git a/MAINTAINERS b/MAINTAINERS
index 03c5d6c..deedc0d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3796,6 +3796,12 @@
 M:	bn@niasdigital.com
 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
 P:	Ingo Molnar
 M:	mingo@redhat.com
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 171afe7..cf6a817 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -563,7 +563,7 @@
 
 	DEB_EE(("dev:%p\n",dev));
 
-	if( VFL_TYPE_GRABBER == (*vid)->type ) {
+	if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
 		vv->video_minor = -1;
 	} else {
 		vv->vbi_minor = -1;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index a5e6275..e8bc7ab 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -656,7 +656,7 @@
 
 		/* if we have a user buffer, the first page may not be
 		   aligned to a page boundary. */
-		pt1->offset = list->offset;
+		pt1->offset = dma->sglist->offset;
 		pt2->offset = pt1->offset+o1;
 		pt3->offset = pt1->offset+o2;
 
@@ -958,21 +958,18 @@
 	case VIDIOC_ENUM_FMT:
 	{
 		struct v4l2_fmtdesc *f = arg;
-		int index;
 
 		switch (f->type) {
 		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;
-			}
-			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;
-		}
 		default:
 			return -EINVAL;
 		}
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 850d568..6f92bea 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -21,9 +21,8 @@
 	tristate
 	default 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_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -138,8 +137,6 @@
 config MEDIA_TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
 	depends on VIDEO_MEDIA && I2C
-	depends on HOTPLUG
-	select FW_LOADER
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for the xc2028/xc3028 tuners.
@@ -147,8 +144,6 @@
 config MEDIA_TUNER_XC5000
 	tristate "Xceive XC5000 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	depends on HOTPLUG
-	select FW_LOADER
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
@@ -162,4 +157,11 @@
 	help
 	  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
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 55f7e67..4dfbe5b 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -21,6 +21,7 @@
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.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/frontends
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index fbcb282..35b763a 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
@@ -148,7 +148,8 @@
 	tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
 		  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",
 			   lo1a, lo1n, lo2a,lo2n);
 		return(-1);
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
new file mode 100644
index 0000000..cb25e43
--- /dev/null
+++ b/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:
+ */
diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/common/tuners/mxl5007t.h
new file mode 100644
index 0000000..aa3eea0
--- /dev/null
+++ b/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:
+ */
+
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index a0545ba..72abf0b 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -6,7 +6,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 #include "tuner-i2c.h"
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 266c255..597e47f 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -6,7 +6,7 @@
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/tuner-types.h>
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 7588db1..7e9c090 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,7 +1,6 @@
 config DVB_BT8XX
 	tristate "BT8xx based PCI cards"
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
-	depends on HOTPLUG	# due to FW_LOADER
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
@@ -10,7 +9,6 @@
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index a577c0f..e84152b 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,8 +1,6 @@
 config DVB_USB
 	tristate "Support for various USB DVB devices"
 	depends on DVB_CORE && USB && I2C && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
-	select FW_LOADER
 	help
 	  By enabling this you will be able to choose the various supported
 	  USB1.1 and USB2.0 DVB devices.
@@ -246,6 +244,14 @@
 	  Say Y here to support the default remote control decoding for the
 	  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
 	tristate "Anysee DVB-T/C USB2.0 support"
 	depends on DVB_USB
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 44c11e4..e206f1e 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -64,6 +64,9 @@
 dvb-usb-anysee-objs = 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/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index adfd4fc..2f408d2 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -43,7 +43,7 @@
 MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
 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,
 	u8 *rbuf, u8 rlen)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index e5238b3..029b437 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -204,5 +204,6 @@
 #define USB_PID_ASUS_U3000				0x171f
 #define USB_PID_ASUS_U3100				0x173f
 #define USB_PID_YUAN_EC372S				0x1edc
+#define USB_PID_DW2102					0x2102
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
new file mode 100644
index 0000000..a4d898b
--- /dev/null
+++ b/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");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
new file mode 100644
index 0000000..7a310f9
--- /dev/null
+++ b/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
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index c20553c..574dffe 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -97,9 +97,8 @@
 
 config DVB_SP8870
 	tristate "Spase sp8870 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -110,9 +109,8 @@
 
 config DVB_SP887X
 	tristate "Spase sp887x based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -135,6 +133,20 @@
 	help
 	  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
 	tristate "LSI L64781"
 	depends on DVB_CORE && I2C
@@ -144,9 +156,8 @@
 
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -211,9 +222,8 @@
 
 config DVB_TDA10048
 	tristate "Philips TDA10048HN based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -253,9 +263,8 @@
 
 config DVB_NXT200X
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
@@ -268,9 +277,8 @@
 
 config DVB_OR51211
 	tristate "Oren OR51211 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
@@ -281,9 +289,8 @@
 
 config DVB_OR51132
 	tristate "Oren OR51132 based"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
@@ -297,9 +304,8 @@
 
 config DVB_BCM3510
 	tristate "Broadcom BCM3510"
-	depends on DVB_CORE && I2C && HOTPLUG
+	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
 	  support this frontend.
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index a89dc0f..028da55 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -25,6 +25,7 @@
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
+obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_TDA10023) += tda10023.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
new file mode 100644
index 0000000..3cbed87
--- /dev/null
+++ b/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);
diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h
new file mode 100644
index 0000000..ddc7a07
--- /dev/null
+++ b/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 */
diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h
new file mode 100644
index 0000000..01de02a
--- /dev/null
+++ b/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 */
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
new file mode 100644
index 0000000..d2876d2
--- /dev/null
+++ b/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
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index b4b8ed7..c5f45fe 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -110,12 +110,12 @@
 	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;
 
@@ -1187,7 +1187,7 @@
 }
 
 
-int smscore_module_init(void)
+static int __init smscore_module_init(void)
 {
 	int rc = 0;
 
@@ -1209,7 +1209,7 @@
 	return rc;
 }
 
-void smscore_module_exit(void)
+static void __exit smscore_module_exit(void)
 {
 
 	kmutex_lock(&g_smscore_deviceslock);
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 6f9c185..229274a 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -27,8 +27,8 @@
 
 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)
 {
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 87c973a..41b5a98 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -5,8 +5,6 @@
 config DVB_AV7110
 	tristate "AV7110 cards"
 	depends on DVB_CORE && PCI && I2C
-	depends on HOTPLUG
-	select FW_LOADER if !DVB_AV7110_FIRMWARE
 	select TTPCI_EEPROM
 	select VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
@@ -127,14 +125,12 @@
 	depends on DVB_BUDGET_CORE && I2C
 	select 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_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
 	select DVB_TDA10021 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select DVB_TUA6100 if !DVB_FE_CUSTOMISE
-	select FW_LOADER
 	help
 	  Support for simple SAA7146 based DVB cards
 	  (so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index a23cc0a..d5f48a3 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -1,8 +1,6 @@
 config DVB_TTUSB_DEC
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	depends on DVB_CORE && USB && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
-	select FW_LOADER
 	select CRC32
 	help
 	  Support for external USB adapters designed by Technotrend and
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 4e3f83e..1ed88f3 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -85,6 +85,7 @@
 #include <linux/input.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 
 /*
@@ -444,14 +445,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -466,6 +460,14 @@
 	.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
 usb if it is */
 static int usb_dsbr100_probe(struct usb_interface *intf,
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index 09fe6f1..7fd7ee2 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include "oss/aci.h"
 #include "miropcm20-rds-core.h"
 
@@ -228,9 +229,7 @@
 };
 
 static struct video_device pcm20_radio = {
-	.owner		= THIS_MODULE,
 	.name		= "Miro PCM 20 radio",
-	.type		= VID_TYPE_TUNER,
 	.fops           = &pcm20_fops,
 	.priv		= &pcm20_unit
 };
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 1ec18ed..eba9209 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -36,6 +36,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -388,12 +389,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -408,6 +404,12 @@
 	.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)
 {
 	if(io==-1)
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 46cdb54..3fe5504 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -352,12 +353,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -372,6 +368,12 @@
 	.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_PARM_DESC(debug,"activates debug info");
 
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index b14db53..6166e72 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -39,6 +39,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* V4L2 API defs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/param.h>
 #include <linux/pnp.h>
 
@@ -569,12 +570,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -589,6 +585,12 @@
 	.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
 
 static struct pnp_device_id cadet_pnp_devices[] = {
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index de49be9..36e754e 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -46,6 +46,7 @@
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/errno.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -374,11 +375,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -393,6 +390,12 @@
 	.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 )
 {
 	struct gemtek_pci_card *card;
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 81f6aeb..2b1a622 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -23,6 +23,7 @@
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
 #include <linux/spinlock.h>
 
@@ -552,11 +553,7 @@
 	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_g_tuner		= vidioc_g_tuner,
 	.vidioc_s_tuner		= vidioc_s_tuner,
@@ -571,6 +568,12 @@
 	.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.
  */
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index bddd3c4..0ada1c6 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,6)
@@ -354,10 +355,7 @@
 	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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -372,6 +370,12 @@
 	.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,
 	const struct pci_device_id *ent)
 {
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 0133ecf..43c7549 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -44,6 +44,7 @@
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #define DRIVER_VERSION	"0.77"
 
@@ -373,13 +374,7 @@
 	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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -394,6 +389,12 @@
 	.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)
 {
 	if(!request_region(pci_resource_start(pdev, 0),
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 0708021..e2dde08 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -17,6 +17,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/spinlock.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -294,12 +295,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -314,6 +310,12 @@
 	.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)
 {
 	if(io==-1)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 66e052f..bb5d92f 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>	/* udelay			*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/isapnp.h>
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
@@ -294,12 +295,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -314,6 +310,12 @@
 	.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? */
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index b0ccf7c..6290553 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -22,6 +22,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 
 static struct mutex lock;
@@ -410,12 +411,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -430,6 +426,12 @@
 	.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)
 {
 	fmr2_unit.port = io;
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index dc93a88..a4984ff 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -133,6 +133,7 @@
 #include <linux/videodev2.h>
 #include <linux/mutex.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/rds.h>
 #include <asm/unaligned.h>
 
@@ -1585,15 +1586,7 @@
 	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_g_input		= si470x_vidioc_g_input,
 	.vidioc_s_input		= si470x_vidioc_s_input,
@@ -1607,7 +1600,16 @@
 	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
 	.vidioc_s_frequency	= si470x_vidioc_s_frequency,
 	.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,
 };
 
 
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index acc3208..cefa44f 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/spinlock.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
@@ -366,12 +367,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -386,6 +382,12 @@
 	.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)
 {
 	if(io==-1)
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 4ebdfba..d70172d 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -23,6 +23,7 @@
 #include <asm/uaccess.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -346,12 +347,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -366,6 +362,12 @@
 	.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)
 {
 	if(io == -1) {
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 18f2abd..f8d62cf 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -40,6 +40,7 @@
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,1,1)
@@ -344,12 +345,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -364,6 +360,12 @@
 	.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
 
 static int typhoon_proc_show(struct seq_file *m, void *v)
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 43773c5..9f17a33 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -37,6 +37,7 @@
 #include <asm/uaccess.h>	/* copy to/from user              */
 #include <linux/videodev2.h>	/* kernel radio structs           */
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -407,12 +408,7 @@
 	.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_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -427,6 +423,12 @@
 	.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)
 {
 	if (io == -1) {
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f606d29..d4a6e56 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -487,17 +487,6 @@
 	  To compile this driver as a module, choose M here: the
 	  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
 	tristate "Quickcam BW Video For Linux"
 	depends on PARPORT && VIDEO_V4L1
@@ -806,13 +795,7 @@
 
 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"
 
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 45d5db5..bbc6f8b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,6 +10,8 @@
 
 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_V4L2_COMMON) += v4l2-common.o
@@ -55,7 +57,6 @@
 obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
 
 obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_PLANB) += planb.o
 obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
 obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 8c7d195..56ebfd5 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -754,7 +754,6 @@
 };
 
 static struct video_device ar_template = {
-	.owner		= THIS_MODULE,
 	.name		= "Colour AR VGA",
 	.type		= VID_TYPE_CAPTURE,
 	.fops		= &ar_fops,
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 52b2491..ed9a50f 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -6,6 +6,7 @@
 	select VIDEO_TVEEPROM
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+	select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
 	---help---
 	  This is a video4linux driver for Auvitek's USB device.
 
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 898e123..443e590 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -32,6 +32,9 @@
 	[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
 		.name	= "Hauppauge HVR950Q",
 	},
+	[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
+		.name	= "Hauppauge HVR950Q rev xxF8",
+	},
 	[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
 		.name	= "DViCO FusionHDTV USB",
 	},
@@ -49,6 +52,7 @@
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 	case AU0828_BOARD_DVICO_FUSIONHDTV7:
 		if (command == 0) {
 			/* Tuner Reset Command from xc5000 */
@@ -110,6 +114,7 @@
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 		if (dev->i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xa0);
 		break;
@@ -128,6 +133,7 @@
 	switch (dev->board) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
 		/* GPIO's
 		 * 4 - CS5340
 		 * 5 - AU8522 Demodulator
@@ -193,6 +199,12 @@
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x0fd9, 0x0008),
 		.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 },
 	{ },
 };
 
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h
index e26f54a..c37f5fd 100644
--- a/drivers/media/video/au0828/au0828-cards.h
+++ b/drivers/media/video/au0828/au0828-cards.h
@@ -23,3 +23,4 @@
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q	1
 #define AU0828_BOARD_HAUPPAUGE_HVR850 	2
 #define AU0828_BOARD_DVICO_FUSIONHDTV7	3
+#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL	4
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index c6d4705..584a83a 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -28,6 +28,7 @@
 #include "au0828.h"
 #include "au8522.h"
 #include "xc5000.h"
+#include "mxl5007t.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
@@ -45,6 +46,11 @@
 	.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)
 {
@@ -342,6 +348,15 @@
 				&dev->i2c_adap,
 				&hauppauge_hvr950q_tunerconfig, dev);
 		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:
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 		       "isn't supported yet\n");
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 24a34fc..ce71e8e 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,9 +1,7 @@
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 0ea559a..85bf31a 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -45,6 +45,7 @@
 #include <linux/kdev_t.h>
 #include "bttvp.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
 
@@ -163,8 +164,8 @@
 static ssize_t show_card(struct device *cd,
 			 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);
 }
 static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -3357,10 +3358,7 @@
 	.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_enum_fmt_vid_cap        = bttv_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap           = bttv_g_fmt_vid_cap,
@@ -3411,8 +3409,14 @@
 	.vidioc_g_register		= bttv_g_register,
 	.vidioc_s_register		= bttv_s_register,
 #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 @@
 	.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_g_tuner         = radio_g_tuner,
 	.vidioc_enum_input      = radio_enum_input,
@@ -3655,6 +3656,12 @@
 	.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                                                         */
 
@@ -4175,8 +4182,7 @@
 
 static struct video_device *vdev_init(struct bttv *btv,
 				      const struct video_device *template,
-				      const char *type_name,
-				      const int type)
+				      const char *type_name)
 {
 	struct video_device *vfd;
 
@@ -4185,9 +4191,8 @@
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->dev     = &btv->c.pci->dev;
+	vfd->parent  = &btv->c.pci->dev;
 	vfd->release = video_device_release;
-	vfd->type    = type;
 	vfd->debug   = bttv_debug;
 	snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
 		 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
@@ -4223,20 +4228,11 @@
 /* register video4linux devices */
 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");
-	}
 
 	/* 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)
 		goto err;
@@ -4244,7 +4240,7 @@
 		goto err;
 	printk(KERN_INFO "bttv%d: registered device video%d\n",
 	       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) {
 		printk(KERN_ERR "bttv%d: device_create_file 'card' "
 		       "failed\n", btv->c.nr);
@@ -4252,8 +4248,7 @@
 	}
 
 	/* 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)
 		goto err;
@@ -4265,8 +4260,7 @@
 	if (!btv->has_radio)
 		return 0;
 	/* 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)
 		goto err;
 	if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 0af5868..649682a 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <media/v4l2-ioctl.h>
 
 #include "bttvp.h"
 
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 68f28e5..6819e21 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
+#include <media/v4l2-ioctl.h>
 #include <asm/io.h>
 #include "bttvp.h"
 
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index b364ada..d3b3268 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -74,6 +74,7 @@
 #include <linux/sched.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
 
@@ -906,9 +907,7 @@
 };
 static struct video_device qcam_template=
 {
-	.owner		= THIS_MODULE,
 	.name		= "Connectix Quickcam",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &qcam_fops,
 };
 
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index fe1e67b..fe9379b 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 #include <linux/jiffies.h>
 
@@ -701,9 +702,7 @@
 
 static struct video_device qcam_template=
 {
-	.owner		= THIS_MODULE,
 	.name		= "Colour QuickCam",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &qcam_fops,
 };
 
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index d99453f..c149b7d 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -25,6 +25,7 @@
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
 #include <linux/device.h>
 #include <linux/wait.h>
@@ -1768,17 +1769,7 @@
 	.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_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	= cafe_vidioc_try_fmt_vid_cap,
@@ -1801,6 +1792,17 @@
 	.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 @@
 	cam->v4ldev = cafe_v4l_template;
 	cam->v4ldev.debug = 0;
 //	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);
 	if (ret)
 		goto out_smbus;
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index 54de0cd..bd5d9de 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -17,7 +17,7 @@
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <linux/smp_lock.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #ifdef CONFIG_COMPAT
 
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 2a81376..dc8cc61 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3799,9 +3799,7 @@
 };
 
 static struct video_device cpia_template = {
-	.owner		= THIS_MODULE,
 	.name		= "CPiA Camera",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &cpia_fops,
 };
 
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index 5096058..8f0cfee 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -46,6 +46,7 @@
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index f2e8b1c..af8b9ec 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -32,6 +32,7 @@
 #include "cpia2.h"
 
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/firmware.h>
 
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 7ce2789..515c8b5 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <media/v4l2-ioctl.h>
 
 #include "cpia2.h"
 #include "cpia2dev.h"
@@ -1935,11 +1936,7 @@
 
 static struct video_device cpia2_template = {
 	/* I could not find any place for the old .initialize initializer?? */
-	.owner=		THIS_MODULE,
 	.name=		"CPiA2 Camera",
-	.type=		VID_TYPE_CAPTURE,
-	.type2 = 	V4L2_CAP_VIDEO_CAPTURE |
-			V4L2_CAP_STREAMING,
 	.minor=		-1,
 	.fops=		&fops_template,
 	.release=	video_device_release,
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 1c3fa3a..61d14d2 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -111,7 +111,7 @@
 		if (cmd == VIDIOC_DBG_G_REGISTER)
 			reg->val = cs5345_read(client, reg->reg & 0x1f);
 		else
-			cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f);
+			cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff);
 		break;
 	}
 #endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 645b339..e30a589 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -26,7 +26,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv-legacy.h>
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 9aefdc5..ef48565 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -2,9 +2,7 @@
 	tristate "Conexant cx23418 MPEG encoder support"
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
 	depends on INPUT	# due to VIDEO_IR
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_IR
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index c40a286..0b55837 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -30,7 +30,6 @@
 	if (freq != 32000 && freq != 44100 && freq != 48000)
 		return -EINVAL;
 
-	/* common for all inputs and rates */
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
 	cx18_av_write(cx, 0x127, 0x50);
 
@@ -38,15 +37,30 @@
 		switch (freq) {
 		case 32000:
 			/* VID_PLL and AUX_PLL */
-			cx18_av_write4(cx, 0x108, 0x1006040f);
+			cx18_av_write4(cx, 0x108, 0x1408040f);
 
 			/* 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, 0x904, 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;
 
 		case 44100:
@@ -54,12 +68,24 @@
 			cx18_av_write4(cx, 0x108, 0x1009040f);
 
 			/* 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, 0x904, 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;
 
 		case 48000:
@@ -67,12 +93,24 @@
 			cx18_av_write4(cx, 0x108, 0x100a040f);
 
 			/* 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, 0x904, 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;
 		}
 	} else {
@@ -82,18 +120,31 @@
 			cx18_av_write4(cx, 0x108, 0x1e08040f);
 
 			/* 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);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
 			cx18_av_write4(cx, 0x900, 0x08020000);
 			cx18_av_write4(cx, 0x904, 0x08020000);
 			cx18_av_write4(cx, 0x90c, 0x08020000);
 
 			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
 			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;
 
 		case 44100:
@@ -101,15 +152,28 @@
 			cx18_av_write4(cx, 0x108, 0x1809040f);
 
 			/* 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);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
 			cx18_av_write4(cx, 0x900, 0x08017385);
 			cx18_av_write4(cx, 0x904, 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;
 
 		case 48000:
@@ -117,15 +181,28 @@
 			cx18_av_write4(cx, 0x108, 0x180a040f);
 
 			/* 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);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.5555 = 2 * (32000/48000) */
 			cx18_av_write4(cx, 0x900, 0x08015555);
 			cx18_av_write4(cx, 0x904, 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;
 		}
 	}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 45e31b0..4801bc7 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -46,6 +46,7 @@
 #include <linux/dvb/video.h>
 #include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tuner.h>
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 2d630d9..78fadd2 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -86,10 +86,6 @@
 
 #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_SYNC2 0x72646548 /* "rdeH" */
 
@@ -100,35 +96,22 @@
 	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;
-	int retries = 3;
 	int i, j;
+	unsigned size;
 	u32 __iomem *dst = (u32 __iomem *)mem;
 	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");
 		return -ENOMEM;
 	}
 
 	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) {
 		setup_page(i);
 		for (j = i; j < fw->size && j < i + 4096; j += 4) {
@@ -145,15 +128,16 @@
 	}
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 		CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
+	size = fw->size;
 	release_firmware(fw);
 	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;
-	int retries = 3;
 	int i, j;
+	unsigned size;
 	const u32 *src;
 	struct cx18_apu_rom_seghdr seghdr;
 	const u8 *vers;
@@ -161,10 +145,8 @@
 	u32 apu_version = 0;
 	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");
 		return -ENOMEM;
 	}
@@ -173,19 +155,8 @@
 	vers = fw->data + sizeof(seghdr);
 	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];
-	while (offset + sizeof(seghdr) < size) {
+	while (offset + sizeof(seghdr) < fw->size) {
 		/* TODO: byteswapping */
 		memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
 		offset += sizeof(seghdr);
@@ -215,6 +186,7 @@
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
 		CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
 				fn, apu_version, fw->size);
+	size = fw->size;
 	release_firmware(fw);
 	/* Clear bit0 for APU to start from 0 */
 	write_reg(read_reg(0xc72030) & ~1, 0xc72030);
@@ -340,7 +312,7 @@
 	/* Only if the processor is not running */
 	if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
 		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(0xa00000, 4);  /* todo: not hardcoded */
@@ -348,7 +320,7 @@
 		cx18_msleep_timeout(500, 0);
 
 		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) {
 			int retries = 0;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 0d74e59..a7f8396 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -787,50 +787,54 @@
 	return res;
 }
 
+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
+	.vidioc_g_register              = cx18_g_register,
+	.vidioc_s_register              = cx18_s_register,
+#endif
+	.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->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;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	vdev->vidioc_g_register              = cx18_g_register;
-	vdev->vidioc_s_register              = cx18_s_register;
-#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;
+	vdev->ioctl_ops = &cx18_ioctl_ops;
 }
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 1728b1d..0da57f5 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -187,14 +187,11 @@
 		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",
 			cx->num);
 
 	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->release = video_device_release;
 	s->v4l2dev->tvnorms = V4L2_STD_ALL;
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 5cfb46b..e60bd31 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,9 +1,7 @@
 config VIDEO_CX23885
 	tristate "Conexant cx23885 (2388x successor) support"
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
-	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index e7ef093..8118091 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
 
 #include "cx23885.h"
@@ -1699,14 +1700,7 @@
 	.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_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
@@ -1735,6 +1729,13 @@
 	.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)
 {
 	dprintk(1, "%s()\n", __func__);
@@ -1766,7 +1767,7 @@
 	vfd->minor   = -1;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, cx23885_boards[tsport->dev->board].name);
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index fd7112c..a19de85 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -145,6 +145,7 @@
 	},
 	[CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
 		.name		= "DViCO FusionHDTV7 Dual Express",
+		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
 };
@@ -325,25 +326,41 @@
 {
 	struct cx23885_i2c *bus = priv;
 	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) {
 	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;
 	}
 
-	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)
@@ -435,6 +452,19 @@
 		mdelay(20);
 		cx_set(GP0_IO, 0x00050005);
 		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;
 	}
 }
 
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index d17343e..6286a9c 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -76,12 +76,12 @@
  * 0x00010ea0 0x00010xxx Free
  */
 
-static struct sram_channel cx23887_sram_channels[] = {
+static struct sram_channel cx23885_sram_channels[] = {
 	[SRAM_CH01] = {
 		.name		= "VID A",
 		.cmds_start	= 0x10000,
-		.ctrl_start	= 0x105b0,
-		.cdt		= 0x107b0,
+		.ctrl_start	= 0x10380,
+		.cdt		= 0x104c0,
 		.fifo_start	= 0x40,
 		.fifo_size	= 0x2800,
 		.ptr1_reg	= DMA1_PTR1,
@@ -104,8 +104,8 @@
 	[SRAM_CH03] = {
 		.name		= "TS1 B",
 		.cmds_start	= 0x100A0,
-		.ctrl_start	= 0x10780,
-		.cdt		= 0x10400,
+		.ctrl_start	= 0x10400,
+		.cdt		= 0x10580,
 		.fifo_start	= 0x5000,
 		.fifo_size	= 0x1000,
 		.ptr1_reg	= DMA3_PTR1,
@@ -140,7 +140,118 @@
 	[SRAM_CH06] = {
 		.name		= "TS2 C",
 		.cmds_start	= 0x10140,
-		.ctrl_start	= 0x10680,
+		.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[] = {
+	[SRAM_CH01] = {
+		.name		= "VID A",
+		.cmds_start	= 0x10000,
+		.ctrl_start	= 0x105b0,
+		.cdt		= 0x107b0,
+		.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	= 0x10630,
+		.cdt		= 0x10870,
+		.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	= 0x10670,
 		.cdt		= 0x108d0,
 		.fifo_start	= 0x6000,
 		.fifo_size	= 0x1000,
@@ -460,6 +571,7 @@
 	cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
 	cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
 	cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
+	cx_write(PAD_CTRL, 0x00500300);
 
 	mdelay(100);
 
@@ -625,7 +737,6 @@
 	atomic_inc(&dev->refcount);
 
 	dev->nr = cx23885_devcount++;
-	dev->sram_channels = cx23887_sram_channels;
 	sprintf(dev->name, "cx23885[%d]", dev->nr);
 
 	mutex_lock(&devlist);
@@ -637,11 +748,13 @@
 		dev->bridge = CX23885_BRIDGE_887;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 25000000;
+		dev->sram_channels = cx23887_sram_channels;
 	} else
 	if(dev->pci->device == 0x8852) {
 		dev->bridge = CX23885_BRIDGE_885;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 28000000;
+		dev->sram_channels = cx23885_sram_channels;
 	} else
 		BUG();
 
@@ -1010,8 +1123,9 @@
 		port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
 	dprintk(1, "%s() dma_ctl(0x%08X)        0x%08x\n", __func__,
 		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__,
 		port->reg_lngth, cx_read(port->reg_lngth));
 	dprintk(1, "%s() hw_sop_ctrl(0x%08X)    0x%08x\n", __func__,
@@ -1042,6 +1156,9 @@
 	dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
 		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 */
 	cx23885_sram_channel_setup(dev,
 				   &dev->sram_channels[ port->sram_chno ],
@@ -1083,7 +1200,21 @@
 	cx_write(port->reg_gpcnt_ctl, 3);
 	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 = reg & ~0x1;    /* Clear TS1_OE */
@@ -1133,7 +1264,7 @@
 	cx_clear(port->reg_ts_int_msk, port->ts_int_msk_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);
 
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 043fc4e..ad2235d 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -33,6 +33,7 @@
 
 #include "cx23885.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
@@ -326,7 +327,7 @@
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 dev->name, type, cx23885_boards[dev->board].name);
@@ -1433,12 +1434,7 @@
 	.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_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1471,6 +1467,14 @@
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
 #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,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
@@ -1512,7 +1516,6 @@
 	memcpy(&cx23885_vbi_template, &cx23885_video_template,
 		sizeof(cx23885_vbi_template));
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
-	cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
 
 	dev->tvnorm = cx23885_video_template.current_norm;
 
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index 448f4cd..de515da 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,8 +1,6 @@
 config VIDEO_CX25840
 	tristate "Conexant CX2584x audio/video decoders"
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
-	depends on HOTPLUG # due to FW_LOADER
-	select FW_LOADER
 	---help---
 	  Support for the Conexant CX2584x audio/video decoders.
 
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index e7bf4f4..209d3bc 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -50,7 +50,7 @@
 
 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);
 
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 72916ba..b87337e 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -24,8 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 
-extern int cx25840_debug;
-
 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
    present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
    certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 10e20d8..9dd7bdf 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -33,9 +33,8 @@
 
 config VIDEO_CX88_BLACKBIRD
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
-	depends on VIDEO_CX88 && HOTPLUG
+	depends on VIDEO_CX88
 	select VIDEO_CX2341X
-	select FW_LOADER
 	---help---
 	  This adds support for MPEG encoder cards based on the
 	  Blackbird reference design, using the Conexant 2388x
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index bfdca58..9a1374a 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
 
 #include "cx88.h"
@@ -1174,12 +1175,7 @@
 	.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_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
@@ -1207,6 +1203,13 @@
 	.vidioc_g_tuner       = vidioc_g_tuner,
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.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,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index fa6d398..de199a2 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1348,7 +1348,7 @@
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = AUDIO_CHIP_WM8775,
+		.audio_chip     = V4L2_IDENT_WM8775,
 		.input		= {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 60eeda3..d656fec 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -40,6 +40,7 @@
 
 #include "cx88.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -1006,7 +1007,7 @@
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->dev     = &pci->dev;
+	vfd->parent  = &pci->dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 core->name, type, core->board.name);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 0fed5cd..ef4d56e 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -39,6 +39,7 @@
 
 #include "cx88.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
@@ -447,7 +448,7 @@
 		   the initialization. Some boards may use different
 		   routes for different inputs. HVR-1300 surely does */
 		if (core->board.audio_chip &&
-		    core->board.audio_chip == AUDIO_CHIP_WM8775) {
+		    core->board.audio_chip == V4L2_IDENT_WM8775) {
 			struct v4l2_routing route;
 
 			route.input = INPUT(input).audioroute;
@@ -1682,13 +1683,7 @@
 	.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_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1721,6 +1716,15 @@
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
 #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,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
@@ -1735,12 +1739,7 @@
 	.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_g_tuner       = radio_g_tuner,
 	.vidioc_enum_input    = radio_enum_input,
@@ -1759,6 +1758,13 @@
 #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)
@@ -1830,7 +1836,6 @@
 	memcpy( &cx8800_vbi_template, &cx8800_video_template,
 		sizeof(cx8800_vbi_template) );
 	strcpy(cx8800_vbi_template.name,"cx8800-vbi");
-	cx8800_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
 
 	/* initialize driver struct */
 	spin_lock_init(&dev->slock);
@@ -1866,7 +1871,7 @@
 
 	/* load and configure helper modules */
 
-	if (core->board.audio_chip == AUDIO_CHIP_WM8775)
+	if (core->board.audio_chip == V4L2_IDENT_WM8775)
 		request_module("wm8775");
 
 	switch (core->boardnr) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 14ac173..54fe650 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -29,8 +29,8 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
+#include <media/v4l2-chip-ident.h>
 #include <media/cx2341x.h>
-#include <media/audiochip.h>
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 #include <media/videobuf-dvb.h>
 #endif
@@ -252,7 +252,7 @@
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
-	enum audiochip          audio_chip;
+	unsigned int            audio_chip;
 };
 
 struct cx88_subid {
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 05f0d5a..476ae44 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -32,8 +32,8 @@
 #include <media/saa7115.h>
 #include <media/tvp5150.h>
 #include <media/tveeprom.h>
-#include <media/audiochip.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
 
 #include "em28xx.h"
 
@@ -52,6 +52,15 @@
 };
 
 struct em28xx_board em28xx_boards[] = {
+	[EM2750_BOARD_UNKNOWN] = {
+		.name          = "Unknown EM2750/EM2751 webcam grabber",
+		.vchannels     = 1,
+		.input         = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = 0,
+			.amux     = 0,
+		} },
+	},
 	[EM2800_BOARD_UNKNOWN] = {
 		.name         = "Unknown EM2800 video grabber",
 		.is_em2800    = 1,
@@ -73,6 +82,39 @@
 		.is_em2800    = 0,
 		.tuner_type   = TUNER_ABSENT,
 	},
+	[EM2750_BOARD_DLCW_130] = {
+		/* Beijing Huaqi Information Digital Technology Co., Ltd */
+		.name          = "Huaqi DLCW-130",
+		.valid         = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 1,
+		.input         = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = 0,
+			.amux     = 0,
+		} },
+	},
+	[EM2800_BOARD_KWORLD_USB2800] = {
+		.name         = "Kworld USB2800",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.is_em2800    = 1,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_PHILIPS_FCV1236D,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
 	[EM2820_BOARD_KWORLD_PVRTV2800RF] = {
 		.name         = "Kworld PVR TV 2800 RF",
 		.is_em2800    = 0,
@@ -151,6 +193,376 @@
 					MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
 		} },
 	},
+	[EM2820_BOARD_DLINK_USB_TV] = {
+		.name         = "D-Link DUB-T210 TV Tuner",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.is_em2800    = 0,
+		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
+		.name         = "Hercules Smart TV USB 2.0",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
+		.name         = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.is_em2800    = 0,
+		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_GADMEI_UTV310] = {
+		.name         = "Gadmei UTV310",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_TNF_5335MF,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
+		.name         = "Leadtek Winfast USB II Deluxe",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7114,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = 2,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = 0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = 9,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_PINNACLE_DVC_100] = {
+		.name         = "Pinnacle Dazzle DVC 100",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
+		.name          = "Videology 20K14XUSB USB2.0",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 1,
+		.input         = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = 0,
+			.amux     = 0,
+		} },
+	},
+	[EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
+		.name         = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.is_em2800    = 0,
+		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,	/* unknown? */
+		.tda9887_conf = TDA9887_PRESENT,	/* unknown? */
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2821_BOARD_SUPERCOMP_USB_2] = {
+		.name         = "Supercomp USB 2.0 TV",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.is_em2800    = 0,
+		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
+		.tda9887_conf = TDA9887_PRESENT |
+				TDA9887_PORT1_ACTIVE |
+				TDA9887_PORT2_ACTIVE,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2821_BOARD_USBGEAR_VD204] = {
+		.name          = "Usbgear VD204v9",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 2,
+		.decoder       = EM28XX_SAA7113,
+		.input          = { {
+			.type  = EM28XX_VMUX_COMPOSITE1,
+			.vmux  = SAA7115_COMPOSITE0,
+			.amux  = 1,
+		}, {
+			.type  = EM28XX_VMUX_SVIDEO,
+			.vmux  = SAA7115_SVIDEO3,
+			.amux  = 1,
+		} },
+	},
+	[EM2860_BOARD_NETGMBH_CAM] = {
+		/* Beijing Huaqi Information Digital Technology Co., Ltd */
+		.name          = "NetGMBH Cam",
+		.valid       = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 1,
+		.input         = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = 0,
+			.amux     = 0,
+		} },
+	},
+	[EM2860_BOARD_TYPHOON_DVD_MAKER] = {
+		.name          = "Typhoon DVD Maker",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 2,
+		.decoder       = EM28XX_SAA7113,
+		.input          = { {
+			.type  = EM28XX_VMUX_COMPOSITE1,
+			.vmux  = SAA7115_COMPOSITE0,
+			.amux  = 1,
+		}, {
+			.type  = EM28XX_VMUX_SVIDEO,
+			.vmux  = SAA7115_SVIDEO3,
+			.amux  = 1,
+		} },
+	},
+	[EM2860_BOARD_GADMEI_UTV330] = {
+		.name         = "Gadmei UTV330",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_TNF_5335MF,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
+	[EM2860_BOARD_TERRATEC_HYBRID_XS] = {
+		.name         = "Terratec Cinergy A Hybrid XS",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2861_BOARD_KWORLD_PVRTV_300U] = {
+		.name	      = "KWorld PVRTV 300U",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
+		.name          = "Yakumo MovieMixer",
+		.valid       = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels     = 1,
+		.decoder       = EM28XX_TVP5150,
+		.input         = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2861_BOARD_PLEXTOR_PX_TV100U] = {
+		.name         = "Plextor ConvertX PX-TV100U",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_TNF_5335MF,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2870_BOARD_TERRATEC_XS] = {
+		.name         = "Terratec Cinergy T XS",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type   = TUNER_XC2028,
+	},
+	[EM2870_BOARD_TERRATEC_XS_MT2060] = {
+		.name         = "Terratec Cinergy T XS (MT2060)",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type   = TUNER_ABSENT, /* MT2060 */
+	},
+	[EM2870_BOARD_KWORLD_350U] = {
+		.name         = "Kworld 350 U DVB-T",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type   = TUNER_XC2028,
+	},
+	[EM2870_BOARD_KWORLD_355U] = {
+		.name         = "Kworld 355 U DVB-T",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+	},
+	[EM2870_BOARD_PINNACLE_PCTV_DVB] = {
+		.name         = "Pinnacle PCTV DVB-T",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type   = TUNER_ABSENT, /* MT2060 */
+	},
+	[EM2870_BOARD_COMPRO_VIDEOMATE] = {
+		.name         = "Compro, VideoMate U3",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type   = TUNER_ABSENT, /* MT2060 */
+	},
+	[EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
+		.name         = "Terratec Hybrid XS Secam",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.has_msp34xx  = 1,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
 	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
 		.name         = "Hauppauge WinTV HVR 900",
 		.vchannels    = 3,
@@ -194,7 +606,7 @@
 			.amux     = 1,
 		} },
 	},
-	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
+	[EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
 		.name           = "Hauppauge WinTV HVR 950",
 		.vchannels      = 3,
 		.tda9887_conf   = TDA9887_PRESENT,
@@ -240,12 +652,36 @@
 			.amux     = 1,
 		} },
 	},
+	[EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
+		.name           = "AMD ATI TV Wonder HD 600",
+		.vchannels      = 3,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.tuner_type     = TUNER_XC2028,
+		.mts_firmware   = 1,
+		.has_12mhz_i2s  = 1,
+		.has_dvb        = 1,
+		.decoder        = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
 	[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
 		.name         = "Terratec Hybrid XS",
 		.vchannels    = 3,
 		.tda9887_conf = TDA9887_PRESENT,
 		.tuner_type   = TUNER_XC2028,
 		.decoder      = EM28XX_TVP5150,
+		.has_dvb        = 1,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -328,6 +764,21 @@
 			.amux     = 1,
 		} },
 	},
+	[EM2800_BOARD_GRABBEEX_USB2800] = {
+		.name         = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+		.is_em2800    = 1,
+		.vchannels    = 2,
+		.decoder      = EM28XX_SAA7113,
+		.input          = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = 1,
+		} },
+	},
 	[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
 		.name         = "Leadtek Winfast USB II",
 		.is_em2800    = 1,
@@ -439,13 +890,232 @@
 			.amux     = 0,
 		} },
 	},
+	[EM2880_BOARD_MSI_DIGIVOX_AD] = {
+		.name         = "MSI DigiVox A/D",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
+		.name         = "MSI DigiVox A/D II",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2880_BOARD_KWORLD_DVB_305U] = {
+		.name	      = "KWorld DVB-T 305U",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2880_BOARD_KWORLD_DVB_310U] = {
+		.name	      = "KWorld DVB-T 310U",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2881_BOARD_DNT_DA2_HYBRID] = {
+		.name         = "DNT DA2 Hybrid",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
+		.name         = "Pinnacle Hybrid Pro",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
+		.name         = "Pinnacle Hybrid Pro (2)",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2882_BOARD_KWORLD_VS_DVBT] = {
+		.name         = "Kworld VS-DVB-T 323UR",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
+		.name         = "Terratec Hybrid XS (em2882)",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2883_BOARD_KWORLD_HYBRID_A316] = {
+		.name         = "Kworld PlusTV HD Hybrid 330",
+		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+		.vchannels    = 3,
+		.is_em2800    = 0,
+		.tuner_type   = TUNER_XC2028,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = 0,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = 1,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = 1,
+		} },
+	},
+	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
+		.name         = "Compro VideoMate ForYou/Stereo",
+		.vchannels    = 2,
+		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_TVP5150,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		} },
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
 /* table of devices that work with this driver */
 struct usb_device_id em28xx_id_table [] = {
 	{ USB_DEVICE(0xeb1a, 0x2750),
-			.driver_info = EM2820_BOARD_UNKNOWN },
+			.driver_info = EM2750_BOARD_UNKNOWN },
+	{ USB_DEVICE(0xeb1a, 0x2751),
+			.driver_info = EM2750_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2800),
 			.driver_info = EM2800_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2820),
@@ -462,36 +1132,78 @@
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2883),
 			.driver_info = EM2820_BOARD_UNKNOWN },
+	{ USB_DEVICE(0xeb1a, 0xe300),
+			.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+	{ USB_DEVICE(0xeb1a, 0xe305),
+			.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
+	{ USB_DEVICE(0xeb1a, 0xe310),
+			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
+	{ USB_DEVICE(0xeb1a, 0xa316),
+			.driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+	{ USB_DEVICE(0xeb1a, 0xe320),
+			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
+	{ USB_DEVICE(0xeb1a, 0xe323),
+			.driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
+	{ USB_DEVICE(0xeb1a, 0xe350),
+			.driver_info = EM2870_BOARD_KWORLD_350U },
+	{ USB_DEVICE(0xeb1a, 0xe355),
+			.driver_info = EM2870_BOARD_KWORLD_355U },
+	{ USB_DEVICE(0xeb1a, 0x2801),
+			.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
+	{ USB_DEVICE(0xeb1a, 0xe357),
+			.driver_info = EM2870_BOARD_KWORLD_355U },
 	{ USB_DEVICE(0x0ccd, 0x0036),
 			.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
-	{ USB_DEVICE(0x2304, 0x0208),
-			.driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+	{ USB_DEVICE(0x0ccd, 0x004c),
+			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
+	{ USB_DEVICE(0x0ccd, 0x004f),
+			.driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
+	{ USB_DEVICE(0x0ccd, 0x005e),
+			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
+	{ USB_DEVICE(0x0ccd, 0x0042),
+			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+	{ USB_DEVICE(0x0ccd, 0x0043),
+			.driver_info = EM2870_BOARD_TERRATEC_XS },
+	{ USB_DEVICE(0x0ccd, 0x0047),
+			.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+	{ USB_DEVICE(0x185b, 0x2870),
+			.driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
+	{ USB_DEVICE(0x185b, 0x2041),
+			.driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
 	{ USB_DEVICE(0x2040, 0x4200),
 			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
 	{ USB_DEVICE(0x2040, 0x4201),
 			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
-	{ USB_DEVICE(0x2304, 0x0207),
-			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
-	{ USB_DEVICE(0x2304, 0x021a),
-			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
-	{ USB_DEVICE(0x2304, 0x0227),
-			.driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
 	{ USB_DEVICE(0x2040, 0x6500),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 	{ USB_DEVICE(0x2040, 0x6502),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
 	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
-			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
-			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
-			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
-			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
-	{ USB_DEVICE(0x0ccd, 0x0042),
-			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
-	{ USB_DEVICE(0x0ccd, 0x0047),
-			.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x0438, 0xb002),
+			.driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
+	{ USB_DEVICE(0x2001, 0xf112),
+			.driver_info = EM2820_BOARD_DLINK_USB_TV },
+	{ USB_DEVICE(0x2304, 0x0207),
+			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+	{ USB_DEVICE(0x2304, 0x0208),
+			.driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+	{ USB_DEVICE(0x2304, 0x021a),
+			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+	{ USB_DEVICE(0x2304, 0x0226),
+			.driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
+	{ USB_DEVICE(0x2304, 0x0227),
+			.driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
+	{ USB_DEVICE(0x0413, 0x6023),
+			.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
+	{ USB_DEVICE(0x093b, 0xa005),
+			.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -500,6 +1212,18 @@
  *  Reset sequences for analog/digital modes
  */
 
+/* Reset for the most [analog] boards */
+static struct em28xx_reg_seq default_analog[] = {
+	{EM28XX_R08_GPIO,	0x6d,   ~EM_GPIO_4,	10},
+	{	-1,		-1,	-1,		-1},
+};
+
+/* Reset for the most [digital] boards */
+static struct em28xx_reg_seq default_digital[] = {
+	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{	-1,		-1,	-1,		-1},
+};
+
 /* Board Hauppauge WinTV HVR 900 analog */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
 	{EM28XX_R08_GPIO,	0x2d,	~EM_GPIO_4,	10},
@@ -515,14 +1239,42 @@
 	{ -1,			-1,	-1,		-1},
 };
 
-/* Board Hauppauge WinTV HVR 900 tuner_callback */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
+	{EM28XX_R08_GPIO,       0x69,   ~EM_GPIO_4,	 10},
+	{	-1,		-1,	-1,		 -1},
+};
+
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = {
+	{EM28XX_R08_GPIO,	0x6a,	~EM_GPIO_4,	10},
+	{	-1,		-1,	-1,		-1},
+};
+
+/* Board  - EM2870 Kworld 355u
+   Analog - No input analog */
+static struct em28xx_reg_seq em2870_kworld_355u_digital[] = {
+	{EM2880_R04_GPO,	0x01,	0xff,		10},
+	{  -1,			-1,	-1,		-1},
+};
+
+/* Callback for the most boards */
+static struct em28xx_reg_seq default_callback[] = {
 	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
 	{EM28XX_R08_GPIO,	0,		EM_GPIO_4,	10},
 	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
 	{  -1,			-1,		-1,		-1},
 };
 
+/* Callback for EM2882 TERRATEC HYBRID XS */
+static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
+	{EM28XX_R08_GPIO,       0x2e,   0xff,		   6},
+	{EM28XX_R08_GPIO,       0x3e,   ~EM_GPIO_4,	   6},
+	{EM2880_R04_GPO,        0x04,   0xff,		  10},
+	{EM2880_R04_GPO,        0x0c,   0xff,		  10},
+	{  -1,			-1,	-1,		  -1},
+};
+
 /*
  * EEPROM hash table for devices with generic USB IDs
  */
@@ -569,6 +1321,7 @@
 	dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
 	dev->has_dvb = em28xx_boards[dev->model].has_dvb;
 	dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
+	dev->valid = em28xx_boards[dev->model].valid;
 }
 
 /* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -604,9 +1357,12 @@
 	case EM2880_BOARD_TERRATEC_PRODIGY_XS:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
-	case EM2880_BOARD_TERRATEC_HYBRID_XS:
-	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+	case EM2860_BOARD_TERRATEC_HYBRID_XS:
+	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+	case EM2882_BOARD_PINNACLE_HYBRID_PRO:
+	case EM2883_BOARD_KWORLD_HYBRID_A316:
+	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
 		em28xx_write_regs(dev, EM28XX_R0F_XCLK,    "\x27", 1);
 		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
 		msleep(50);
@@ -614,9 +1370,158 @@
 		/* Sets GPO/GPIO sequences for this device */
 		dev->analog_gpio      = hauppauge_wintv_hvr_900_analog;
 		dev->digital_gpio     = hauppauge_wintv_hvr_900_digital;
-		dev->tun_analog_gpio  = hauppauge_wintv_hvr_900_tuner_callback;
-		dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;
+		dev->tun_analog_gpio  = default_callback;
+		dev->tun_digital_gpio = default_callback;
+		break;
 
+	case EM2882_BOARD_TERRATEC_HYBRID_XS:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK,    "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		msleep(50);
+
+		/* should be added ir_codes here */
+
+		/* Sets GPO/GPIO sequences for this device */
+		dev->analog_gpio      = hauppauge_wintv_hvr_900_analog;
+		dev->digital_gpio     = hauppauge_wintv_hvr_900_digital;
+		dev->tun_analog_gpio  = default_callback;
+		dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital;
+		break;
+
+	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
+	case EM2880_BOARD_TERRATEC_HYBRID_XS:
+	case EM2870_BOARD_TERRATEC_XS:
+	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
+	case EM2880_BOARD_KWORLD_DVB_310U:
+	case EM2870_BOARD_KWORLD_350U:
+	case EM2881_BOARD_DNT_DA2_HYBRID:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK,    "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		msleep(50);
+
+		/* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital
+			 and analog commands. If this commands doesn't work,
+			 add this timer. */
+
+		/* Sets GPO/GPIO sequences for this device */
+		dev->analog_gpio      = default_analog;
+		dev->digital_gpio     = default_digital;
+		dev->tun_analog_gpio  = default_callback;
+		dev->tun_digital_gpio = default_callback;
+		break;
+
+	case EM2880_BOARD_MSI_DIGIVOX_AD:
+	case EM2880_BOARD_MSI_DIGIVOX_AD_II:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK,    "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		msleep(50);
+
+		/* Sets GPO/GPIO sequences for this device */
+		dev->analog_gpio      = em2880_msi_digivox_ad_analog;
+		dev->digital_gpio     = em2880_msi_digivox_ad_digital;
+		dev->tun_analog_gpio  = default_callback;
+		dev->tun_digital_gpio = default_callback;
+		break;
+
+	case EM2750_BOARD_UNKNOWN:
+	case EM2750_BOARD_DLCW_130:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1);
+		break;
+
+	case EM2861_BOARD_PLEXTOR_PX_TV100U:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* FIXME guess */
+		/* Turn on analog audio output */
+		em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+		break;
+
+	case EM2861_BOARD_KWORLD_PVRTV_300U:
+	case EM2880_BOARD_KWORLD_DVB_305U:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\x6d", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\x7d", 1);
+		msleep(10);
+		break;
+
+	case EM2870_BOARD_KWORLD_355U:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		msleep(50);
+
+		/* Sets GPO/GPIO sequences for this device */
+		dev->digital_gpio     = em2870_kworld_355u_digital;
+		break;
+
+	case EM2870_BOARD_COMPRO_VIDEOMATE:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* TODO: someone can do some cleanup here...
+			 not everything's needed */
+		em28xx_write_regs(dev, 0x04, "\x00", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x04, "\x01", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\xfd", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xfc", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xdc", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xfc", 1);
+		mdelay(70);
+		break;
+
+	case EM2870_BOARD_TERRATEC_XS_MT2060:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* this device needs some gpio writes to get the DVB-T
+		   demod work */
+		em28xx_write_regs(dev, 0x08, "\xfe", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xde", 1);
+		mdelay(70);
+		dev->em28xx_write_regs(dev, 0x08, "\xfe", 1);
+		mdelay(70);
+		break;
+
+	case EM2870_BOARD_PINNACLE_PCTV_DVB:
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* this device needs some gpio writes to get the
+		   DVB-T demod work */
+		em28xx_write_regs(dev, 0x08, "\xfe", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xde", 1);
+		mdelay(70);
+		em28xx_write_regs(dev, 0x08, "\xfe", 1);
+		mdelay(70);
+		/* switch em2880 rc protocol */
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1);
+		/* should be added ir_codes here */
+		break;
+
+	case EM2820_BOARD_GADMEI_UTV310:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* Turn on analog audio output */
+		em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+		break;
+
+	case EM2860_BOARD_GADMEI_UTV330:
+		/* Turn on IR */
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* should be added ir_codes here */
+		break;
+
+	case EM2820_BOARD_MSI_VOX_USB_2:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		/* enables audio for that device */
+		em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
 		break;
 	}
 
@@ -639,12 +1544,16 @@
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
+	case EM2880_BOARD_TERRATEC_HYBRID_XS:
+		ctl->demod = XC3028_FE_ZARLINK456;
+		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
 		/* djh - Not sure which demod we need here */
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
-	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
 		/* FIXME: Better to specify the needed IF */
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
@@ -809,6 +1718,8 @@
 		break;
 	case (EM2800_BOARD_KWORLD_USB2800):
 		break;
+	case (EM2800_BOARD_GRABBEEX_USB2800):
+		break;
 	}
 }
 
@@ -823,7 +1734,7 @@
 	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
-	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	{
 		struct tveeprom tv;
 #ifdef CONFIG_MODULES
@@ -836,7 +1747,7 @@
 
 		dev->tuner_type = tv.tuner_type;
 
-		if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+		if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
 			dev->i2s_speed = 2048000;
 			dev->has_msp34xx = 1;
 		}
@@ -854,11 +1765,21 @@
 	case EM2800_BOARD_UNKNOWN:
 		if (!em28xx_hint_board(dev))
 			em28xx_set_model(dev);
+		break;
 	}
 
 	if (dev->has_snapshot_button)
 		em28xx_register_snapshot_button(dev);
 
+	if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) {
+		em28xx_errdev("\n\n");
+		em28xx_errdev("The support for this board weren't "
+			      "valid yet.\n");
+		em28xx_errdev("Please send a report of having this working\n");
+		em28xx_errdev("not to V4L mailing list (and/or to other "
+				"addresses)\n\n");
+	}
+
 	/* Allow override tuner type by a module parameter */
 	if (tuner >= 0)
 		dev->tuner_type = tuner;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cc61cfb..4b992bc 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -6,6 +6,7 @@
  (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 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>
 
@@ -409,8 +410,9 @@
 	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	/* init frontend */
 	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_AMD_ATI_TV_WONDER_HD_600:
 		dvb->frontend = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
 					   &dev->i2c_adap);
@@ -441,6 +443,15 @@
 		}
 		break;
 #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:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
 				" isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 2d9f14d..49ab062 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -38,6 +38,7 @@
 
 #include "em28xx.h"
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
@@ -1763,20 +1764,7 @@
 	.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_enum_fmt_vid_cap    = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap       = vidioc_g_fmt_vid_cap,
@@ -1814,16 +1802,29 @@
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	.vidiocgmbuf                = vidiocgmbuf,
 #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,
 	.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_g_tuner       = radio_g_tuner,
 	.vidioc_enum_input    = radio_enum_input,
@@ -1842,6 +1843,13 @@
 #endif
 };
 
+static struct video_device em28xx_radio_template = {
+	.name                 = "em28xx-radio",
+	.fops                 = &radio_fops,
+	.ioctl_ops 	      = &radio_ioctl_ops,
+	.minor                = -1,
+};
+
 /******************************** usb interface ******************************/
 
 
@@ -1882,7 +1890,6 @@
 
 static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 					     const struct video_device *template,
-					     const int type,
 					     const char *type_name)
 {
 	struct video_device *vfd;
@@ -1892,9 +1899,8 @@
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->dev = &dev->udev->dev;
+	vfd->parent = &dev->udev->dev;
 	vfd->release = video_device_release;
-	vfd->type = type;
 	vfd->debug = video_debug;
 
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
@@ -1972,14 +1978,11 @@
 	list_add_tail(&dev->devlist, &em28xx_devlist);
 
 	/* 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) {
 		em28xx_errdev("cannot allocate video_device.\n");
 		goto fail_unreg;
 	}
-	if (dev->tuner_type != TUNER_ABSENT)
-		dev->vdev->type |= VID_TYPE_TUNER;
 
 	/* register v4l2 video video_device */
 	retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
@@ -1991,8 +1994,7 @@
 	}
 
 	/* 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 */
 	if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
 					vbi_nr[dev->devno]) < 0) {
@@ -2002,8 +2004,7 @@
 	}
 
 	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) {
 			em28xx_errdev("cannot allocate video_device.\n");
 			goto fail_unreg;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 89842c5..9a33107 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -54,15 +54,58 @@
 #define EM2880_BOARD_TERRATEC_PRODIGY_XS	13
 #define EM2820_BOARD_PROLINK_PLAYTV_USB2	14
 #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_HAUPPAUGE_WINTV_HVR_900_R2	18
 #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 */
 #define EM28XX_MIN_BUF 4
 #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 */
 #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 
@@ -251,6 +294,7 @@
 	unsigned int max_range_640_480:1;
 	unsigned int has_dvb:1;
 	unsigned int has_snapshot_button:1;
+	unsigned int valid:1;
 
 	enum em28xx_decoder decoder;
 
@@ -331,6 +375,7 @@
 	unsigned int max_range_640_480:1;
 	unsigned int has_dvb: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 */
 	unsigned int wait_after_write;
@@ -360,7 +405,7 @@
 	v4l2_std_id norm;	/* selected tv norm */
 	int ctl_freq;		/* selected frequency */
 	unsigned int ctl_input;	/* selected input */
-	unsigned int ctl_ainput;	/* slected audio input */
+	unsigned int ctl_ainput;/* selected audio input */
 	int mute;
 	int volume;
 	/* frame properties */
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 15d037a..2d170d1 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -34,6 +34,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/page-flags.h>
+#include <media/v4l2-ioctl.h>
 #include <asm/byteorder.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -985,7 +986,7 @@
 
 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;
 
 	if ((err = device_create_file(classdev, &dev_attr_reg)))
@@ -2584,8 +2585,6 @@
 	}
 
 	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->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 013d593..44b0bff 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -25,9 +25,6 @@
 #define CONEX_CAM 1		/* special JPEG header */
 #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_DESCRIPTION("GSPCA USB Conexant Camera Driver");
 MODULE_LICENSE("GPL");
@@ -818,7 +815,6 @@
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -1011,9 +1007,8 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 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);
@@ -1038,7 +1033,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 8ab4ea7..c8c2f02 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -22,9 +22,6 @@
 
 #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_DESCRIPTION("Etoms USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -602,26 +599,10 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	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->dev_name = (char *) id->driver_info;
 	cam->epaddr = 1;
+	sd->sensor = id->driver_info;
 	if (sd->sensor == SENSOR_PAS106) {
 		cam->cam_mode = sif_mode;
 		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
@@ -911,12 +892,11 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
 #ifndef CONFIG_USB_ET61X251
-	{USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
+	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
 #endif
-	{USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
+	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
 	{}
 };
 
@@ -942,7 +922,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 16e367c..3a051c9 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -32,6 +32,7 @@
 #include <asm/page.h>
 #include <linux/uaccess.h>
 #include <linux/jiffies.h>
+#include <media/v4l2-ioctl.h>
 
 #include "gspca.h"
 
@@ -42,8 +43,7 @@
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 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;
 
@@ -209,6 +209,8 @@
 				   &frame->v4l2_buf.timestamp);
 		frame->v4l2_buf.sequence = ++gspca_dev->sequence;
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
+		if (packet_type == LAST_PACKET)
+			gspca_dev->last_packet_type = packet_type;
 		return frame;
 	}
 
@@ -399,7 +401,7 @@
  * This routine may be called many times when the bandwidth is too small
  * (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_host_endpoint *ep;
@@ -832,7 +834,16 @@
 
 	memset(cap, 0, sizeof *cap);
 	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,
 		sizeof cap->bus_info);
 	cap->version = DRIVER_VERSION_NUMBER;
@@ -1649,12 +1660,7 @@
 	.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_dqbuf		= vidioc_dqbuf,
 	.vidioc_qbuf		= vidioc_qbuf,
@@ -1683,6 +1689,14 @@
 #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
  *
@@ -1740,10 +1754,11 @@
 
 	/* init video stuff */
 	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);
 	gspca_dev->vdev.fops = &gspca_dev->fops;
 	gspca_dev->fops.owner = module;		/* module protection */
+	gspca_dev->present = 1;
 	ret = video_register_device(&gspca_dev->vdev,
 				  VFL_TYPE_GRABBER,
 				  video_nr);
@@ -1752,7 +1767,6 @@
 		goto out;
 	}
 
-	gspca_dev->present = 1;
 	usb_set_intfdata(intf, gspca_dev);
 	PDEBUG(D_PROBE, "probe ok");
 	return 0;
@@ -1885,7 +1899,10 @@
 /* -- module insert / remove -- */
 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;
 }
 static void __exit gspca_exit(void)
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 88c2b02..21c4ee5 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -24,9 +24,6 @@
 #include "gspca.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_DESCRIPTION("GSPCA/Mars USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -140,7 +137,6 @@
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -424,9 +420,8 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 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);
@@ -451,7 +446,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 08d99c3..83139efc 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -24,9 +24,6 @@
 
 #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_DESCRIPTION("OV519 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -1375,7 +1372,6 @@
 		cam->cam_mode = sif_mode;
 		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->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
@@ -2129,21 +2125,20 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 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
@@ -2169,7 +2164,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index fa7abc4..7ef18d5 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -27,9 +27,6 @@
 
 #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_DESCRIPTION("Pixart PAC207");
 MODULE_LICENSE("GPL");
@@ -208,7 +205,7 @@
 }
 
 
-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;
 	int err;
@@ -223,8 +220,7 @@
 	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;
 	int res;
@@ -574,17 +570,16 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 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);
@@ -609,7 +604,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 5c052e3..ea3d702 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -23,9 +23,6 @@
 
 #include "gspca.h"
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
 MODULE_DESCRIPTION("Pixart PAC7311");
 MODULE_LICENSE("GPL");
@@ -266,7 +263,6 @@
 	reg_w(gspca_dev, 0x3e, 0x20);
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x05;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -713,16 +709,14 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")},
-	{USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")},
-	{USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")},
-	{USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")},
-	{USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")},
-			/* and also ', Trust WB-3350p, SIGMA cam 2350' */
-	{USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")},
-	{USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")},
+	{USB_DEVICE(0x093a, 0x2600)},
+	{USB_DEVICE(0x093a, 0x2601)},
+	{USB_DEVICE(0x093a, 0x2603)},
+	{USB_DEVICE(0x093a, 0x2608)},
+	{USB_DEVICE(0x093a, 0x260e)},
+	{USB_DEVICE(0x093a, 0x260f)},
+	{USB_DEVICE(0x093a, 0x2621)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -747,7 +741,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index dbeebe8..e18748c 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -24,9 +24,6 @@
 
 #include "gspca.h"
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 8)
-static const char version[] = "2.1.8";
-
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -44,25 +41,29 @@
 	unsigned char brightness;
 	unsigned char autogain;
 	unsigned char autogain_ignore_frames;
+	unsigned char frames_to_drop;
 	unsigned char freq;		/* light freq filter setting */
-	unsigned char saturation;
-	unsigned char hue;
-	unsigned char contrast;
 
 	unsigned char fr_h_sz;		/* size of frame header */
 	char sensor;			/* Type of image sensor chip */
 #define SENSOR_HV7131R 0
 #define SENSOR_OV6650 1
 #define SENSOR_OV7630 2
-#define SENSOR_OV7630_3 3
-#define SENSOR_PAS106 4
-#define SENSOR_PAS202 5
-#define SENSOR_TAS5110 6
-#define SENSOR_TAS5130CXX 7
+#define SENSOR_PAS106 3
+#define SENSOR_PAS202 4
+#define SENSOR_TAS5110 5
+#define SENSOR_TAS5130CXX 6
 	char sensor_has_gain;
 	__u8 sensor_addr;
+	__u8 reg11;
 };
 
+/* flags used in the device id table */
+#define F_GAIN 0x01		/* has gain */
+#define F_AUTO 0x02		/* has autogain */
+#define F_SIF  0x04		/* sif or vga */
+#define F_H18  0x08		/* long (18 b) or short (12 b) frame header */
+
 #define COMP2 0x8f
 #define COMP 0xc7		/* 0x87 //0x07 */
 #define COMP1 0xc9		/* 0x89 //0x09 */
@@ -92,12 +93,6 @@
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
 	{
@@ -174,48 +169,6 @@
 		.set = sd_setfreq,
 		.get = sd_getfreq,
 	},
-	{
-		{
-			.id      = V4L2_CID_SATURATION,
-			.type    = V4L2_CTRL_TYPE_INTEGER,
-			.name    = "Saturation",
-			.minimum = 0,
-			.maximum = 255,
-			.step    = 1,
-#define SATURATION_DEF 127
-			.default_value = SATURATION_DEF,
-		},
-		.set = sd_setsaturation,
-		.get = sd_getsaturation,
-	},
-	{
-		{
-			.id      = V4L2_CID_HUE,
-			.type    = V4L2_CTRL_TYPE_INTEGER,
-			.name    = "Hue",
-			.minimum = 0,
-			.maximum = 255,
-			.step    = 1,
-#define HUE_DEF 127
-			.default_value = HUE_DEF,
-		},
-		.set = sd_sethue,
-		.get = sd_gethue,
-	},
-	{
-		{
-			.id      = V4L2_CID_CONTRAST,
-			.type    = V4L2_CTRL_TYPE_INTEGER,
-			.name    = "Contrast",
-			.minimum = 0,
-			.maximum = 255,
-			.step    = 1,
-#define CONTRAST_DEF 127
-			.default_value = CONTRAST_DEF,
-		},
-		.set = sd_setcontrast,
-		.get = sd_getcontrast,
-	},
 };
 
 static struct v4l2_pix_format vga_mode[] = {
@@ -248,8 +201,6 @@
 		.priv = 0},
 };
 
-static const __u8 probe_ov7630[] = {0x08, 0x44};
-
 static const __u8 initHv7131[] = {
 	0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
@@ -321,7 +272,7 @@
 	0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
 	0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
 };
-static const __u8 ov7630_sensor_init_com[][8] = {
+static const __u8 ov7630_sensor_init[][8] = {
 	{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 	{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
 /*	{0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},	   jfm */
@@ -342,17 +293,6 @@
 	{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
 	{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 };
-static const __u8 ov7630_sensor_init[][8] = {
-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
-	{0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10},	/* jfm */
-	{0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
-	{0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
-	{0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},	/* gain */
-};
-static const __u8 ov7630_sensor_init_3[][8] = {
-	{0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
-	{0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
-};
 
 static const __u8 initPas106[] = {
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
@@ -542,7 +482,6 @@
 
 	switch (sd->sensor) {
 	case  SENSOR_OV6650:
-	case  SENSOR_OV7630_3:
 	case  SENSOR_OV7630: {
 		__u8 i2cOV[] =
 			{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
@@ -635,7 +574,7 @@
 	case SENSOR_OV6650:
 		gain >>= 1;
 		/* fall thru */
-	case SENSOR_OV7630_3: {
+	case SENSOR_OV7630: {
 		__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
 
 		i2c[1] = sd->sensor_addr;
@@ -690,7 +629,7 @@
 		break;
 	    }
 	case SENSOR_OV6650:
-	case SENSOR_OV7630_3: {
+	case SENSOR_OV7630: {
 		/* The ov6650 / ov7630 have 2 registers which both influence
 		   exposure, register 11, whose low nibble sets the nr off fps
 		   according to: fps = 30 / (low_nibble + 1)
@@ -705,16 +644,20 @@
 		   The code maps our 0 - 510 ms exposure ctrl to these 2
 		   registers, trying to keep fps as high as possible.
 		*/
-		__u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
-		int reg10, reg11;
+		__u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
+		int reg10, reg11, reg10_max;
+
 		/* ov6645 datasheet says reg10_max is 9a, but that uses
 		   tline * 2 * reg10 as formula for calculating texpo, the
 		   ov6650 probably uses the same formula as the 7730 which uses
 		   tline * 4 * reg10, which explains why the reg10max we've
 		   found experimentally for the ov6650 is exactly half that of
 		   the ov6645. The ov7630 datasheet says the max is 0x41. */
-		const int reg10_max = (sd->sensor == SENSOR_OV6650)
-				? 0x4d : 0x41;
+		if (sd->sensor == SENSOR_OV6650) {
+			reg10_max = 0x4d;
+			i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
+		} else
+			reg10_max = 0x41;
 
 		reg11 = (60 * sd->exposure + 999) / 1000;
 		if (reg11 < 1)
@@ -735,20 +678,23 @@
 		else if (reg10 > reg10_max)
 			reg10 = reg10_max;
 
+		/* In 640x480, if the reg11 has less than 3, the image is
+		   unstable (not enough bandwidth). */
+		if (gspca_dev->width == 640 && reg11 < 3)
+			reg11 = 3;
+
 		/* Write reg 10 and reg11 low nibble */
 		i2c[1] = sd->sensor_addr;
 		i2c[3] = reg10;
 		i2c[4] |= reg11 - 1;
-		if (sd->sensor == SENSOR_OV7630_3) {
-			__u8 reg76 = reg10 & 0x03;
-			__u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
-					    0x00, 0x00, 0x00, 0x10};
-			reg10 >>= 2;
-			i2c_reg76[3] = reg76;
-			if (i2c_w(gspca_dev, i2c_reg76) < 0)
-				PDEBUG(D_ERR, "i2c error exposure");
-		}
-		if (i2c_w(gspca_dev, i2c) < 0)
+
+		/* If register 11 didn't change, don't change it */
+		if (sd->reg11 == reg11 )
+			i2c[0] = 0xa0;
+
+		if (i2c_w(gspca_dev, i2c) == 0)
+			sd->reg11 = reg11;
+		else
 			PDEBUG(D_ERR, "i2c error exposure");
 		break;
 	    }
@@ -761,11 +707,11 @@
 
 	switch (sd->sensor) {
 	case SENSOR_OV6650:
-	case SENSOR_OV7630_3: {
+	case SENSOR_OV7630: {
 		/* Framerate adjust register for artificial light 50 hz flicker
-		   compensation, identical to ov6630 0x2b register, see ov6630
-		   datasheet.
-		   0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
+		   compensation, for the ov6650 this is identical to ov6630
+		   0x2b register, see ov6630 datasheet.
+		   0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
 		__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
 		switch (sd->freq) {
 		default:
@@ -786,69 +732,6 @@
 	}
 }
 
-static void setsaturation(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->sensor) {
-/*	case SENSOR_OV6650: */
-	case SENSOR_OV7630_3:
-	case SENSOR_OV7630: {
-		__u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
-		i2c[1] = sd->sensor_addr;
-		i2c[3] = sd->saturation & 0xf0;
-		if (i2c_w(gspca_dev, i2c) < 0)
-			PDEBUG(D_ERR, "i2c error setsaturation");
-		else
-			PDEBUG(D_CONF, "saturation set to: %d",
-				(int)sd->saturation);
-		break;
-	    }
-	}
-}
-
-static void sethue(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->sensor) {
-/*	case SENSOR_OV6650: */
-	case SENSOR_OV7630_3:
-	case SENSOR_OV7630: {
-		__u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
-		i2c[1] = sd->sensor_addr;
-		i2c[3] = 0x20 | (sd->hue >> 3);
-		if (i2c_w(gspca_dev, i2c) < 0)
-			PDEBUG(D_ERR, "i2c error setsaturation");
-		else
-			PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
-		break;
-	    }
-	}
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->sensor) {
-/*	case SENSOR_OV6650: */
-	case SENSOR_OV7630_3:
-	case SENSOR_OV7630: {
-		__u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
-		i2c[1] = sd->sensor_addr;
-		i2c[3] = 0x20 | (sd->contrast >> 3);
-		if (i2c_w(gspca_dev, i2c) < 0)
-			PDEBUG(D_ERR, "i2c error setcontrast");
-		else
-			PDEBUG(D_CONF, "contrast set to: %d",
-				(int)sd->contrast);
-		break;
-	    }
-	}
-}
-
-
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -874,88 +757,32 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 product;
 	int sif = 0;
 
 	/* nctrls depends upon the sensor, so we use a per cam copy */
 	memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
 	gspca_dev->sd_desc = &sd->sd_desc;
 
-	sd->fr_h_sz = 12;		/* default size of the frame header */
-	sd->sd_desc.nctrls = 2;		/* default nb of ctrls */
-	sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
-
-	product = id->idProduct;
-/*	switch (id->idVendor) { */
-/*	case 0x0c45:				 * Sonix */
-		switch (product) {
-		case 0x6001:			/* SN9C102 */
-		case 0x6005:			/* SN9C101 */
-		case 0x6007:			/* SN9C101 */
-			sd->sensor = SENSOR_TAS5110;
-			sd->sensor_has_gain = 1;
-			sd->sd_desc.nctrls = 4;
-			sd->sd_desc.dq_callback = do_autogain;
-			sif = 1;
-			break;
-		case 0x6009:			/* SN9C101 */
-		case 0x600d:			/* SN9C101 */
-		case 0x6029:			/* SN9C101 */
-			sd->sensor = SENSOR_PAS106;
-			sif = 1;
-			break;
-		case 0x6011:			/* SN9C101 - SN9C101G */
-			sd->sensor = SENSOR_OV6650;
-			sd->sensor_has_gain = 1;
-			sd->sensor_addr = 0x60;
-			sd->sd_desc.nctrls = 5;
-			sd->sd_desc.dq_callback = do_autogain;
-			sif = 1;
-			break;
-		case 0x6019:			/* SN9C101 */
-		case 0x602c:			/* SN9C102 */
-		case 0x602e:			/* SN9C102 */
-			sd->sensor = SENSOR_OV7630;
-			sd->sensor_addr = 0x21;
-			break;
-		case 0x60b0:			/* SN9C103 */
-			sd->sensor = SENSOR_OV7630_3;
-			sd->sensor_addr = 0x21;
-			sd->fr_h_sz = 18;	/* size of frame header */
-			sd->sensor_has_gain = 1;
-			sd->sd_desc.nctrls = 8;
-			sd->sd_desc.dq_callback = do_autogain;
-			sd->autogain = 0;
-			break;
-		case 0x6024:			/* SN9C102 */
-		case 0x6025:			/* SN9C102 */
-			sd->sensor = SENSOR_TAS5130CXX;
-			break;
-		case 0x6028:			/* SN9C102 */
-			sd->sensor = SENSOR_PAS202;
-			break;
-		case 0x602d:			/* SN9C102 */
-			sd->sensor = SENSOR_HV7131R;
-			break;
-		case 0x60af:			/* SN9C103 */
-			sd->sensor = SENSOR_PAS202;
-			sd->fr_h_sz = 18;	/* size of frame header (?) */
-			break;
-		}
-/*		break; */
-/*	} */
+	/* copy the webcam info from the device id */
+	sd->sensor = (id->driver_info >> 24) & 0xff;
+	if (id->driver_info & (F_GAIN << 16))
+		sd->sensor_has_gain = 1;
+	if (id->driver_info & (F_AUTO << 16))
+		sd->sd_desc.dq_callback = do_autogain;
+	if (id->driver_info & (F_SIF << 16))
+		sif = 1;
+	if (id->driver_info & (F_H18 << 16))
+		sd->fr_h_sz = 18;		/* size of frame header */
+	else
+		sd->fr_h_sz = 12;
+	sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
+	sd->sensor_addr = id->driver_info & 0xff;
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	if (!sif) {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = ARRAY_SIZE(vga_mode);
-		if (sd->sensor == SENSOR_OV7630_3) {
-			/* We only have 320x240 & 640x480 */
-			cam->cam_mode++;
-			cam->nmodes--;
-		}
 	} else {
 		cam->cam_mode = sif_mode;
 		cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -963,12 +790,9 @@
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
+	sd->autogain = AUTOGAIN_DEF;
 	sd->freq = FREQ_DEF;
-	sd->contrast = CONTRAST_DEF;
-	sd->saturation = SATURATION_DEF;
-	sd->hue = HUE_DEF;
-	if (sd->sensor == SENSOR_OV7630_3)	/* jfm: from win trace */
-		reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
+
 	return 0;
 }
 
@@ -1002,9 +826,8 @@
 static void sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int mode, l;
+	int mode, l = 0x1f;
 	const __u8 *sn9c10x;
-	__u8 reg01, reg17;
 	__u8 reg17_19[3];
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -1022,13 +845,11 @@
 		reg17_19[2] = 0x20;
 		break;
 	case SENSOR_OV7630:
-		sn9c10x = initOv7630;
-		reg17_19[0] = 0x68;
-		reg17_19[1] = (mode << 4) | COMP2;
-		reg17_19[2] = MCK_INIT1;
-		break;
-	case SENSOR_OV7630_3:
-		sn9c10x = initOv7630_3;
+		if (sd->fr_h_sz == 18) { /* SN9C103 */
+			sn9c10x = initOv7630_3;
+			l = sizeof initOv7630_3;
+		} else
+			sn9c10x = initOv7630;
 		reg17_19[0] = 0x68;
 		reg17_19[1] = (mode << 4) | COMP2;
 		reg17_19[2] = MCK_INIT1;
@@ -1059,30 +880,11 @@
 		reg17_19[2] = mode ? 0x23 : 0x43;
 		break;
 	}
-	switch (sd->sensor) {
-	case SENSOR_OV7630:
-		reg01 = 0x06;
-		reg17 = 0x29;
-		l = sizeof initOv7630;
-		break;
-	case SENSOR_OV7630_3:
-		reg01 = 0x44;
-		reg17 = 0x68;
-		l = sizeof initOv7630_3;
-		break;
-	default:
-		reg01 = sn9c10x[0];
-		reg17 = sn9c10x[0x17 - 1];
-		l = 0x1f;
-		break;
-	}
 
 	/* reg 0x01 bit 2 video transfert on */
-	reg_w(gspca_dev, 0x01, &reg01, 1);
+	reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
 	/* reg 0x17 SensorClk enable inv Clk 0x60 */
-	reg_w(gspca_dev, 0x17, &reg17, 1);
-/*fixme: for ov7630 102
-	reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
+	reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
 	/* Set the registers from the template */
 	reg_w_big(gspca_dev, 0x01, sn9c10x, l);
 	switch (sd->sensor) {
@@ -1095,17 +897,13 @@
 				sizeof ov6650_sensor_init);
 		break;
 	case SENSOR_OV7630:
-		i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
-				sizeof ov7630_sensor_init_com);
-		msleep(200);
 		i2c_w_vector(gspca_dev, ov7630_sensor_init,
 				sizeof ov7630_sensor_init);
-		break;
-	case SENSOR_OV7630_3:
-		i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
-				sizeof ov7630_sensor_init_com);
-		msleep(200);
-		i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
+		if (sd->fr_h_sz == 18) { /* SN9C103 */
+			const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
+						0x00, 0x00, 0x10 };
+			i2c_w(gspca_dev, i2c);
+		}
 		break;
 	case SENSOR_PAS106:
 		pas106_i2cinit(gspca_dev);
@@ -1145,14 +943,14 @@
 	reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
 	msleep(20);
 
+	sd->reg11 = -1;
+
 	setgain(gspca_dev);
 	setbrightness(gspca_dev);
 	setexposure(gspca_dev);
 	setfreq(gspca_dev);
-	setsaturation(gspca_dev);
-	sethue(gspca_dev);
-	setcontrast(gspca_dev);
 
+	sd->frames_to_drop = 0;
 	sd->autogain_ignore_frames = 0;
 	atomic_set(&sd->avg_lum, -1);
 }
@@ -1198,21 +996,31 @@
 			    && data[3 + i] == 0xc4
 			    && data[4 + i] == 0xc4
 			    && data[5 + i] == 0x96) {	/* start of frame */
-				frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-							frame, data, 0);
+				int lum = -1;
+				int pkt_type = LAST_PACKET;
+
 				if (len - i < sd->fr_h_sz) {
-					atomic_set(&sd->avg_lum, -1);
 					PDEBUG(D_STREAM, "packet too short to"
 						" get avg brightness");
 				} else if (sd->fr_h_sz == 12) {
-					atomic_set(&sd->avg_lum,
-						data[i + 8] +
-							(data[i + 9] << 8));
+					lum = data[i + 8] + (data[i + 9] << 8);
 				} else {
-					atomic_set(&sd->avg_lum,
-						data[i + 9] +
-							(data[i + 10] << 8));
+					lum = data[i + 9] +
+						(data[i + 10] << 8);
 				}
+				if (lum == 0) {
+					lum = -1;
+					sd->frames_to_drop = 2;
+				}
+				atomic_set(&sd->avg_lum, lum);
+
+				if (sd->frames_to_drop) {
+					sd->frames_to_drop--;
+					pkt_type = DISCARD_PACKET;
+				}
+
+				frame = gspca_frame_add(gspca_dev, pkt_type,
+							frame, data, 0);
 				data += i + sd->fr_h_sz;
 				len -= i + sd->fr_h_sz;
 				gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -1327,60 +1135,6 @@
 	return 0;
 }
 
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->saturation = val;
-	if (gspca_dev->streaming)
-		setsaturation(gspca_dev);
-	return 0;
-}
-
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->saturation;
-	return 0;
-}
-
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->hue = val;
-	if (gspca_dev->streaming)
-		sethue(gspca_dev);
-	return 0;
-}
-
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->hue;
-	return 0;
-}
-
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->contrast = val;
-	if (gspca_dev->streaming)
-		setcontrast(gspca_dev);
-	return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->contrast;
-	return 0;
-}
-
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu)
 {
@@ -1418,27 +1172,47 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define SFCI(sensor, flags, nctrls, i2c_addr) \
+	.driver_info = (SENSOR_ ## sensor << 24) \
+			| ((flags) << 16) \
+			| ((nctrls) << 8) \
+			| (i2c_addr)
 static __devinitdata struct usb_device_id device_table[] = {
 #ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
-	{USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
-	{USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
-	{USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
-	{USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
+	{USB_DEVICE(0x0c45, 0x6001),			/* SN9C102 */
+			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+	{USB_DEVICE(0x0c45, 0x6005),			/* SN9C101 */
+			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+	{USB_DEVICE(0x0c45, 0x6007),			/* SN9C101 */
+			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+	{USB_DEVICE(0x0c45, 0x6009),			/* SN9C101 */
+			SFCI(PAS106, F_SIF, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x600d),			/* SN9C101 */
+			SFCI(PAS106, F_SIF, 2, 0)},
 #endif
-	{USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
+	{USB_DEVICE(0x0c45, 0x6011),		/* SN9C101 - SN9C101G */
+			SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
 #ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
-	{USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
-	{USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
-	{USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
-	{USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
-	{USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
-	{USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
-	{USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
-	{USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
-	{USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
+	{USB_DEVICE(0x0c45, 0x6019),			/* SN9C101 */
+			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+	{USB_DEVICE(0x0c45, 0x6024),			/* SN9C102 */
+			SFCI(TAS5130CXX, 0, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x6025),			/* SN9C102 */
+			SFCI(TAS5130CXX, 0, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x6028),			/* SN9C102 */
+			SFCI(PAS202, 0, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x6029),			/* SN9C101 */
+			SFCI(PAS106, F_SIF, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x602c),			/* SN9C102 */
+			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+	{USB_DEVICE(0x0c45, 0x602d),			/* SN9C102 */
+			SFCI(HV7131R, 0, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x602e),			/* SN9C102 */
+			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+	{USB_DEVICE(0x0c45, 0x60af),			/* SN9C103 */
+			SFCI(PAS202, F_H18, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x60b0),			/* SN9C103 */
+			SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
 #endif
 	{}
 };
@@ -1464,7 +1238,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3e68b99..33a3df1 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,9 +24,6 @@
 #include "gspca.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_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -361,6 +358,7 @@
 };
 static const __u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
+/*		(delay 20ms) */
 	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
 						/* Outformat ?? rawRGB */
 	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -539,13 +537,31 @@
 			value, 0,
 			gspca_dev->usb_buf, len,
 			500);
+	PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
 }
 
+static void reg_w1(struct gspca_dev *gspca_dev,
+		   __u16 value,
+		   __u8 data)
+{
+	PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+	gspca_dev->usb_buf[0] = data;
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			value,
+			0,
+			gspca_dev->usb_buf, 1,
+			500);
+}
 static void reg_w(struct gspca_dev *gspca_dev,
 			  __u16 value,
 			  const __u8 *buffer,
 			  int len)
 {
+	PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+		value, buffer[0], buffer[1]);
 	if (len <= sizeof gspca_dev->usb_buf) {
 		memcpy(gspca_dev->usb_buf, buffer, len);
 		usb_control_msg(gspca_dev->dev,
@@ -571,31 +587,42 @@
 	}
 }
 
-/* I2C write 2 bytes */
-static void i2c_w2(struct gspca_dev *gspca_dev,
-		   const __u8 *buffer)
+/* I2C write 1 byte */
+static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 mode[8];
 
-	/* is i2c ready */
-	mode[0] = 0x81 | (2 << 4);
-	mode[1] = sd->i2c_base;
-	mode[2] = buffer[0];
-	mode[3] = buffer[1];
-	mode[4] = 0;
-	mode[5] = 0;
-	mode[6] = 0;
-	mode[7] = 0x10;
-	reg_w(gspca_dev, 0x08, mode, 8);
+	PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
+	gspca_dev->usb_buf[0] = 0x81 | (2 << 4);	/* = a1 */
+	gspca_dev->usb_buf[1] = sd->i2c_base;
+	gspca_dev->usb_buf[2] = reg;
+	gspca_dev->usb_buf[3] = val;
+	gspca_dev->usb_buf[4] = 0;
+	gspca_dev->usb_buf[5] = 0;
+	gspca_dev->usb_buf[6] = 0;
+	gspca_dev->usb_buf[7] = 0x10;
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			0x08,			/* value = i2c */
+			0,
+			gspca_dev->usb_buf, 8,
+			500);
 }
 
 /* I2C write 8 bytes */
 static void i2c_w8(struct gspca_dev *gspca_dev,
 		   const __u8 *buffer)
 {
-	reg_w(gspca_dev, 0x08, buffer, 8);
-	msleep(1);
+	memcpy(gspca_dev->usb_buf, buffer, 8);
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			0x08, 0,		/* value, index */
+			gspca_dev->usb_buf, 8,
+			500);
 }
 
 /* read 5 bytes in gspca_dev->usb_buf */
@@ -613,24 +640,21 @@
 	mode[6] = 0;
 	mode[7] = 0x10;
 	i2c_w8(gspca_dev, mode);
+	msleep(2);
 	mode[0] = 0x81 | (5 << 4) | 0x02;
 	mode[2] = 0;
 	i2c_w8(gspca_dev, mode);
+	msleep(2);
 	reg_r(gspca_dev, 0x0a, 5);
 }
 
 static int probesensor(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 reg02;
-	static const __u8 datasend[] = { 2, 0 };
-	/* reg val1 val2 val3 val4 */
 
-	i2c_w2(gspca_dev, datasend);
-/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
+	i2c_w1(gspca_dev, 0x02, 0);			/* sensor wakeup */
 	msleep(10);
-	reg02 = 0x66;
-	reg_w(gspca_dev, 0x02, &reg02, 1);		/* Gpio on */
+	reg_w1(gspca_dev, 0x02, 0x66);			/* Gpio on */
 	msleep(10);
 	i2c_r5(gspca_dev, 0);				/* read sensor id */
 	if (gspca_dev->usb_buf[0] == 0x02
@@ -642,7 +666,7 @@
 		sd->sensor = SENSOR_HV7131R;
 		return SENSOR_HV7131R;
 	}
-	PDEBUG(D_PROBE, "Find Sensor %d %d %d",
+	PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
 		gspca_dev->usb_buf[2]);
 	PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
@@ -653,8 +677,6 @@
 			  const __u8 *sn9c1xx)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 data;
-	__u8 regF1;
 	const __u8 *reg9a;
 	static const __u8 reg9a_def[] =
 		{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
@@ -663,15 +685,13 @@
 	static const __u8 reg9a_sn9c325[] =
 		{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
 
-
-	regF1 = 0x00;
-	reg_w(gspca_dev, 0xf1, &regF1, 1);
-	reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/
+	reg_w1(gspca_dev, 0xf1, 0x00);
+	reg_w1(gspca_dev, 0x01, sn9c1xx[0]);	/*fixme:jfm was [1] en v1*/
 
 	/* configure gpio */
 	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
 	reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
-	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);	/* jfm was 3 */
+	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);	/* jfm len was 3 */
 	switch (sd->bridge) {
 	case BRIDGE_SN9C325:
 		reg9a = reg9a_sn9c325;
@@ -685,35 +705,25 @@
 	}
 	reg_w(gspca_dev, 0x9a, reg9a, 6);
 
-	data = 0x60;				/*fixme:jfm 60 00 00 (3) */
-	reg_w(gspca_dev, 0xd4, &data, 1);
+	reg_w1(gspca_dev, 0xd4, 0x60);	/*fixme:jfm 60 00 00 (3) ? */
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
 	switch (sd->bridge) {
 	case BRIDGE_SN9C120:			/* from win trace */
-		data = 0x61;
-		reg_w(gspca_dev, 0x01, &data, 1);
-		data = 0x20;
-		reg_w(gspca_dev, 0x17, &data, 1);
-		data = 0x60;
-		reg_w(gspca_dev, 0x01, &data, 1);
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x60);
 		break;
 	case BRIDGE_SN9C325:
-		data = 0x43;
-		reg_w(gspca_dev, 0x01, &data, 1);
-		data = 0xae;
-		reg_w(gspca_dev, 0x17, &data, 1);
-		data = 0x42;
-		reg_w(gspca_dev, 0x01, &data, 1);
+		reg_w1(gspca_dev, 0x01, 0x43);
+		reg_w1(gspca_dev, 0x17, 0xae);
+		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
 	default:
-		data = 0x43;
-		reg_w(gspca_dev, 0x01, &data, 1);
-		data = 0x61;
-		reg_w(gspca_dev, 0x17, &data, 1);
-		data = 0x42;
-		reg_w(gspca_dev, 0x01, &data, 1);
+		reg_w1(gspca_dev, 0x01, 0x43);
+		reg_w1(gspca_dev, 0x17, 0x61);
+		reg_w1(gspca_dev, 0x01, 0x42);
 	}
 
 	if (sd->sensor == SENSOR_HV7131R) {
@@ -770,6 +780,9 @@
 {
 	int i = 0;
 
+	i2c_w8(gspca_dev, ov7660_sensor_init[i]);	/* reset SCCB */
+	i++;
+	msleep(20);
 	while (ov7660_sensor_init[i][0]) {
 		i2c_w8(gspca_dev, ov7660_sensor_init[i]);
 		i++;
@@ -782,194 +795,16 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
-
-	vendor = id->idVendor;
-	product = id->idProduct;
-	sd->sensor = -1;
-	switch (vendor) {
-	case 0x0458:				/* Genius */
-/*		switch (product) {
-		case 0x7025: */
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_MI0360;
-			sd->i2c_base = 0x5d;
-/*			break;
-		} */
-		break;
-	case 0x045e:
-/*		switch (product) {
-		case 0x00f5:
-		case 0x00f7: */
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_OV7660;
-			sd->i2c_base = 0x21;
-/*			break;
-		} */
-		break;
-	case 0x0471:				/* Philips */
-/*		switch (product) {
-		case 0x0327:
-		case 0x0328:
-		case 0x0330: */
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_MI0360;
-			sd->i2c_base = 0x5d;
-/*			break;
-		} */
-		break;
-	case 0x0c45:				/* Sonix */
-		switch (product) {
-		case 0x6040:
-			sd->bridge = BRIDGE_SN9C102P;
-/*			sd->sensor = SENSOR_MI0360;	 * from BW600.inf */
-/*fixme: MI0360 base=5d ? */
-			sd->sensor = SENSOR_HV7131R;	/* gspcav1 value */
-			sd->i2c_base = 0x11;
-			break;
-/*		case 0x607a:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C102P;
-			sd->sensor = SENSOR_OV7648;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x607c:
-			sd->bridge = BRIDGE_SN9C102P;
-			sd->sensor = SENSOR_HV7131R;
-			sd->i2c_base = 0x11;
-			break;
-/*		case 0x607e:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C102P;
-			sd->sensor = SENSOR_OV7630;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x60c0:
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_MI0360;
-			sd->i2c_base = 0x5d;
-			break;
-/*		case 0x60c8:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_OM6801;
-			sd->i2c_base = 0x??;
-			break; */
-/*		case 0x60cc:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_HV7131GP;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x60ec:
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_MO4000;
-			sd->i2c_base = 0x21;
-			break;
-/*		case 0x60ef:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_ICM105C;
-			sd->i2c_base = 0x??;
-			break; */
-/*		case 0x60fa:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_OV7648;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x60fb:
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_OV7660;
-			sd->i2c_base = 0x21;
-			break;
-		case 0x60fc:
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_HV7131R;
-			sd->i2c_base = 0x11;
-			break;
-/*		case 0x60fe:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C105;
-			sd->sensor = SENSOR_OV7630;
-			sd->i2c_base = 0x??;
-			break; */
-/*		case 0x6108:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_OM6801;
-			sd->i2c_base = 0x??;
-			break; */
-/*		case 0x6122:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C110;
-			sd->sensor = SENSOR_ICM105C;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x612a:
-/*			sd->bridge = BRIDGE_SN9C110;	 * in BW600.inf */
-			sd->bridge = BRIDGE_SN9C325;
-			sd->sensor = SENSOR_OV7648;
-			sd->i2c_base = 0x21;
-/*fixme: sensor_init has base = 00 et 6e!*/
-			break;
-/*		case 0x6123:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C110;
-			sd->sensor = SENSOR_SanyoCCD;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x612c:
-			sd->bridge = BRIDGE_SN9C110;
-			sd->sensor = SENSOR_MO4000;
-			sd->i2c_base = 0x21;
-			break;
-/*		case 0x612e:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C110;
-			sd->sensor = SENSOR_OV7630;
-			sd->i2c_base = 0x??;
-			break; */
-/*		case 0x612f:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C110;
-			sd->sensor = SENSOR_ICM105C;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x6130:
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_MI0360;
-			sd->i2c_base = 0x5d;
-			break;
-		case 0x6138:
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_MO4000;
-			sd->i2c_base = 0x21;
-			break;
-/*		case 0x613a:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_OV7648;
-			sd->i2c_base = 0x??;
-			break; */
-		case 0x613b:
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_OV7660;
-			sd->i2c_base = 0x21;
-			break;
-		case 0x613c:
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_HV7131R;
-			sd->i2c_base = 0x11;
-			break;
-/*		case 0x613e:				* from BW600.inf
-			sd->bridge = BRIDGE_SN9C120;
-			sd->sensor = SENSOR_OV7630;
-			sd->i2c_base = 0x??;
-			break; */
-		}
-		break;
-	}
-	if (sd->sensor < 0) {
-		PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
-			vendor, product);
-		return -EINVAL;
-	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
 
+	sd->bridge = id->driver_info >> 16;
+	sd->sensor = id->driver_info >> 8;
+	sd->i2c_base = id->driver_info;
+
 	sd->qindex = 4;			/* set the quantization table */
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
@@ -983,34 +818,26 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 /*	const __u8 *sn9c1xx; */
-	__u8 regF1;
 	__u8 regGpio[] = { 0x29, 0x74 };
+	__u8 regF1;
 
 	/* setup a selector by bridge */
-	regF1 = 0x01;
-	reg_w(gspca_dev, 0xf1, &regF1, 1);
+	reg_w1(gspca_dev, 0xf1, 0x01);
 	reg_r(gspca_dev, 0x00, 1);		/* -> regF1 = 0x00 */
-	regF1 = gspca_dev->usb_buf[0];
-	reg_w(gspca_dev, 0xf1, &regF1, 1);
+	reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
 	reg_r(gspca_dev, 0x00, 1);
 	regF1 = gspca_dev->usb_buf[0];
 	switch (sd->bridge) {
 	case BRIDGE_SN9C102P:
 		if (regF1 != 0x11)
 			return -ENODEV;
-		reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+		reg_w1(gspca_dev, 0x02, regGpio[1]);
 		break;
 	case BRIDGE_SN9C105:
 		if (regF1 != 0x11)
 			return -ENODEV;
 		reg_w(gspca_dev, 0x02, regGpio, 2);
 		break;
-	case BRIDGE_SN9C110:
-		if (regF1 != 0x12)
-			return -ENODEV;
-		regGpio[1] = 0x62;
-		reg_w(gspca_dev, 0x02, &regGpio[1], 1);
-		break;
 	case BRIDGE_SN9C120:
 		if (regF1 != 0x12)
 			return -ENODEV;
@@ -1018,16 +845,15 @@
 		reg_w(gspca_dev, 0x02, regGpio, 2);
 		break;
 	default:
+/*	case BRIDGE_SN9C110: */
 /*	case BRIDGE_SN9C325: */
 		if (regF1 != 0x12)
 			return -ENODEV;
-		regGpio[1] = 0x62;
-		reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
 	}
 
-	regF1 = 0x01;
-	reg_w(gspca_dev, 0xf1, &regF1, 1);
+	reg_w1(gspca_dev, 0xf1, 0x01);
 
 	return 0;
 }
@@ -1123,7 +949,7 @@
 	}
 
 	k2 = sd->brightness >> 10;
-	reg_w(gspca_dev, 0x96, &k2, 1);
+	reg_w1(gspca_dev, 0x96, k2);
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1152,7 +978,7 @@
 		data = (colour + 32) & 0x7f;	/* blue */
 	else
 		data = (-colour + 32) & 0x7f;	/* red */
-	reg_w(gspca_dev, 0x05, &data, 1);
+	reg_w1(gspca_dev, 0x05, data);
 }
 
 /* -- start the camera -- */
@@ -1165,7 +991,6 @@
 	__u8 reg17;
 	const __u8 *sn9c1xx;
 	int mode;
-	static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
 	static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
 	static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
 	static const __u8 CA_sn9c120[] =
@@ -1179,21 +1004,20 @@
 
 /*fixme:jfm this sequence should appear at end of sd_start */
 /* with
-	data = 0x44;
-	reg_w(gspca_dev, 0x01, &data, 1); */
-	reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1);
-	reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1);
-	reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1);
-	reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1);
-	reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
-	reg_w(gspca_dev, 0xd2, &DC29[0], 1);
-	reg_w(gspca_dev, 0xd3, &DC29[1], 1);
-	reg_w(gspca_dev, 0xc6, &DC29[2], 1);
-	reg_w(gspca_dev, 0xc7, &DC29[3], 1);
-	reg_w(gspca_dev, 0xc8, &DC29[4], 1);
-	reg_w(gspca_dev, 0xc9, &DC29[5], 1);
+	reg_w1(gspca_dev, 0x01, 0x44); */
+	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
+	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
+	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
+	reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
+	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
+	reg_w1(gspca_dev, 0xd2, 0x6a);		/* DC29 */
+	reg_w1(gspca_dev, 0xd3, 0x50);
+	reg_w1(gspca_dev, 0xc6, 0x00);
+	reg_w1(gspca_dev, 0xc7, 0x00);
+	reg_w1(gspca_dev, 0xc8, 0x50);
+	reg_w1(gspca_dev, 0xc9, 0x3c);
 /*fixme:jfm end of ending sequence */
-	reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
+	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
 	switch (sd->bridge) {
 	case BRIDGE_SN9C325:
 		data = 0xae;
@@ -1205,11 +1029,11 @@
 		data = 0x60;
 		break;
 	}
-	reg_w(gspca_dev, 0x17, &data, 1);
-	reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1);
-	reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1);
-	reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1);
-	reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1);
+	reg_w1(gspca_dev, 0x17, data);
+	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
+	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
+	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
+	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
 	switch (sd->bridge) {
 	case BRIDGE_SN9C325:
 		reg_w(gspca_dev, 0x20, regsn20_sn9c325,
@@ -1217,10 +1041,8 @@
 		for (i = 0; i < 8; i++)
 			reg_w(gspca_dev, 0x84, reg84_sn9c325,
 					sizeof reg84_sn9c325);
-		data = 0x0a;
-		reg_w(gspca_dev, 0x9a, &data, 1);
-		data = 0x60;
-		reg_w(gspca_dev, 0x99, &data, 1);
+		reg_w1(gspca_dev, 0x9a, 0x0a);
+		reg_w1(gspca_dev, 0x99, 0x60);
 		break;
 	case BRIDGE_SN9C120:
 		reg_w(gspca_dev, 0x20, regsn20_sn9c120,
@@ -1233,39 +1055,30 @@
 					sizeof reg84_sn9c120_2);
 		reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
 				sizeof reg84_sn9c120_3);
-		data = 0x05;
-		reg_w(gspca_dev, 0x9a, &data, 1);
-		data = 0x5b;
-		reg_w(gspca_dev, 0x99, &data, 1);
+		reg_w1(gspca_dev, 0x9a, 0x05);
+		reg_w1(gspca_dev, 0x99, 0x5b);
 		break;
 	default:
 		reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
 		for (i = 0; i < 8; i++)
 			reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
-		data = 0x08;
-		reg_w(gspca_dev, 0x9a, &data, 1);
-		data = 0x59;
-		reg_w(gspca_dev, 0x99, &data, 1);
+		reg_w1(gspca_dev, 0x9a, 0x08);
+		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
 	}
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
-	reg1 = 0x02;
+	if (mode)
+		reg1 = 0x46;	/* 320 clk 48Mhz */
+	else
+		reg1 = 0x06;	/* 640 clk 24Mz */
 	reg17 = 0x61;
 	switch (sd->sensor) {
 	case SENSOR_HV7131R:
 		hv7131R_InitSensor(gspca_dev);
-		if (mode)
-			reg1 = 0x46;	/* 320 clk 48Mhz */
-		else
-			reg1 = 0x06;	/* 640 clk 24Mz */
 		break;
 	case SENSOR_MI0360:
 		mi0360_InitSensor(gspca_dev);
-		if (mode)
-			reg1 = 0x46;	/* 320 clk 48Mhz */
-		else
-			reg1 = 0x06;	/* 640 clk 24Mz */
 		break;
 	case SENSOR_MO4000:
 		mo4000_InitSensor(gspca_dev);
@@ -1274,13 +1087,13 @@
 			reg1 = 0x06;	/* clk 24Mz */
 		} else {
 			reg17 = 0x22;	/* 640 MCKSIZE */
-			reg1 = 0x06;	/* 640 clk 24Mz */
+/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
 		}
 		break;
 	case SENSOR_OV7648:
+		ov7648_InitSensor(gspca_dev);
 		reg17 = 0xa2;
 		reg1 = 0x44;
-		ov7648_InitSensor(gspca_dev);
 /*		if (mode)
 			;		 * 320x2...
 		else
@@ -1292,7 +1105,7 @@
 		if (mode) {
 /*			reg17 = 0x21;	 * 320 */
 /*			reg1 = 0x44; */
-			reg1 = 0x46;
+/*			reg1 = 0x46;	(done) */
 		} else {
 			reg17 = 0xa2;	/* 640 */
 			reg1 = 0x40;
@@ -1321,16 +1134,16 @@
 
 	/* here change size mode 0 -> VGA; 1 -> CIF */
 	data = 0x40 | sn9c1xx[0x18] | (mode << 4);
-	reg_w(gspca_dev, 0x18, &data, 1);
+	reg_w1(gspca_dev, 0x18, data);
 
 	reg_w(gspca_dev, 0x100, qtable4, 0x40);
 	reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
 
 	data = sn9c1xx[0x18] | (mode << 4);
-	reg_w(gspca_dev, 0x18, &data, 1);
+	reg_w1(gspca_dev, 0x18, data);
 
-	reg_w(gspca_dev, 0x17, &reg17, 1);
-	reg_w(gspca_dev, 0x01, &reg1, 1);
+	reg_w1(gspca_dev, 0x17, reg17);
+	reg_w1(gspca_dev, 0x01, reg1);
 	setbrightness(gspca_dev);
 	setcontrast(gspca_dev);
 }
@@ -1342,7 +1155,6 @@
 		{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
 	static const __u8 stopmi0360[] =
 		{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
-	__u8 regF1;
 	__u8 data;
 	const __u8 *sn9c1xx;
 
@@ -1366,12 +1178,11 @@
 		break;
 	}
 	sn9c1xx = sn_tb[(int) sd->sensor];
-	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
-	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1);
-	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
-	reg_w(gspca_dev, 0x01, &data, 1);
-	regF1 = 0x01;
-	reg_w(gspca_dev, 0xf1, &regF1, 1);
+	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
+	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+	reg_w1(gspca_dev, 0x01, data);
+	reg_w1(gspca_dev, 0xf1, 0x01);
 }
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -1610,30 +1421,53 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define BSI(bridge, sensor, i2c_addr) \
+	.driver_info = (BRIDGE_ ## bridge << 16) \
+			| (SENSOR_ ## sensor << 8) \
+			| (i2c_addr)
 static const __devinitdata struct usb_device_id device_table[] = {
 #ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
-	{USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
-	{USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
-	{USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
-	{USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
+	{USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
+	{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
+	{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
 #endif
-	{USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
-	{USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
-	{USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
-	{USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
-	{USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
-	{USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
-	{USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
-	{USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
-	{USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
+	{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
+	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
+/* bw600.inf:
+	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
+/*	{USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
+/*	{USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
+/*	{USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
+/*	{USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
+/*	{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)},
+/* bw600.inf:
+	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */
+	{USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
+/*	{USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
 #ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
-	{USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
-	{USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
-	{USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
+	{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
+	{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
+/*	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
+/*	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
 #endif
+	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1658,7 +1492,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	info("v%s registered", version);
+	info("registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 1562061..17fe2c2 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -24,9 +24,6 @@
 #include "gspca.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_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -630,109 +627,10 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
 
-	vendor = id->idVendor;
-	product = id->idProduct;
-	switch (vendor) {
-	case 0x040a:		/* Kodak cameras */
-/*		switch (product) { */
-/*		case 0x0300: */
-			sd->subtype = KodakEZ200;
-/*			break; */
-/*		} */
-		break;
-	case 0x041e:		/* Creative cameras */
-/*		switch (product) { */
-/*		case 0x400a: */
-			sd->subtype = CreativePCCam300;
-/*			break; */
-/*		} */
-		break;
-	case 0x046d:		/* Logitech Labtec */
-		switch (product) {
-		case 0x0890:
-			sd->subtype = LogitechTraveler;
-			break;
-		case 0x0900:
-			sd->subtype = LogitechClickSmart310;
-			break;
-		case 0x0901:
-			sd->subtype = LogitechClickSmart510;
-			break;
-		}
-		break;
-	case 0x04a5:		/* Benq */
-/*		switch (product) { */
-/*		case 0x300c: */
-			sd->subtype = BenqDC1016;
-/*			break; */
-/*		} */
-		break;
-	case 0x04fc:		/* SunPlus */
-/*		switch (product) { */
-/*		case 0x7333: */
-			sd->subtype = PalmPixDC85;
-/*			break; */
-/*		} */
-		break;
-	case 0x055f:		/* Mustek cameras */
-		switch (product) {
-		case 0xc200:
-			sd->subtype = MustekGsmart300;
-			break;
-		case 0xc220:
-			sd->subtype = Gsmartmini;
-			break;
-		}
-		break;
-	case 0x06bd:		/* Agfa Cl20 */
-/*		switch (product) { */
-/*		case 0x0404: */
-			sd->subtype = AgfaCl20;
-/*			break; */
-/*		} */
-		break;
-	case 0x06be:		/* Optimedia */
-/*		switch (product) { */
-/*		case 0x0800: */
-			sd->subtype = Optimedia;
-/*			break; */
-/*		} */
-		break;
-	case 0x084d:		/* D-Link / Minton */
-/*		switch (product) { */
-/*		case 0x0003:	 * DSC-350 / S-Cam F5 */
-			sd->subtype = DLinkDSC350;
-/*			break; */
-/*		} */
-		break;
-	case 0x08ca:		/* Aiptek */
-/*		switch (product) { */
-/*		case 0x0103: */
-			sd->subtype = AiptekPocketDV;
-/*			break; */
-/*		} */
-		break;
-	case 0x2899:		/* ToptroIndustrial */
-/*		switch (product) { */
-/*		case 0x012c: */
-			sd->subtype = ToptroIndus;
-/*			break; */
-/*		} */
-		break;
-	case 0x8086:		/* Intel */
-/*		switch (product) { */
-/*		case 0x0630:	 * Pocket PC Camera */
-			sd->subtype = IntelPocketPCCamera;
-/*			break; */
-/*		} */
-		break;
-	}
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
+	sd->subtype = id->driver_info;
 	if (sd->subtype != LogitechClickSmart310) {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -1162,23 +1060,22 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
-	{USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
-	{USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
-	{USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
-	{USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
-	{USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
-	{USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
-	{USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
-	{USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
-	{USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
-	{USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
-	{USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
-	{USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
-	{USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
-	{USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
+	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
+	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
+	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
+	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
+	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
+	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
+	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
+	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
+	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
+	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
+	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
+	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
+	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
+	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
+	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1203,7 +1100,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 50e929d..51a3c34 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -23,9 +23,6 @@
 
 #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_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -1923,63 +1920,12 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
 
-	vendor = id->idVendor;
-	product = id->idProduct;
-	switch (vendor) {
-	case 0x0000:		/* Unknow Camera */
-/*		switch (product) { */
-/*		case 0x0000: */
-			sd->subtype = MystFromOriUnknownCamera;
-/*			break; */
-/*		} */
-		break;
-	case 0x040a:		/* Kodak cameras */
-/*		switch (product) { */
-/*		case 0x0002: */
-			sd->subtype = KodakDVC325;
-/*			break; */
-/*		} */
-		break;
-	case 0x0497:		/* Smile International */
-/*		switch (product) { */
-/*		case 0xc001: */
-			sd->subtype = SmileIntlCamera;
-/*			break; */
-/*		} */
-		break;
-	case 0x0506:		/* 3COM cameras */
-/*		switch (product) { */
-/*		case 0x00df: */
-			sd->subtype = ThreeComHomeConnectLite;
-/*			break; */
-/*		} */
-		break;
-	case 0x0733:	/* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-		switch (product) {
-		case 0x0401:
-			sd->subtype = IntelCreateAndShare;
-			break;
-		case 0x0402:
-			sd->subtype = ViewQuestM318B;
-			break;
-		}
-		break;
-	case 0x1776:		/* Arowana */
-/*		switch (product) { */
-/*		case 0x501c: */
-			sd->subtype = Arowana300KCMOSCamera;
-/*			break; */
-/*		} */
-		break;
-	}
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+	sd->subtype = id->driver_info;
 	sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
 	sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
@@ -2183,15 +2129,14 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")},
-	{USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")},
-	{USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")},
-	{USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")},
-	{USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")},
-	{USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")},
-	{USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")},
+	{USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
+	{USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
+	{USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},
+	{USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare},
+	{USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B},
+	{USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera},
+	{USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -2216,7 +2161,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index ddea6e1..3c2be80 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -23,9 +23,6 @@
 
 #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_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -34,10 +31,6 @@
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	int buflen;
-	unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */
-	unsigned char tmpbuf2[640 * 480 * 2];	/* YUYV */
-
 	unsigned char brightness;
 
 	char subtype;
@@ -67,29 +60,29 @@
 };
 
 static struct v4l2_pix_format vga_mode[] = {
-	{160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 160 * 2,
-		.sizeimage = 160 * 120 * 2,
+	{160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 160 * 3,
+		.sizeimage = 160 * 120 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 5},
-	{176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 176 * 2,
-		.sizeimage = 176 * 144 * 2,
+	{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 176 * 3,
+		.sizeimage = 176 * 144 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 4},
-	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 320 * 2,
-		.sizeimage = 320 * 240 * 2,
+	{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 320 * 3,
+		.sizeimage = 320 * 240 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 2},
-	{352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 352 * 2,
-		.sizeimage = 352 * 288 * 2,
+	{352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 352 * 3,
+		.sizeimage = 352 * 288 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
-	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 640 * 2,
-		.sizeimage = 640 * 480 * 2,
+	{640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 640 * 3,
+		.sizeimage = 640 * 480 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0},
 };
@@ -641,33 +634,11 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
-
-	vendor = id->idVendor;
-	product = id->idProduct;
-	switch (vendor) {
-	case 0x041e:		/* Creative cameras */
-/*		switch (product) { */
-/*		case 0x401d:	 * here505b */
-			sd->subtype = Nxultra;
-/*			break; */
-/*		} */
-		break;
-	case 0x0733:	/* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-/*		switch (product) { */
-/*		case 0x0430: */
-/*		fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
-			sd->subtype = IntelPCCameraPro;
-/*			break; */
-/*		} */
-		break;
-	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
+	sd->subtype = id->driver_info;
 	if (sd->subtype != IntelPCCameraPro)
 		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 	else			/* no 640x480 for IntelPCCameraPro */
@@ -785,77 +756,30 @@
 	reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
 }
 
-/* convert YYUV per line to YUYV (YUV 4:2:2) */
-static void yyuv_decode(unsigned char *out,
-			unsigned char *in,
-			int width,
-			int height)
-{
-	unsigned char *Ui, *Vi, *yi, *yi1;
-	unsigned char *out1;
-	int i, j;
-
-	yi = in;
-	for (i = height / 2; --i >= 0; ) {
-		out1 = out + width * 2;		/* next line */
-		yi1 = yi + width;
-		Ui = yi1 + width;
-		Vi = Ui + width / 2;
-		for (j = width / 2; --j >= 0; ) {
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Ui;
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Vi;
-
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Ui++;
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Vi++;
-		}
-		yi += width * 2;
-		out = out1;
-	}
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		if (gspca_dev->last_packet_type == FIRST_PACKET) {
-			yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
-					gspca_dev->width,
-					gspca_dev->height);
-			frame = gspca_frame_add(gspca_dev,
-						LAST_PACKET,
-						frame,
-						sd->tmpbuf2,
-						gspca_dev->width
-							* gspca_dev->height
-							* 2);
-		}
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, 0);
+		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+					data, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		if (len > 0)
-			memcpy(sd->tmpbuf, data, len);
-		else
-			len = 0;
-		sd->buflen = len;
-		return;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
-		return;
+		break;
+	default:
+		data += 1;
+		len -= 1;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	}
-	data += 1;
-	len -= 1;
-	memcpy(&sd->tmpbuf[sd->buflen], data, len);
-	sd->buflen += len;
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
@@ -910,10 +834,10 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")},
-	{USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")},
+	{USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
+	{USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
+/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -938,7 +862,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 143203c..6fe715c 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -25,9 +25,6 @@
 
 #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_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -36,10 +33,6 @@
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	int buflen;
-	__u8 tmpbuf[640 * 480 * 3];	/* YYUV per line */
-	__u8 tmpbuf2[640 * 480 * 2];	/* YUYV */
-
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
@@ -118,29 +111,29 @@
 };
 
 static struct v4l2_pix_format vga_mode[] = {
-	{160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 160 * 2,
-		.sizeimage = 160 * 120 * 2,
+	{160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 160 * 3,
+		.sizeimage = 160 * 120 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 5},
-	{176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 176 * 2,
-		.sizeimage = 176 * 144 * 2,
+	{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 176 * 3,
+		.sizeimage = 176 * 144 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 4},
-	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 320 * 2,
-		.sizeimage = 320 * 240 * 2,
+	{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 320 * 3,
+		.sizeimage = 320 * 240 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 2},
-	{352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 352 * 2,
-		.sizeimage = 352 * 288 * 2,
+	{352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 352 * 3,
+		.sizeimage = 352 * 288 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
-	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 640 * 2,
-		.sizeimage = 640 * 480 * 2,
+	{640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+		.bytesperline = 640 * 3,
+		.sizeimage = 640 * 480 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0},
 };
@@ -310,7 +303,6 @@
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -576,77 +568,30 @@
 {
 }
 
-/* convert YYUV per line to YUYV (YUV 4:2:2) */
-static void yyuv_decode(unsigned char *out,
-			unsigned char *in,
-			int width,
-			int height)
-{
-	unsigned char *Ui, *Vi, *yi, *yi1;
-	unsigned char *out1;
-	int i, j;
-
-	yi = in;
-	for (i = height / 2; --i >= 0; ) {
-		out1 = out + width * 2;		/* next line */
-		yi1 = yi + width;
-		Ui = yi1 + width;
-		Vi = Ui + width / 2;
-		for (j = width / 2; --j >= 0; ) {
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Ui;
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Vi;
-
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Ui++;
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Vi++;
-		}
-		yi += width * 2;
-		out = out1;
-	}
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		if (gspca_dev->last_packet_type == FIRST_PACKET) {
-			yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
-					gspca_dev->width,
-					gspca_dev->height);
-			frame = gspca_frame_add(gspca_dev,
-						LAST_PACKET,
-						frame,
-						sd->tmpbuf2,
-						gspca_dev->width
-							* gspca_dev->height
-							* 2);
-		}
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, 0);
+		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+					data, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		if (len > 0)
-			memcpy(sd->tmpbuf, data, len);
-		else
-			len = 0;
-		sd->buflen = len;
-		return;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
-		return;
+		break;
+	default:
+		data += 1;
+		len -= 1;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	}
-	data += 1;
-	len -= 1;
-	memcpy(&sd->tmpbuf[sd->buflen], data, len);
-	sd->buflen += len;
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
@@ -804,12 +749,12 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")},
-/*	{USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */
-	{USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")},
-	{USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")},
+	{USB_DEVICE(0x06e1, 0xa190)},
+/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
+	{USB_DEVICE(0x0733, 0x0430)}, */
+	{USB_DEVICE(0x0734, 0x043b)},
+	{USB_DEVICE(0x99fa, 0x8988)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -834,7 +779,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index d8cd938..b608a27 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -22,9 +22,6 @@
 
 #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_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -33,10 +30,6 @@
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	int buflen;
-	unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */
-	unsigned char tmpbuf2[352 * 288 * 2];	/* YUYV */
-
 	unsigned char brightness;
 
 	char subtype;
@@ -71,23 +64,23 @@
 
 static struct v4l2_pix_format sif_mode[] = {
 	{160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 160 * 2,
-		.sizeimage = 160 * 120 * 2,
+		.bytesperline = 160 * 3,
+		.sizeimage = 160 * 120 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 3},
 	{176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 176 * 2,
-		.sizeimage = 176 * 144 * 2,
+		.bytesperline = 176 * 3,
+		.sizeimage = 176 * 144 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 2},
 	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 320 * 2,
-		.sizeimage = 320 * 240 * 2,
+		.bytesperline = 320 * 3,
+		.sizeimage = 320 * 240 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
 	{352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
-		.bytesperline = 352 * 2,
-		.sizeimage = 352 * 288 * 2,
+		.bytesperline = 352 * 3,
+		.sizeimage = 352 * 288 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0},
 };
@@ -1476,58 +1469,8 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u16 product;
 	int data1, data2;
 
-	product = id->idProduct;
-	switch (id->idVendor) {
-	case 0x0130:		/* Clone webcam */
-/*		switch (product) { */
-/*		case 0x0130: */
-			sd->subtype = HamaUSBSightcam;	/* same as Hama 0010 */
-/*			break; */
-/*		} */
-		break;
-	case 0x041e:		/* Creative cameras */
-/*		switch (product) { */
-/*		case 0x4018: */
-			sd->subtype = CreativeVista;
-/*			break; */
-/*		} */
-		break;
-	case 0x0461:		/* MicroInnovation */
-/*		switch (product) { */
-/*		case 0x0815: */
-			sd->subtype = MicroInnovationIC200;
-/*			break; */
-/*		} */
-		break;
-	case 0x0733:	/* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-/*		switch (product) { */
-/*		case 0x110: */
-			sd->subtype = ViewQuestVQ110;
-/*			break; */
-/*		} */
-		break;
-	case 0x0af9:		/* Hama cameras */
-		switch (product) {
-		case 0x0010:
-			sd->subtype = HamaUSBSightcam;
-			break;
-		case 0x0011:
-			sd->subtype = HamaUSBSightcam2;
-			break;
-		}
-		break;
-	case 0x8086:		/* Intel */
-/*		switch (product) { */
-/*		case 0x0110: */
-			sd->subtype = IntelEasyPCCamera;
-/*			break; */
-/*		} */
-		break;
-	}
-
 	/* Read from global register the USB product and vendor IDs, just to
 	 * prove that we can communicate with the device.  This works, which
 	 * confirms at we are communicating properly and that the device
@@ -1544,10 +1487,11 @@
 	PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	cam->cam_mode = sif_mode;
 	cam->nmodes = ARRAY_SIZE(sif_mode);
+
+	sd->subtype = id->driver_info;
 	sd->brightness = BRIGHTNESS_DEF;
 
 	switch (sd->subtype) {
@@ -1619,77 +1563,30 @@
 {
 }
 
-/* convert YUVY per line to YUYV (YUV 4:2:2) */
-static void yuvy_decode(unsigned char *out,
-			unsigned char *in,
-			int width,
-			int height)
-{
-	unsigned char *Ui, *Vi, *yi, *yi1;
-	unsigned char *out1;
-	int i, j;
-
-	yi = in;
-	for (i = height / 2; --i >= 0; ) {
-		out1 = out + width * 2;		/* next line */
-		Ui = yi + width;
-		Vi = Ui + width / 2;
-		yi1 = Vi + width / 2;
-		for (j = width / 2; --j >= 0; ) {
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Ui;
-			*out++ = 128 + *yi++;
-			*out++ = 128 + *Vi;
-
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Ui++;
-			*out1++ = 128 + *yi1++;
-			*out1++ = 128 + *Vi++;
-		}
-		yi += width * 2;
-		out = out1;
-	}
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		if (gspca_dev->last_packet_type == FIRST_PACKET) {
-			yuvy_decode(sd->tmpbuf2, sd->tmpbuf,
-					gspca_dev->width,
-					gspca_dev->height);
-			frame = gspca_frame_add(gspca_dev,
-						LAST_PACKET,
-						frame,
-						sd->tmpbuf2,
-						gspca_dev->width
-							* gspca_dev->height
-							* 2);
-		}
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, 0);
+		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+					data, 0);
 		data += SPCA508_OFFSET_DATA;
 		len -= SPCA508_OFFSET_DATA;
-		if (len > 0)
-			memcpy(sd->tmpbuf, data, len);
-		else
-			len = 0;
-		sd->buflen = len;
-		return;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
-		return;
+		break;
+	default:
+		data += 1;
+		len -= 1;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				data, len);
+		break;
 	}
-	data += 1;
-	len -= 1;
-	memcpy(&sd->tmpbuf[sd->buflen], data, len);
-	sd->buflen += len;
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1745,15 +1642,14 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")},
-	{USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")},
-	{USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")},
-	{USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")},
-	{USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")},
-	{USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")},
-	{USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")},
+	{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
+	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
+	{USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},
+	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
+	{USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
+	{USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
+	{USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1778,7 +1674,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index b659bd0..a261745 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -24,9 +24,6 @@
 
 #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_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -582,35 +579,15 @@
 		PDEBUG(D_PROBE, "Bad vendor / product from device");
 		return -EINVAL;
 	}
-	switch (product) {
-	case 0x0928:
-	case 0x0929:
-	case 0x092a:
-	case 0x092b:
-	case 0x092c:
-	case 0x092d:
-	case 0x092e:
-	case 0x092f:
-	case 0x403b:
-		sd->chip_revision = Rev012A;
-		break;
-	default:
-/*	case 0x0561:
-	case 0x0815:			* ?? in spca508.c
-	case 0x401a:
-	case 0x7004:
-	case 0x7e50:
-	case 0xa001:
-	case 0xcdee: */
-		sd->chip_revision = Rev072A;
-		break;
-	}
+
 	cam = &gspca_dev->cam;
 	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
 	cam->cam_mode = sif_mode;
 	cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+
+	sd->chip_revision = id->driver_info;
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
@@ -997,23 +974,22 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")},
-	{USB_DEVICE(0x041e, 0x403b),  DVNM("Creative Webcam Vista (VF0010)")},
-	{USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")},
-	{USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")},
-	{USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")},
-	{USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")},
-	{USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")},
-	{USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")},
-	{USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")},
-	{USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")},
-	{USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")},
-	{USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")},
-	{USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")},
-	{USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")},
-	{USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")},
+	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
+	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
+	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
+	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
+	{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
+	{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
+	{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
+	{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
+	{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
 	{}
 };
 
@@ -1039,7 +1015,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index c78ee0d..16219cf 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -23,9 +23,6 @@
 #include "gspca.h"
 #include "jpeg.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_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -299,7 +296,6 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam = &gspca_dev->cam;
 
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x02;
 	gspca_dev->cam.cam_mode = vga_mode;
 	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
@@ -549,9 +545,8 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
+	{USB_DEVICE(0x05e1, 0x0893)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -576,7 +571,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	info("v%s registered", version);
+	info("registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index abd7bef..54efa48 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -24,9 +24,6 @@
 #include "gspca.h"
 #include "jpeg.h"
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 8)
-static const char version[] = "2.1.8";
-
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -804,229 +801,29 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
 	struct cam *cam;
-	__u16 vendor;
-	__u16 product;
-	__u8 fw;
-
-	vendor = id->idVendor;
-	product = id->idProduct;
-	switch (vendor) {
-	case 0x041e:		/* Creative cameras */
-/*		switch (product) { */
-/*		case 0x400b: */
-/*		case 0x4012: */
-/*		case 0x4013: */
-/*			sd->bridge = BRIDGE_SPCA504C; */
-/*			break; */
-/*		} */
-		break;
-	case 0x0458:		/* Genius KYE cameras */
-/*		switch (product) { */
-/*		case 0x7006: */
-			sd->bridge = BRIDGE_SPCA504B;
-/*			break; */
-/*		} */
-		break;
-	case 0x0461:		/* MicroInnovation */
-/*		switch (product) { */
-/*		case 0x0821: */
-			sd->bridge = BRIDGE_SPCA533;
-/*			break; */
-/*		} */
-		break;
-	case 0x046d:		/* Logitech Labtec */
-		switch (product) {
-		case 0x0905:
-			sd->subtype = LogitechClickSmart820;
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x0960:
-			sd->subtype = LogitechClickSmart420;
-			sd->bridge = BRIDGE_SPCA504C;
-			break;
-		}
-		break;
-	case 0x0471:				/* Philips */
-/*		switch (product) { */
-/*		case 0x0322: */
-			sd->bridge = BRIDGE_SPCA504B;
-/*			break; */
-/*		} */
-		break;
-	case 0x04a5:		/* Benq */
-		switch (product) {
-		case 0x3003:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		case 0x3008:
-		case 0x300a:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		}
-		break;
-	case 0x04f1:		/* JVC */
-/*		switch (product) { */
-/*		case 0x1001: */
-			sd->bridge = BRIDGE_SPCA504B;
-/*			break; */
-/*		} */
-		break;
-	case 0x04fc:		/* SunPlus */
-		switch (product) {
-		case 0x500c:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		case 0x504a:
-/* try to get the firmware as some cam answer 2.0.1.2.2
- * and should be a spca504b then overwrite that setting */
-			reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
-			fw = gspca_dev->usb_buf[0];
-			if (fw == 1) {
-				sd->subtype = AiptekMiniPenCam13;
-				sd->bridge = BRIDGE_SPCA504;
-			} else if (fw == 2) {
-				sd->bridge = BRIDGE_SPCA504B;
-			} else
-				return -ENODEV;
-			break;
-		case 0x504b:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		case 0x5330:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x5360:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		case 0xffff:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		}
-		break;
-	case 0x052b:		/* ?? Megapix */
-/*		switch (product) { */
-/*		case 0x1513: */
-			sd->subtype = MegapixV4;
-			sd->bridge = BRIDGE_SPCA533;
-/*			break; */
-/*		} */
-		break;
-	case 0x0546:		/* Polaroid */
-		switch (product) {
-		case 0x3155:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x3191:
-		case 0x3273:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		}
-		break;
-	case 0x055f:		/* Mustek cameras */
-		switch (product) {
-		case 0xc211:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		case 0xc230:
-		case 0xc232:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0xc360:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		case 0xc420:
-			sd->bridge = BRIDGE_SPCA504;
-			break;
-		case 0xc430:
-		case 0xc440:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0xc520:
-			sd->bridge = BRIDGE_SPCA504;
-			break;
-		case 0xc530:
-		case 0xc540:
-		case 0xc630:
-		case 0xc650:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		}
-		break;
-	case 0x05da:		/* Digital Dream cameras */
-/*		switch (product) { */
-/*		case 0x1018: */
-			sd->bridge = BRIDGE_SPCA504B;
-/*			break; */
-/*		} */
-		break;
-	case 0x06d6:		/* Trust */
-/*		switch (product) { */
-/*		case 0x0031: */
-			sd->bridge = BRIDGE_SPCA533;	/* SPCA533A */
-/*			break; */
-/*		} */
-		break;
-	case 0x0733:	/* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-		switch (product) {
-		case 0x1311:
-		case 0x1314:
-		case 0x2211:
-		case 0x2221:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x3261:
-		case 0x3281:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		}
-		break;
-	case 0x08ca:		/* Aiptek */
-		switch (product) {
-		case 0x0104:
-		case 0x0106:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x2008:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		case 0x2010:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x2016:
-		case 0x2018:
-			sd->bridge = BRIDGE_SPCA504B;
-			break;
-		case 0x2020:
-		case 0x2022:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x2024:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		case 0x2028:
-			sd->bridge = BRIDGE_SPCA533;
-			break;
-		case 0x2040:
-		case 0x2042:
-		case 0x2050:
-		case 0x2060:
-			sd->bridge = BRIDGE_SPCA536;
-			break;
-		}
-		break;
-	case 0x0d64:		/* SunPlus */
-/*		switch (product) { */
-/*		case 0x0303: */
-			sd->bridge = BRIDGE_SPCA536;
-/*			break; */
-/*		} */
-		break;
-	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 
+	sd->bridge = id->driver_info >> 8;
+	sd->subtype = id->driver_info;
+
+	if (sd->subtype == AiptekMiniPenCam13) {
+/* try to get the firmware as some cam answer 2.0.1.2.2
+ * and should be a spca504b then overwrite that setting */
+		reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
+		switch (gspca_dev->usb_buf[0]) {
+		case 1:
+			break;		/* (right bridge/subtype) */
+		case 2:
+			sd->bridge = BRIDGE_SPCA504B;
+			sd->subtype = 0;
+			break;
+		default:
+			return -ENODEV;
+		}
+	}
+
 	switch (sd->bridge) {
 	default:
 /*	case BRIDGE_SPCA504B: */
@@ -1581,65 +1378,67 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define BS(bridge, subtype) \
+	.driver_info = (BRIDGE_ ## bridge << 8) \
+			| (subtype)
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")},
-	{USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")},
-	{USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")},
-	{USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")},
-	{USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")},
-	{USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")},
-	{USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")},
-	{USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")},
-	{USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")},
-	{USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")},
-	{USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")},
-	{USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")},
-	{USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")},
-	{USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")},
-	{USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")},
-	{USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")},
-	{USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")},
-	{USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")},
-	{USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")},
-	{USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")},
-	{USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")},
-	{USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")},
-	{USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")},
-	{USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")},
-	{USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")},
-	{USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")},
-	{USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")},
-	{USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")},
-	{USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")},
-	{USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")},
-	{USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")},
-	{USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")},
-	{USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")},
-	{USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")},
-	{USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")},
-	{USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")},
-	{USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")},
-	{USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")},
-	{USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")},
-	{USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")},
-	{USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")},
-	{USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")},
-	{USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")},
-	{USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")},
-	{USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")},
-	{USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")},
-	{USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")},
-	{USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")},
-	{USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")},
-	{USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")},
-	{USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")},
-	{USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")},
-	{USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")},
-	{USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")},
-	{USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")},
-	{USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")},
-	{USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")},
+	{USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
+	{USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
+	{USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
+	{USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
+	{USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
+	{USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
+	{USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
+	{USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
+	{USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
+	{USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
+	{USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
+	{USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
+	{USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
+	{USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
+	{USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
+	{USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
+	{USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
+	{USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
+	{USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
+	{USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
+	{USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
+	{USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
+	{USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
+	{USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
+	{USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
+	{USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
+	{USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
+	{USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
+	{USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1664,7 +1463,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 00f47e4..91b555c 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -1,12 +1,4 @@
 /*
- *Notes: * t613  + tas5130A
- *	* Focus to light do not balance well as in win.
- *	  Quality in win is not good, but its kinda better.
- *	 * Fix some "extraneous bytes", most of apps will show the image anyway
- *	 * Gamma table, is there, but its really doing something?
- *	 * 7~8 Fps, its ok, max on win its 10.
- *			Costantino Leandro
- *
  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,16 +14,22 @@
  * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *Notes: * t613  + tas5130A
+ *	* Focus to light do not balance well as in win.
+ *	  Quality in win is not good, but its kinda better.
+ *	 * Fix some "extraneous bytes", most of apps will show the image anyway
+ *	 * Gamma table, is there, but its really doing something?
+ *	 * 7~8 Fps, its ok, max on win its 10.
+ *			Costantino Leandro
  */
 
 #define MODULE_NAME "t613"
+
 #include "gspca.h"
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
 
 #define MAX_GAMMA 0x10		/* 0 to 15 */
 
-/* From LUVCVIEW */
 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
 
 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
@@ -424,7 +422,6 @@
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 
 	cam->cam_mode = vga_mode_t16;
@@ -998,9 +995,8 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
+	{USB_DEVICE(0x17a1, 0x0128)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1025,7 +1021,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 0b79389..1ff8ba2 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -22,9 +22,6 @@
 
 #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_DESCRIPTION("TV8532 USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -249,7 +246,6 @@
 	tv_8532WriteEEprom(gspca_dev);
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 1;
 	cam->cam_mode = sif_mode;
 	cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
@@ -624,13 +620,12 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")},
-	{USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")},
-	{USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")},
-	{USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")},
-	{USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")},
+	{USB_DEVICE(0x046d, 0x0920)},
+	{USB_DEVICE(0x046d, 0x0921)},
+	{USB_DEVICE(0x0545, 0x808b)},
+	{USB_DEVICE(0x0545, 0x8333)},
+	{USB_DEVICE(0x0923, 0x010f)},
 	{}
 };
 
@@ -656,7 +651,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index fcf2c9e..a422175 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -24,9 +24,6 @@
 
 #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_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -1419,30 +1416,10 @@
 	struct usb_device *dev = gspca_dev->dev;
 	struct cam *cam;
 	int sensor;
-	__u16 product;
-
-	product = id->idProduct;
-	sd->bridge = BRIDGE_VC0321;
-	switch (id->idVendor) {
-	case 0x0ac8:		/* Vimicro z-star */
-		switch (product) {
-		case 0x0323:
-			sd->bridge = BRIDGE_VC0323;
-			break;
-		}
-		break;
-	case 0x17ef:		/* Lenovo */
-/*		switch (product) { */
-/*		case 0x4802:	 * Lenovo MI1310_SOC */
-			sd->bridge = BRIDGE_VC0323;
-/*			break; */
-/*		} */
-		break;
-	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x02;
+	sd->bridge = id->driver_info;
 	if (sd->bridge == BRIDGE_VC0321) {
 		cam->cam_mode = vc0321_mode;
 		cam->nmodes = ARRAY_SIZE(vc0321_mode);
@@ -1771,16 +1748,15 @@
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")},
-	{USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")},
-	{USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")},
-	{USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")},
-	{USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")},
-	{USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")},
-	{USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")},
-	{USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")},
+	{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
+	{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1805,7 +1781,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index b761b11..22a994c 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -24,9 +24,6 @@
 
 #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>, "
 		"Serge A. Suchkov <Serge.A.S@tochka.ru>");
 MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
@@ -49,7 +46,7 @@
 	__u8 sharpness;
 
 	char qindex;
-	char sensor;			/* Type of image sensor chip */
+	signed char sensor;		/* Type of image sensor chip */
 /* !! values used in different tables */
 #define SENSOR_CS2102 0
 #define SENSOR_CS2102K 1
@@ -2205,10 +2202,10 @@
 };
 static const struct usb_action hdcs2020b_50HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
-	{0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
-	{0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */
-	{0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */
+	{0xaa, 0x13, 0x0018},			/* 00,13,18,aa */
+	{0xaa, 0x14, 0x0001},			/* 00,14,01,aa */
+	{0xaa, 0x0e, 0x0005},			/* 00,0e,05,aa */
+	{0xaa, 0x19, 0x001f},			/* 00,19,1f,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
 	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
 	{0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */
@@ -2226,10 +2223,10 @@
 };
 static const struct usb_action hdcs2020b_60HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
-	{0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
-	{0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
-	{0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */
+	{0xaa, 0x13, 0x0031},			/* 00,13,31,aa */
+	{0xaa, 0x14, 0x0001},			/* 00,14,01,aa */
+	{0xaa, 0x0e, 0x0004},			/* 00,0e,04,aa */
+	{0xaa, 0x19, 0x00cd},			/* 00,19,cd,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
 	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
 	{0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */
@@ -2247,10 +2244,10 @@
 };
 static const struct usb_action hdcs2020b_NoFliker[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
-	{0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
-	{0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
-	{0xaa, 0x19, 0x0000}, /* 00,19,00,aa */
+	{0xaa, 0x13, 0x0010},			/* 00,13,10,aa */
+	{0xaa, 0x14, 0x0001},			/* 00,14,01,aa */
+	{0xaa, 0x0e, 0x0004},			/* 00,0e,04,aa */
+	{0xaa, 0x19, 0x0000},			/* 00,19,00,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
 	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
 	{0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
@@ -4102,27 +4099,27 @@
 
 static const struct usb_action pas106b_Initial[] = {	/* 176x144 */
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},		/* ClockSetting */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 /* Sream and Sensor specific */
-	{0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},	/* CMOSSensorSelect */
+	{0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
 /* Picture size */
-	{0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH},  /* FrameWidthHigh 00 */
-	{0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW},	  /* FrameWidthLow B0 */
-	{0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */
-	{0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW},  /* FrameHightLow 90 */
+	{0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH},
+	{0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW},
+	{0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH},
+	{0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW},
 /* System */
-	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 /* Sream and Sensor specific */
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
 /* Sensor Interface */
-	{0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},  /* Compatibily Mode */
+	{0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
 /* Window inside sensor array */
-	{0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},	/* WinXStartLow */
-	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},	/* FirstYLow */
-	{0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},	/* FirstxLow */
-	{0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},	/* WinHeightLow */
-	{0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},	/* WinWidthLow */
+	{0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+	{0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
+	{0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
+	{0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
 /* Init the sensor */
 	{0xaa, 0x02, 0x0004},
 	{0xaa, 0x08, 0x0000},
@@ -4135,40 +4132,40 @@
 	{0xaa, 0x14, 0x0081},
 
 /* Other registors */
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
 /* Frame retreiving */
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},	/* AutoAdjustFPS */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 /* Gains */
-	{0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},	/* DigitalGain */
+	{0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
 /* Unknown */
 	{0xa0, 0x00, 0x01ad},
 /* Sharpness */
-	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},	/* SharpnessMode */
-	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},	/* Sharpness05 */
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 /* Other registors */
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},	/* OperationMode */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 /* Auto exposure and white balance */
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},	/* AWBStatus */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
 /*Dead pixels */
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 /* EEPROM */
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},	/* EEPROMAccess */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* ClockSetting */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
 /* Other registers */
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},	/* OperationMode */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 /* Auto exposure and white balance */
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},	/* AWBStatus */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
 /*Dead pixels */
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 /* EEPROM */
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},	/* EEPROMAccess */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* ClockSetting */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
 
 	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
 	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
@@ -4180,67 +4177,67 @@
 	{0xa0, 0xf4, ZC3XX_R111_RGB21},
 	{0xa0, 0x58, ZC3XX_R112_RGB22},
 /* Auto correction */
-	{0xa0, 0x03, ZC3XX_R181_WINXSTART},	/* WinXstart */
-	{0xa0, 0x08, ZC3XX_R182_WINXWIDTH},	/* WinXWidth */
-	{0xa0, 0x16, ZC3XX_R183_WINXCENTER},	/* WinXCenter */
-	{0xa0, 0x03, ZC3XX_R184_WINYSTART},	/* WinYStart */
-	{0xa0, 0x05, ZC3XX_R185_WINYWIDTH},	/* WinYWidth */
-	{0xa0, 0x14, ZC3XX_R186_WINYCENTER},	/* WinYCenter */
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+	{0xa0, 0x03, ZC3XX_R181_WINXSTART},
+	{0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
+	{0xa0, 0x16, ZC3XX_R183_WINXCENTER},
+	{0xa0, 0x03, ZC3XX_R184_WINYSTART},
+	{0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
+	{0xa0, 0x14, ZC3XX_R186_WINYCENTER},
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
 
 /* Auto exposure and white balance */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* ExposureLimitHigh */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},	/* ExposureLimitMid */
-	{0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},	/* ExposureLimitLow */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* AntiFlickerHigh */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* AntiFlickerLow */
-	{0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},	/* AntiFlickerLow */
-	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},		/* AEBFreeze */
-	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},		/* AEBUnfreeze */
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
 /* sensor on */
 	{0xaa, 0x07, 0x00b1},
 	{0xaa, 0x05, 0x0003},
 	{0xaa, 0x04, 0x0001},
 	{0xaa, 0x03, 0x003b},
 /* Gains */
-	{0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* DigitalLimitDiff */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},	/* DigitalGainStep */
-	{0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},		/* GlobalGain */
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},		/* GlobalGain */
+	{0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
 /* Auto correction */
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},	/* AutoCorrectEnable */
+	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
 	{0xa1, 0x01, 0x0180},				/* AutoCorrectEnable */
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* AutoCorrectEnable */
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 /* Gains */
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},			/* RGain */
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},			/* GGain */
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},			/* BGain */
+	{0xa0, 0x40, ZC3XX_R116_RGAIN},
+	{0xa0, 0x40, ZC3XX_R117_GGAIN},
+	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 	{}
 };
 
 static const struct usb_action pas106b_InitialScale[] = {	/* 352x288 */
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},		/* ClockSetting */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 /* Sream and Sensor specific */
-	{0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},	/* CMOSSensorSelect */
+	{0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
 /* Picture size */
-	{0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH},	/* FrameWidthHigh */
-	{0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW},		/* FrameWidthLow */
-	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},	/* FrameHeightHigh */
-	{0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW},	/* FrameHightLow */
+	{0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH},
+	{0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW},
+	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+	{0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW},
 /* System */
-	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},	/* SystemOperating */
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 /* Sream and Sensor specific */
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
 /* Sensor Interface */
-	{0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},	/* Compatibily Mode */
+	{0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
 /* Window inside sensor array */
-	{0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},	/* WinXStartLow */
-	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},	/* FirstYLow */
-	{0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},	/* FirstxLow */
-	{0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},	/* WinHeightLow */
-	{0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},	/* WinWidthLow */
+	{0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+	{0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
+	{0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
+	{0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
 /* Init the sensor */
 	{0xaa, 0x02, 0x0004},
 	{0xaa, 0x08, 0x0000},
@@ -4253,41 +4250,41 @@
 	{0xaa, 0x14, 0x0081},
 
 /* Other registors */
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
 /* Frame retreiving */
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},	/* AutoAdjustFPS */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 /* Gains */
-	{0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},	/* DigitalGain */
+	{0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
 /* Unknown */
 	{0xa0, 0x00, 0x01ad},
 /* Sharpness */
-	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},	/* SharpnessMode */
-	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},	/* Sharpness05 */
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 /* Other registors */
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},	/* OperationMode */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 /* Auto exposure and white balance */
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},	/* AWBStatus */
-	{0xa0, 0x80, ZC3XX_R18D_YTARGET},	/* ????????? */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+	{0xa0, 0x80, ZC3XX_R18D_YTARGET},
 /*Dead pixels */
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 /* EEPROM */
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},	/* EEPROMAccess */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* ClockSetting */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
 /* Other registers */
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},	/* OperationMode */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 /* Auto exposure and white balance */
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},	/* AWBStatus */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
 /*Dead pixels */
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 /* EEPROM */
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},	/* EEPROMAccess */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 /* JPEG control */
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* ClockSetting */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
 
 	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
 	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
@@ -4299,43 +4296,43 @@
 	{0xa0, 0xf4, ZC3XX_R111_RGB21},
 	{0xa0, 0x58, ZC3XX_R112_RGB22},
 /* Auto correction */
-	{0xa0, 0x03, ZC3XX_R181_WINXSTART},	/* WinXstart */
-	{0xa0, 0x08, ZC3XX_R182_WINXWIDTH},	/* WinXWidth */
-	{0xa0, 0x16, ZC3XX_R183_WINXCENTER},	/* WinXCenter */
-	{0xa0, 0x03, ZC3XX_R184_WINYSTART},	/* WinYStart */
-	{0xa0, 0x05, ZC3XX_R185_WINYWIDTH},	/* WinYWidth */
-	{0xa0, 0x14, ZC3XX_R186_WINYCENTER},	/* WinYCenter */
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+	{0xa0, 0x03, ZC3XX_R181_WINXSTART},
+	{0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
+	{0xa0, 0x16, ZC3XX_R183_WINXCENTER},
+	{0xa0, 0x03, ZC3XX_R184_WINYSTART},
+	{0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
+	{0xa0, 0x14, ZC3XX_R186_WINYCENTER},
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
 
 /* Auto exposure and white balance */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},  /* ExposureLimitMid */
-	{0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},  /* ExposureLimitLow 0xb1 */
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
 
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},   /* AntiFlickerHigh 0x00 */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},    /* AntiFlickerLow 0x00 */
-	{0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},    /* AntiFlickerLow 0x87 */
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
 
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},	/* AEBFreeze 0x10 0x0c */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},	/* AEBUnfreeze 0x30 0x18 */
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
 /* sensor on */
 	{0xaa, 0x07, 0x00b1},
 	{0xaa, 0x05, 0x0003},
 	{0xaa, 0x04, 0x0001},
 	{0xaa, 0x03, 0x003b},
 /* Gains */
-	{0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* DigitalLimitDiff */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},	/* DigitalGainStep */
-	{0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},	/* GlobalGain */
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},	/* GlobalGain */
+	{0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
 /* Auto correction */
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},	/* AutoCorrectEnable */
+	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
 	{0xa1, 0x01, 0x0180},				/* AutoCorrectEnable */
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* AutoCorrectEnable */
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 /* Gains */
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},		/* RGain */
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},		/* GGain */
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},		/* BGain */
+	{0xa0, 0x40, ZC3XX_R116_RGAIN},
+	{0xa0, 0x40, ZC3XX_R117_GGAIN},
+	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 
 	{0xa0, 0x00, 0x0007},			/* AutoCorrectEnable */
 	{0xa0, 0xff, ZC3XX_R018_FRAMELOST},	/* Frame adjust */
@@ -4459,8 +4456,8 @@
 	{0xa0, 0x50, ZC3XX_R112_RGB22},
 
 	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
 	{0xa1, 0x01, 0x01c8},
 	{0xa1, 0x01, 0x01c9},
 	{0xa1, 0x01, 0x01ca},
@@ -5984,7 +5981,7 @@
 	{0xaa, 0x1b, 0x0000},		/* 00,1b,00,aa, */
 	{0xaa, 0x13, 0x0002},		/* 00,13,02,aa, */
 	{0xaa, 0x15, 0x0004},		/* 00,15,04,aa */
-	{0xaa, 0x01, 0x0000},
+/*??	{0xaa, 0x01, 0x0000}, */
 	{0xaa, 0x01, 0x0000},
 	{0xaa, 0x1a, 0x0000},		/* 00,1a,00,aa, */
 	{0xaa, 0x1c, 0x0017},		/* 00,1c,17,aa, */
@@ -6000,8 +5997,8 @@
 	{0xaa, 0x0f, 0x00a0},		/* 00,0f,a0,aa, */
 	{0xaa, 0x10, 0x0000},		/* 00,10,00,aa, */
 	{0xaa, 0x11, 0x00a0},		/* 00,11,a0,aa, */
-	{0xa0, 0x00, 0x0039},
-	{0xa1, 0x01, 0x0037},
+/*??	{0xa0, 0x00, 0x0039},
+	{0xa1, 0x01, 0x0037}, */
 	{0xaa, 0x16, 0x0001},		/* 00,16,01,aa, */
 	{0xaa, 0x17, 0x00e8},		/* 00,17,e6,aa, (e6 -> e8) */
 	{0xaa, 0x18, 0x0002},		/* 00,18,02,aa, */
@@ -6272,7 +6269,7 @@
 			__u8 value,
 			__u16 index)
 {
-	PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index);
+	PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
 	reg_w_i(dev, value, index);
 }
 
@@ -6280,17 +6277,17 @@
 			__u8 reg)
 {
 	__u8 retbyte;
-	__u8 retval[2];
+	__u16 retval;
 
 	reg_w_i(gspca_dev->dev, reg, 0x92);
 	reg_w_i(gspca_dev->dev, 0x02, 0x90);		/* <- read command */
 	msleep(25);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
-	retval[0] = reg_r_i(gspca_dev, 0x0095);		/* read Lowbyte */
-	retval[1] = reg_r_i(gspca_dev, 0x0096);		/* read Hightbyte */
-	PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x",
-			reg, retbyte, retval[1], retval[0]);
-	return (retval[1] << 8) | retval[0];
+	retval = reg_r_i(gspca_dev, 0x0095);		/* read Lowbyte */
+	retval |= reg_r_i(gspca_dev, 0x0096) << 8;	/* read Hightbyte */
+	PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)",
+			reg, retval, retbyte);
+	return retval;
 }
 
 static __u8 i2c_write(struct gspca_dev *gspca_dev,
@@ -6306,7 +6303,7 @@
 	reg_w_i(gspca_dev->dev, 0x01, 0x90);		/* <- write command */
 	msleep(5);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
-	PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)",
+	PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
 			reg, valH, valL, retbyte);
 	return retbyte;
 }
@@ -6349,6 +6346,8 @@
 		{0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
 	static const __u8 po2030_matrix[9] =
 		{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
+	static const __u8 vf0250_matrix[9] =
+		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
 
 	switch (sd->sensor) {
 	case SENSOR_GC0305:
@@ -6363,8 +6362,9 @@
 	case SENSOR_PO2030:
 		matrix = po2030_matrix;
 		break;
-	case SENSOR_TAS5130C_VF0250:	/* no matrix? */
-		return;
+	case SENSOR_TAS5130C_VF0250:
+		matrix = vf0250_matrix;
+		break;
 	default:		/* matrix already loaded */
 		return;
 	}
@@ -6744,7 +6744,7 @@
 		return 0x04;			/* CS2102 */
 
 	start_2wr_probe(dev, 0x06);		/* OmniVision */
-	reg_w(dev, 0x08, 0x8d);
+	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
 	retbyte = i2c_read(gspca_dev, 0x11);
 	if (retbyte != 0) {
@@ -6778,7 +6778,7 @@
 		return 0x0c;			/* ICM105A */
 
 	start_2wr_probe(dev, 0x0e);		/* PAS202BCB */
-	reg_w(dev, 0x08, 0x8d);
+	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
 	msleep(500);
 	retbyte = i2c_read(gspca_dev, 0x03);
@@ -6830,7 +6830,6 @@
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
 	{0x8400, 0x15},		/* TAS5130K */
-	{0, 0}
 };
 
 static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6843,7 +6842,7 @@
 
 /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
 	reg_w(dev, 0x02, 0x0010);
-	reg_r(gspca_dev, 0x10);
+	reg_r(gspca_dev, 0x0010);
 	reg_w(dev, 0x01, 0x0000);
 	reg_w(dev, 0x00, 0x0010);
 	reg_w(dev, 0x01, 0x0001);
@@ -6869,17 +6868,15 @@
 	PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
 	reg_r(gspca_dev, 0x0010);
 	/* this is tested only once anyway */
-	i = 0;
-	while (chipset_revision_sensor[i].revision) {
+	for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
 		if (chipset_revision_sensor[i].revision == checkword) {
 			sd->chip_revision = checkword;
 			send_unknown(dev, SENSOR_PB0330);
 			return chipset_revision_sensor[i].internal_sensor_id;
 		}
-		i++;
 	}
 
-	reg_w(dev, 0x01, 0x0000);
+	reg_w(dev, 0x01, 0x0000);	/* check ?? */
 	reg_w(dev, 0x01, 0x0001);
 	reg_w(dev, 0xdd, 0x008b);
 	reg_w(dev, 0x0a, 0x0010);
@@ -6901,8 +6898,11 @@
 	retbyte = i2c_read(gspca_dev, 0x00);
 	if (retbyte != 0) {
 		PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
-		send_unknown(dev, SENSOR_GC0305);
-		return retbyte;		/* 0x29 = gc0305 - should continue? */
+		if (retbyte == 0x11)			/* VF0250 */
+			return 0x0250;
+		if (retbyte == 0x29)			/* gc0305 */
+			send_unknown(dev, SENSOR_GC0305);
+		return retbyte;
 	}
 
 	reg_w(dev, 0x01, 0x0000);	/* check OmniVision */
@@ -6918,18 +6918,18 @@
 		return 0x06;		/* OmniVision confirm ? */
 	}
 
-	reg_w(dev, 0x01, 0x00);
-	reg_w(dev, 0x00, 0x02);
-	reg_w(dev, 0x01, 0x10);
-	reg_w(dev, 0x01, 0x01);
-	reg_w(dev, 0xee, 0x8b);
-	reg_w(dev, 0x03, 0x12);
+	reg_w(dev, 0x01, 0x0000);
+	reg_w(dev, 0x00, 0x0002);
+	reg_w(dev, 0x01, 0x0010);
+	reg_w(dev, 0x01, 0x0001);
+	reg_w(dev, 0xee, 0x008b);
+	reg_w(dev, 0x03, 0x0012);
 /*	msleep(150); */
-	reg_w(dev, 0x01, 0x12);
-	reg_w(dev, 0x05, 0x12);
-	retbyte = i2c_read(gspca_dev, 0x00);		/* ID 0 */
+	reg_w(dev, 0x01, 0x0012);
+	reg_w(dev, 0x05, 0x0012);
+	retbyte = i2c_read(gspca_dev, 0x0000);		/* ID 0 */
 	checkword = retbyte << 8;
-	retbyte = i2c_read(gspca_dev, 0x01);		/* ID 1 */
+	retbyte = i2c_read(gspca_dev, 0x0001);		/* ID 1 */
 	checkword |= retbyte;
 	PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
 	if (checkword == 0x2030) {
@@ -6939,14 +6939,14 @@
 		return checkword;
 	}
 
-	reg_w(dev, 0x01, 0x00);
-	reg_w(dev, 0x0a, 0x10);
-	reg_w(dev, 0xd3, 0x8b);
-	reg_w(dev, 0x01, 0x01);
-	reg_w(dev, 0x03, 0x12);
-	reg_w(dev, 0x01, 0x12);
-	reg_w(dev, 0x05, 0x01);
-	reg_w(dev, 0xd3, 0x8b);
+	reg_w(dev, 0x01, 0x0000);
+	reg_w(dev, 0x0a, 0x0010);
+	reg_w(dev, 0xd3, 0x008b);
+	reg_w(dev, 0x01, 0x0001);
+	reg_w(dev, 0x03, 0x0012);
+	reg_w(dev, 0x01, 0x0012);
+	reg_w(dev, 0x05, 0x0001);
+	reg_w(dev, 0xd3, 0x008b);
 	retbyte = i2c_read(gspca_dev, 0x01);
 	if (retbyte != 0) {
 		PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
@@ -6962,7 +6962,9 @@
 
 	switch (sd->sensor) {
 	case SENSOR_MC501CB:
+		return -1;		/* don't probe */
 	case SENSOR_TAS5130C_VF0250:
+				/* may probe but with write in reg 0x0010 */
 		return -1;		/* don't probe */
 	}
 	sensor = vga_2wr_probe(gspca_dev);
@@ -7010,30 +7012,7 @@
 
 	/* define some sensors from the vendor/product */
 	sd->sharpness = 2;
-	switch (id->idVendor) {
-	case 0x041e:				/* Creative */
-		switch (id->idProduct) {
-		case 0x4051:			/* zc301 chips */
-		case 0x4053:
-			sd->sensor = SENSOR_TAS5130C_VF0250;
-			break;
-		}
-		break;
-	case 0x046d:				/* Logitech Labtec */
-		switch (id->idProduct) {
-		case 0x08dd:
-			sd->sensor = SENSOR_MC501CB;
-			break;
-		}
-		break;
-	case 0x0ac8:				/* Vimicro z-star */
-		switch (id->idProduct) {
-		case 0x305b:
-			sd->sensor = SENSOR_TAS5130C_VF0250;
-			break;
-		}
-		break;
-	}
+	sd->sensor = id->driver_info;
 	sensor = zcxx_probeSensor(gspca_dev);
 	if (sensor >= 0)
 		PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
@@ -7119,6 +7098,10 @@
 			PDEBUG(D_PROBE, "Find Sensor GC0305");
 			sd->sensor = SENSOR_GC0305;
 			break;
+		case 0x0250:
+			PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)");
+			sd->sensor =  SENSOR_TAS5130C_VF0250;
+			break;
 		case 0x2030:
 			PDEBUG(D_PROBE, "Find Sensor PO2030");
 			sd->sensor = SENSOR_PO2030;
@@ -7146,7 +7129,6 @@
 	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 /*fixme:test*/
 	gspca_dev->nbalt--;
@@ -7235,6 +7217,7 @@
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
 	case SENSOR_PO2030:
+	case SENSOR_TAS5130C_VF0250:
 		msleep(100);			/* ?? */
 		reg_r(gspca_dev, 0x0002);	/* --> 0x40 */
 		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
@@ -7515,70 +7498,69 @@
 	.querymenu = sd_querymenu,
 };
 
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")},
+	{USB_DEVICE(0x041e, 0x041e)},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")},
-	{USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")},
-	{USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")},
-	{USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")},
+	{USB_DEVICE(0x041e, 0x4017)},
+	{USB_DEVICE(0x041e, 0x401c)},
+	{USB_DEVICE(0x041e, 0x401e)},
+	{USB_DEVICE(0x041e, 0x401f)},
 #endif
-	{USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")},
+	{USB_DEVICE(0x041e, 0x4029)},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")},
-	{USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")},
-	{USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")},
-	{USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")},
+	{USB_DEVICE(0x041e, 0x4034)},
+	{USB_DEVICE(0x041e, 0x4035)},
+	{USB_DEVICE(0x041e, 0x4036)},
+	{USB_DEVICE(0x041e, 0x403a)},
 #endif
-	{USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")},
-	{USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")},
+	{USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
+	{USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")},
-	{USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")},
-	{USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")},
+	{USB_DEVICE(0x0458, 0x7007)},
+	{USB_DEVICE(0x0458, 0x700c)},
+	{USB_DEVICE(0x0458, 0x700f)},
 #endif
-	{USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")},
-	{USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")},
-	{USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")},
-	{USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")},
-	{USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")},
-	{USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")},
-	{USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")},
-	{USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")},
-	{USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")},
-	{USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")},
-	{USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")},
+	{USB_DEVICE(0x0461, 0x0a00)},
+	{USB_DEVICE(0x046d, 0x08a0)},
+	{USB_DEVICE(0x046d, 0x08a1)},
+	{USB_DEVICE(0x046d, 0x08a2)},
+	{USB_DEVICE(0x046d, 0x08a3)},
+	{USB_DEVICE(0x046d, 0x08a6)},
+	{USB_DEVICE(0x046d, 0x08a7)},
+	{USB_DEVICE(0x046d, 0x08a9)},
+	{USB_DEVICE(0x046d, 0x08aa)},
+	{USB_DEVICE(0x046d, 0x08ac)},
+	{USB_DEVICE(0x046d, 0x08ad)},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")},
+	{USB_DEVICE(0x046d, 0x08ae)},
 #endif
-	{USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")},
-	{USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")},
-	{USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")},
-	{USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")},
-	{USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")},
-	{USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")},
-	{USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")},
-	{USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")},
-	{USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")},
-	{USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")},
-	{USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")},
-	{USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")},
+	{USB_DEVICE(0x046d, 0x08af)},
+	{USB_DEVICE(0x046d, 0x08b9)},
+	{USB_DEVICE(0x046d, 0x08d7)},
+	{USB_DEVICE(0x046d, 0x08d9)},
+	{USB_DEVICE(0x046d, 0x08d8)},
+	{USB_DEVICE(0x046d, 0x08da)},
+	{USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
+	{USB_DEVICE(0x0471, 0x0325)},
+	{USB_DEVICE(0x0471, 0x0326)},
+	{USB_DEVICE(0x0471, 0x032d)},
+	{USB_DEVICE(0x0471, 0x032e)},
+	{USB_DEVICE(0x055f, 0xc005)},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")},
-	{USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")},
+	{USB_DEVICE(0x055f, 0xd003)},
+	{USB_DEVICE(0x055f, 0xd004)},
 #endif
-	{USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")},
-	{USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")},
+	{USB_DEVICE(0x0698, 0x2003)},
+	{USB_DEVICE(0x0ac8, 0x0302)},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")},
-	{USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")},
+	{USB_DEVICE(0x0ac8, 0x301b)},
+	{USB_DEVICE(0x0ac8, 0x303b)},
 #endif
-	{USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")},
+	{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
 #ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")},
-	{USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")},
-	{USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")},
+	{USB_DEVICE(0x0ac8, 0x307b)},
+	{USB_DEVICE(0x10fd, 0x0128)},
+	{USB_DEVICE(0x10fd, 0x8050)},
 #endif
 	{}			/* end of entry */
 };
@@ -7605,7 +7587,7 @@
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "v%s registered", version);
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index 5d7ee8f..0069898b 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -2,9 +2,7 @@
 	tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
 	depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
 	depends on INPUT   # due to VIDEO_IR
-	depends on HOTPLUG # due to FW_LOADER
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_IR
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 41fd792..aea1664 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -465,9 +465,8 @@
 	if (itv->options.radio == -1)
 		itv->options.radio = (tv.has_radio != 0);
 	/* only enable newi2c if an IR blaster is present */
-	/* FIXME: for 2.6.20 the test against 2 should be removed */
-	if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) {
-		itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0;
+	if (itv->options.newi2c == -1 && tv.has_ir) {
+		itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0;
 		if (itv->options.newi2c) {
 		    IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
 		    exit_ivtv_i2c(itv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index a08bb33..ab287b4 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -60,6 +60,7 @@
 #include <linux/dvb/video.h>
 #include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tuner.h>
 #include <media/cx2341x.h>
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 52e00a7..6103030 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1842,69 +1842,73 @@
 	return res;
 }
 
+static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
+	.vidioc_querycap    		    = ivtv_querycap,
+	.vidioc_g_priority  		    = ivtv_g_priority,
+	.vidioc_s_priority  		    = ivtv_s_priority,
+	.vidioc_s_audio     		    = ivtv_s_audio,
+	.vidioc_g_audio     		    = ivtv_g_audio,
+	.vidioc_enumaudio   		    = ivtv_enumaudio,
+	.vidioc_s_audout     		    = ivtv_s_audout,
+	.vidioc_g_audout     		    = ivtv_g_audout,
+	.vidioc_enum_input   		    = ivtv_enum_input,
+	.vidioc_enum_output   		    = ivtv_enum_output,
+	.vidioc_enumaudout   		    = ivtv_enumaudout,
+	.vidioc_cropcap       		    = ivtv_cropcap,
+	.vidioc_s_crop       		    = ivtv_s_crop,
+	.vidioc_g_crop       		    = ivtv_g_crop,
+	.vidioc_g_input      		    = ivtv_g_input,
+	.vidioc_s_input      		    = ivtv_s_input,
+	.vidioc_g_output     		    = ivtv_g_output,
+	.vidioc_s_output     		    = ivtv_s_output,
+	.vidioc_g_frequency 		    = ivtv_g_frequency,
+	.vidioc_s_frequency  		    = ivtv_s_frequency,
+	.vidioc_s_tuner      		    = ivtv_s_tuner,
+	.vidioc_g_tuner      		    = ivtv_g_tuner,
+	.vidioc_g_enc_index 		    = ivtv_g_enc_index,
+	.vidioc_g_fbuf			    = ivtv_g_fbuf,
+	.vidioc_s_fbuf			    = ivtv_s_fbuf,
+	.vidioc_g_std 			    = ivtv_g_std,
+	.vidioc_s_std 			    = ivtv_s_std,
+	.vidioc_overlay			    = ivtv_overlay,
+	.vidioc_log_status		    = ivtv_log_status,
+	.vidioc_enum_fmt_vid_cap 	    = ivtv_enum_fmt_vid_cap,
+	.vidioc_encoder_cmd  		    = ivtv_encoder_cmd,
+	.vidioc_try_encoder_cmd 	    = ivtv_try_encoder_cmd,
+	.vidioc_enum_fmt_vid_out 	    = ivtv_enum_fmt_vid_out,
+	.vidioc_g_fmt_vid_cap 		    = ivtv_g_fmt_vid_cap,
+	.vidioc_g_fmt_vbi_cap		    = ivtv_g_fmt_vbi_cap,
+	.vidioc_g_fmt_sliced_vbi_cap        = ivtv_g_fmt_sliced_vbi_cap,
+	.vidioc_g_fmt_vid_out               = ivtv_g_fmt_vid_out,
+	.vidioc_g_fmt_vid_out_overlay       = ivtv_g_fmt_vid_out_overlay,
+	.vidioc_g_fmt_sliced_vbi_out        = ivtv_g_fmt_sliced_vbi_out,
+	.vidioc_s_fmt_vid_cap  		    = ivtv_s_fmt_vid_cap,
+	.vidioc_s_fmt_vbi_cap 		    = ivtv_s_fmt_vbi_cap,
+	.vidioc_s_fmt_sliced_vbi_cap        = ivtv_s_fmt_sliced_vbi_cap,
+	.vidioc_s_fmt_vid_out               = ivtv_s_fmt_vid_out,
+	.vidioc_s_fmt_vid_out_overlay       = ivtv_s_fmt_vid_out_overlay,
+	.vidioc_s_fmt_sliced_vbi_out        = ivtv_s_fmt_sliced_vbi_out,
+	.vidioc_try_fmt_vid_cap  	    = ivtv_try_fmt_vid_cap,
+	.vidioc_try_fmt_vbi_cap		    = ivtv_try_fmt_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_cap      = ivtv_try_fmt_sliced_vbi_cap,
+	.vidioc_try_fmt_vid_out 	    = ivtv_try_fmt_vid_out,
+	.vidioc_try_fmt_vid_out_overlay     = ivtv_try_fmt_vid_out_overlay,
+	.vidioc_try_fmt_sliced_vbi_out 	    = ivtv_try_fmt_sliced_vbi_out,
+	.vidioc_g_sliced_vbi_cap 	    = ivtv_g_sliced_vbi_cap,
+	.vidioc_g_chip_ident 		    = ivtv_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register 		    = ivtv_g_register,
+	.vidioc_s_register 		    = ivtv_s_register,
+#endif
+	.vidioc_default 		    = ivtv_default,
+	.vidioc_queryctrl 		    = ivtv_queryctrl,
+	.vidioc_querymenu 		    = ivtv_querymenu,
+	.vidioc_g_ext_ctrls 		    = ivtv_g_ext_ctrls,
+	.vidioc_s_ext_ctrls 		    = ivtv_s_ext_ctrls,
+	.vidioc_try_ext_ctrls    	    = ivtv_try_ext_ctrls,
+};
+
 void ivtv_set_funcs(struct video_device *vdev)
 {
-	vdev->vidioc_querycap     	    = ivtv_querycap;
-	vdev->vidioc_g_priority   	    = ivtv_g_priority;
-	vdev->vidioc_s_priority   	    = ivtv_s_priority;
-	vdev->vidioc_s_audio      	    = ivtv_s_audio;
-	vdev->vidioc_g_audio      	    = ivtv_g_audio;
-	vdev->vidioc_enumaudio   	    = ivtv_enumaudio;
-	vdev->vidioc_s_audout     	    = ivtv_s_audout;
-	vdev->vidioc_g_audout     	    = ivtv_g_audout;
-	vdev->vidioc_enum_input   	    = ivtv_enum_input;
-	vdev->vidioc_enum_output   	    = ivtv_enum_output;
-	vdev->vidioc_enumaudout   	    = ivtv_enumaudout;
-	vdev->vidioc_cropcap       	    = ivtv_cropcap;
-	vdev->vidioc_s_crop       	    = ivtv_s_crop;
-	vdev->vidioc_g_crop       	    = ivtv_g_crop;
-	vdev->vidioc_g_input      	    = ivtv_g_input;
-	vdev->vidioc_s_input      	    = ivtv_s_input;
-	vdev->vidioc_g_output     	    = ivtv_g_output;
-	vdev->vidioc_s_output     	    = ivtv_s_output;
-	vdev->vidioc_g_frequency 	    = ivtv_g_frequency;
-	vdev->vidioc_s_frequency  	    = ivtv_s_frequency;
-	vdev->vidioc_s_tuner      	    = ivtv_s_tuner;
-	vdev->vidioc_g_tuner      	    = ivtv_g_tuner;
-	vdev->vidioc_g_enc_index 	    = ivtv_g_enc_index;
-	vdev->vidioc_g_fbuf		    = ivtv_g_fbuf;
-	vdev->vidioc_s_fbuf		    = ivtv_s_fbuf;
-	vdev->vidioc_g_std 		    = ivtv_g_std;
-	vdev->vidioc_s_std 		    = ivtv_s_std;
-	vdev->vidioc_overlay		    = ivtv_overlay;
-	vdev->vidioc_log_status		    = ivtv_log_status;
-	vdev->vidioc_enum_fmt_vid_cap 	    = ivtv_enum_fmt_vid_cap;
-	vdev->vidioc_encoder_cmd  	    = ivtv_encoder_cmd;
-	vdev->vidioc_try_encoder_cmd 	    = ivtv_try_encoder_cmd;
-	vdev->vidioc_enum_fmt_vid_out       = ivtv_enum_fmt_vid_out;
-	vdev->vidioc_g_fmt_vid_cap  	    = ivtv_g_fmt_vid_cap;
-	vdev->vidioc_g_fmt_vbi_cap	    = ivtv_g_fmt_vbi_cap;
-	vdev->vidioc_g_fmt_sliced_vbi_cap   = ivtv_g_fmt_sliced_vbi_cap;
-	vdev->vidioc_g_fmt_vid_out          = ivtv_g_fmt_vid_out;
-	vdev->vidioc_g_fmt_vid_out_overlay  = ivtv_g_fmt_vid_out_overlay;
-	vdev->vidioc_g_fmt_sliced_vbi_out   = ivtv_g_fmt_sliced_vbi_out;
-	vdev->vidioc_s_fmt_vid_cap  	    = ivtv_s_fmt_vid_cap;
-	vdev->vidioc_s_fmt_vbi_cap 	    = ivtv_s_fmt_vbi_cap;
-	vdev->vidioc_s_fmt_sliced_vbi_cap   = ivtv_s_fmt_sliced_vbi_cap;
-	vdev->vidioc_s_fmt_vid_out          = ivtv_s_fmt_vid_out;
-	vdev->vidioc_s_fmt_vid_out_overlay  = ivtv_s_fmt_vid_out_overlay;
-	vdev->vidioc_s_fmt_sliced_vbi_out   = ivtv_s_fmt_sliced_vbi_out;
-	vdev->vidioc_try_fmt_vid_cap  	    = ivtv_try_fmt_vid_cap;
-	vdev->vidioc_try_fmt_vbi_cap	    = ivtv_try_fmt_vbi_cap;
-	vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap;
-	vdev->vidioc_try_fmt_vid_out        = ivtv_try_fmt_vid_out;
-	vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay;
-	vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out;
-	vdev->vidioc_g_sliced_vbi_cap 	    = ivtv_g_sliced_vbi_cap;
-	vdev->vidioc_g_chip_ident 	    = ivtv_g_chip_ident;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	vdev->vidioc_g_register 	    = ivtv_g_register;
-	vdev->vidioc_s_register 	    = ivtv_s_register;
-#endif
-	vdev->vidioc_default 		    = ivtv_default;
-	vdev->vidioc_queryctrl 		    = ivtv_queryctrl;
-	vdev->vidioc_querymenu 		    = ivtv_querymenu;
-	vdev->vidioc_g_ext_ctrls    	    = ivtv_g_ext_ctrls;
-	vdev->vidioc_s_ext_ctrls    	    = ivtv_s_ext_ctrls;
-	vdev->vidioc_try_ext_ctrls    	    = ivtv_try_ext_ctrls;
+	vdev->ioctl_ops = &ivtv_ioctl_ops;
 }
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index f8883b4..54d2023 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -208,16 +208,11 @@
 		return -ENOMEM;
 	}
 
-	s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
-		    VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
-	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
-		s->v4l2dev->type |= VID_TYPE_MPEG_DECODER;
-	}
 	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s",
 			itv->num, s->name);
 
 	s->v4l2dev->minor = minor;
-	s->v4l2dev->dev = &itv->dev->dev;
+	s->v4l2dev->parent = &itv->dev->dev;
 	s->v4l2dev->fops = ivtv_stream_info[type].fops;
 	s->v4l2dev->release = video_device_release;
 	s->v4l2dev->tvnorms = V4L2_STD_ALL;
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 39bf6b1..89a781c 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -26,7 +26,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/m52790.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 2fb5854..7c8ef6a 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <linux/delay.h>
@@ -1697,13 +1698,7 @@
 	.llseek		= no_llseek,
 };
 
-static struct video_device meye_template = {
-	.owner		= THIS_MODULE,
-	.name		= "meye",
-	.type		= VID_TYPE_CAPTURE,
-	.fops		= &meye_fops,
-	.release	= video_device_release,
-	.minor		= -1,
+static const struct v4l2_ioctl_ops meye_ioctl_ops = {
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_enum_input	= vidioc_enum_input,
 	.vidioc_g_input		= vidioc_g_input,
@@ -1724,6 +1719,14 @@
 	.vidioc_default		= vidioc_default,
 };
 
+static struct video_device meye_template = {
+	.name		= "meye",
+	.fops		= &meye_fops,
+	.ioctl_ops 	= &meye_ioctl_ops,
+	.release	= video_device_release,
+	.minor		= -1,
+};
+
 #ifdef CONFIG_PM
 static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -1801,7 +1804,7 @@
 	}
 
 	memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
-	meye.video_dev->dev = &meye.mchip_dev->dev;
+	meye.video_dev->parent = &meye.mchip_dev->dev;
 
 	if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
 		printk(KERN_ERR "meye: unable to power on the camera\n");
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 5691e01..3da74dc 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -51,9 +51,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
-#include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 1622f70..846a14a 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/freezer.h>
-#include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/msp3400.h>
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index ee43499..554d229 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -120,7 +120,7 @@
 	int ret;
 
 	/* Disable chip, synchronous option update */
-	dev_dbg(icd->vdev->dev, "%s\n", __func__);
+	dev_dbg(icd->vdev->parent, "%s\n", __func__);
 
 	ret = reg_write(icd, MT9M001_RESET, 1);
 	if (ret >= 0)
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index eafb0c7..9edaca4 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4666,9 +4666,7 @@
 };
 
 static struct video_device vdev_template = {
-	.owner =	THIS_MODULE,
 	.name =		"OV511 USB Camera",
-	.type =		VID_TYPE_CAPTURE,
 	.fops =		&ov511_fops,
 	.release =	video_device_release,
 	.minor =	-1,
@@ -5661,43 +5659,43 @@
 {
 	int rc;
 
-	rc = video_device_create_file(vdev, &dev_attr_custom_id);
+	rc = device_create_file(&vdev->dev, &dev_attr_custom_id);
 	if (rc) goto err;
-	rc = video_device_create_file(vdev, &dev_attr_model);
+	rc = device_create_file(&vdev->dev, &dev_attr_model);
 	if (rc) goto err_id;
-	rc = video_device_create_file(vdev, &dev_attr_bridge);
+	rc = device_create_file(&vdev->dev, &dev_attr_bridge);
 	if (rc) goto err_model;
-	rc = video_device_create_file(vdev, &dev_attr_sensor);
+	rc = device_create_file(&vdev->dev, &dev_attr_sensor);
 	if (rc) goto err_bridge;
-	rc = video_device_create_file(vdev, &dev_attr_brightness);
+	rc = device_create_file(&vdev->dev, &dev_attr_brightness);
 	if (rc) goto err_sensor;
-	rc = video_device_create_file(vdev, &dev_attr_saturation);
+	rc = device_create_file(&vdev->dev, &dev_attr_saturation);
 	if (rc) goto err_bright;
-	rc = video_device_create_file(vdev, &dev_attr_contrast);
+	rc = device_create_file(&vdev->dev, &dev_attr_contrast);
 	if (rc) goto err_sat;
-	rc = video_device_create_file(vdev, &dev_attr_hue);
+	rc = device_create_file(&vdev->dev, &dev_attr_hue);
 	if (rc) goto err_contrast;
-	rc = video_device_create_file(vdev, &dev_attr_exposure);
+	rc = device_create_file(&vdev->dev, &dev_attr_exposure);
 	if (rc) goto err_hue;
 
 	return 0;
 
 err_hue:
-	video_device_remove_file(vdev, &dev_attr_hue);
+	device_remove_file(&vdev->dev, &dev_attr_hue);
 err_contrast:
-	video_device_remove_file(vdev, &dev_attr_contrast);
+	device_remove_file(&vdev->dev, &dev_attr_contrast);
 err_sat:
-	video_device_remove_file(vdev, &dev_attr_saturation);
+	device_remove_file(&vdev->dev, &dev_attr_saturation);
 err_bright:
-	video_device_remove_file(vdev, &dev_attr_brightness);
+	device_remove_file(&vdev->dev, &dev_attr_brightness);
 err_sensor:
-	video_device_remove_file(vdev, &dev_attr_sensor);
+	device_remove_file(&vdev->dev, &dev_attr_sensor);
 err_bridge:
-	video_device_remove_file(vdev, &dev_attr_bridge);
+	device_remove_file(&vdev->dev, &dev_attr_bridge);
 err_model:
-	video_device_remove_file(vdev, &dev_attr_model);
+	device_remove_file(&vdev->dev, &dev_attr_model);
 err_id:
-	video_device_remove_file(vdev, &dev_attr_custom_id);
+	device_remove_file(&vdev->dev, &dev_attr_custom_id);
 err:
 	return rc;
 }
@@ -5833,7 +5831,7 @@
 		goto error;
 
 	memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
-	ov->vdev->dev = &intf->dev;
+	ov->vdev->parent = &intf->dev;
 	video_set_drvdata(ov->vdev, ov);
 
 	for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 1010e51..baded12 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -4,6 +4,7 @@
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
 
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 36047d4..e69de29 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -1,2309 +0,0 @@
-/*
-    planb - PlanB frame grabber driver
-
-    PlanB is used in the 7x00/8x00 series of PowerMacintosh
-    Computers as video input DMA controller.
-
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
-    Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
-    Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
-    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.
-*/
-
-/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <linux/wait.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/dbdma.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <linux/mutex.h>
-
-#include "planb.h"
-#include "saa7196.h"
-
-/* Would you mind for some ugly debugging? */
-#if 0
-#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#else
-#define DEBUG(x...) 		/* Don't debug driver */
-#endif
-
-#if 0
-#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
-#else
-#define IDEBUG(x...) 		/* Don't debug interrupt part */
-#endif
-
-/* Ever seen a Mac with more than 1 of these? */
-#define PLANB_MAX 1
-
-static int planb_num;
-static struct planb planbs[PLANB_MAX];
-static volatile struct planb_registers *planb_regs;
-
-static int def_norm = PLANB_DEF_NORM;	/* default norm */
-static int video_nr = -1;
-
-module_param(def_norm, int, 0);
-MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
-module_param(video_nr, int, 0);
-MODULE_LICENSE("GPL");
-
-
-/* ------------------ PlanB Exported Functions ------------------ */
-static long planb_write(struct video_device *, const char *, unsigned long, int);
-static long planb_read(struct video_device *, char *, unsigned long, int);
-static int planb_open(struct video_device *, int);
-static void planb_close(struct video_device *);
-static int planb_ioctl(struct video_device *, unsigned int, void *);
-static int planb_init_done(struct video_device *);
-static int planb_mmap(struct video_device *, const char *, unsigned long);
-static void release_planb(void);
-int init_planbs(struct video_init *);
-
-/* ------------------ PlanB Internal Functions ------------------ */
-static int planb_prepare_open(struct planb *);
-static void planb_prepare_close(struct planb *);
-static void saa_write_reg(unsigned char, unsigned char);
-static unsigned char saa_status(int, struct planb *);
-static void saa_set(unsigned char, unsigned char, struct planb *);
-static void saa_init_regs(struct planb *);
-static int grabbuf_alloc(struct planb *);
-static int vgrab(struct planb *, struct video_mmap *);
-static void add_clip(struct planb *, struct video_clip *);
-static void fill_cmd_buff(struct planb *);
-static void cmd_buff(struct planb *);
-static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
-static void overlay_start(struct planb *);
-static void overlay_stop(struct planb *);
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
-	unsigned int);
-static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
-	unsigned int);
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
-	unsigned short, unsigned int, unsigned int);
-static int init_planb(struct planb *);
-static int find_planb(void);
-static void planb_pre_capture(int, int, struct planb *);
-static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
-					int, int, int, int, int, struct planb *);
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
-static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
-static inline int overlay_is_active(struct planb *);
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-static int grabbuf_alloc(struct planb *pb)
-{
-	int i, npage;
-
-	npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
-#ifndef PLANB_GSCANLINE
-		+ MAX_LNUM
-#endif /* PLANB_GSCANLINE */
-		);
-	if ((pb->rawbuf = kmalloc(npage
-				* sizeof(unsigned long), GFP_KERNEL)) == 0)
-		return -ENOMEM;
-	for (i = 0; i < npage; i++) {
-		pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
-								|GFP_DMA, 0);
-		if (!pb->rawbuf[i])
-			break;
-		SetPageReserved(virt_to_page(pb->rawbuf[i]));
-	}
-	if (i-- < npage) {
-		printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
-		for (; i > 0; i--) {
-			ClearPageReserved(virt_to_page(pb->rawbuf[i]));
-			free_pages((unsigned long)pb->rawbuf[i], 0);
-		}
-		kfree(pb->rawbuf);
-		return -ENOBUFS;
-	}
-	pb->rawbuf_size = npage;
-	return 0;
-}
-
-/*****************************/
-/* Hardware access functions */
-/*****************************/
-
-static void saa_write_reg(unsigned char addr, unsigned char val)
-{
-	planb_regs->saa_addr = addr; eieio();
-	planb_regs->saa_regval = val; eieio();
-	return;
-}
-
-/* return  status byte 0 or 1: */
-static unsigned char saa_status(int byte, struct planb *pb)
-{
-	saa_regs[pb->win.norm][SAA7196_STDC] =
-		(saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
-	saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
-
-	/* Let's wait 30msec for this one */
-	msleep_interruptible(30);
-
-	return (unsigned char)in_8 (&planb_regs->saa_status);
-}
-
-static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
-{
-	if(saa_regs[pb->win.norm][addr] != val) {
-		saa_regs[pb->win.norm][addr] = val;
-		saa_write_reg (addr, val);
-	}
-	return;
-}
-
-static void saa_init_regs(struct planb *pb)
-{
-	int i;
-
-	for (i = 0; i < SAA7196_NUMREGS; i++)
-		saa_write_reg (i, saa_regs[pb->win.norm][i]);
-}
-
-static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
-	struct planb *pb)
-{
-	int ht, norm = pb->win.norm;
-
-	switch(bpp) {
-	case 2:
-		/* RGB555+a 1x16-bit + 16-bit transparent */
-		saa_regs[norm][SAA7196_FMTS] &= ~0x3;
-		break;
-	case 1:
-	case 4:
-		/* RGB888 1x24-bit + 8-bit transparent */
-		saa_regs[norm][SAA7196_FMTS] &= ~0x1;
-		saa_regs[norm][SAA7196_FMTS] |= 0x2;
-		break;
-	default:
-		return -EINVAL;
-	}
-	ht = (interlace ? height / 2 : height);
-	saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
-	saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
-						| (width >> 8 & 0x3);
-	saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
-	saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
-						| (ht >> 8 & 0x3);
-	/* feed both fields if interlaced, or else feed only even fields */
-	saa_regs[norm][SAA7196_FMTS] = (interlace) ?
-					(saa_regs[norm][SAA7196_FMTS] & ~0x60)
-					: (saa_regs[norm][SAA7196_FMTS] | 0x60);
-	/* transparent mode; extended format enabled */
-	saa_regs[norm][SAA7196_DPATH] |= 0x3;
-
-	return 0;
-}
-
-/***************************/
-/* DBDMA support functions */
-/***************************/
-
-static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
-{
-	out_le32(&ch->control, PLANB_CLR(RUN));
-	out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
-}
-
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
-{
-	int i = 0;
-
-	out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
-	while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
-		IDEBUG("PlanB: waiting for DMA to stop\n");
-		i++;
-	}
-}
-
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
-	unsigned short command, unsigned int cmd_dep)
-{
-	st_le16(&ch->command, command);
-	st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
-	unsigned int phy_addr, unsigned int cmd_dep)
-{
-	st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
-	st_le16(&ch->req_count, 4);
-	st_le32(&ch->phy_addr, phy_addr);
-	st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
-	unsigned short command, unsigned short req_count,
-	unsigned int phy_addr, unsigned int cmd_dep)
-{
-	st_le16(&ch->command, command);
-	st_le16(&ch->req_count, req_count);
-	st_le32(&ch->phy_addr, phy_addr);
-	st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static volatile struct dbdma_cmd *cmd_geo_setup(
-	volatile struct dbdma_cmd *c1, int width, int height, int interlace,
-	int bpp, int clip, struct planb *pb)
-{
-	int norm = pb->win.norm;
-
-	if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
-		return (volatile struct dbdma_cmd *)NULL;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_FMTS);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_FMTS]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_DPATH);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_DPATH]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
-					bpp | ((clip)? PLANB_CLIPMASK: 0));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
-					bpp | ((clip)? PLANB_CLIPMASK: 0));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_OUTPIX);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_OUTPIX]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_HFILT);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_HFILT]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_OUTLINE);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_OUTLINE]);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
-							SAA7196_VYP);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
-					saa_regs[norm][SAA7196_VYP]);
-	return c1;
-}
-
-/******************************/
-/* misc. supporting functions */
-/******************************/
-
-static inline void planb_lock(struct planb *pb)
-{
-	mutex_lock(&pb->lock);
-}
-
-static inline void planb_unlock(struct planb *pb)
-{
-	mutex_unlock(&pb->lock);
-}
-
-/***************/
-/* Driver Core */
-/***************/
-
-static int planb_prepare_open(struct planb *pb)
-{
-	int	i, size;
-
-	/* allocate memory for two plus alpha command buffers (size: max lines,
-	   plus 40 commands handling, plus 1 alignment), plus dummy command buf,
-	   plus clipmask buffer, plus frame grabbing status */
-	size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
-		* PLANB_DUMMY)*sizeof(struct dbdma_cmd)
-		+(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
-		+MAX_GBUFFERS*sizeof(unsigned int);
-	if ((pb->priv_space = kzalloc (size, GFP_KERNEL)) == 0)
-		return -ENOMEM;
-	pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
-						DBDMA_ALIGN (pb->priv_space);
-	pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
-	pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
-	pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
-	pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
-	for (i = 1; i < MAX_GBUFFERS; i++) {
-		pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
-		pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
-	}
-	pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
-						+ PLANB_DUMMY);
-	pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
-
-	pb->rawbuf = NULL;
-	pb->rawbuf_size = 0;
-	pb->grabbing = 0;
-	for (i = 0; i < MAX_GBUFFERS; i++) {
-		pb->frame_stat[i] = GBUFFER_UNUSED;
-		pb->gwidth[i] = 0;
-		pb->gheight[i] = 0;
-		pb->gfmt[i] = 0;
-		pb->gnorm_switch[i] = 0;
-#ifndef PLANB_GSCANLINE
-		pb->lsize[i] = 0;
-		pb->lnum[i] = 0;
-#endif /* PLANB_GSCANLINE */
-	}
-	pb->gcount = 0;
-	pb->suspend = 0;
-	pb->last_fr = -999;
-	pb->prev_last_fr = -999;
-
-	/* Reset DMA controllers */
-	planb_dbdma_stop(&pb->planb_base->ch2);
-	planb_dbdma_stop(&pb->planb_base->ch1);
-
-	return 0;
-}
-
-static void planb_prepare_close(struct planb *pb)
-{
-	int i;
-
-	/* make sure the dma's are idle */
-	planb_dbdma_stop(&pb->planb_base->ch2);
-	planb_dbdma_stop(&pb->planb_base->ch1);
-	/* free kernel memory of command buffers */
-	if(pb->priv_space != 0) {
-		kfree (pb->priv_space);
-		pb->priv_space = 0;
-		pb->cmd_buff_inited = 0;
-	}
-	if(pb->rawbuf) {
-		for (i = 0; i < pb->rawbuf_size; i++) {
-			ClearPageReserved(virt_to_page(pb->rawbuf[i]));
-			free_pages((unsigned long)pb->rawbuf[i], 0);
-		}
-		kfree(pb->rawbuf);
-	}
-	pb->rawbuf = NULL;
-}
-
-/*****************************/
-/* overlay support functions */
-/*****************************/
-
-static inline int overlay_is_active(struct planb *pb)
-{
-	unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
-	unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
-
-	return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
-			&& (caddr < (pb->ch1_cmd_phys + size))
-			&& (caddr >= (unsigned)pb->ch1_cmd_phys);
-}
-
-static void overlay_start(struct planb *pb)
-{
-
-	DEBUG("PlanB: overlay_start()\n");
-
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
-
-		DEBUG("PlanB: presumably, grabbing is in progress...\n");
-
-		planb_dbdma_stop(&pb->planb_base->ch2);
-		out_le32 (&pb->planb_base->ch2.cmdptr,
-						virt_to_bus(pb->ch2_cmd));
-		planb_dbdma_restart(&pb->planb_base->ch2);
-		st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
-		tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
-		eieio();
-		pb->prev_last_fr = pb->last_fr;
-		pb->last_fr = -2;
-		if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-			IDEBUG("PlanB: became inactive "
-				"in the mean time... reactivating\n");
-			planb_dbdma_stop(&pb->planb_base->ch1);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->ch1_cmd));
-			planb_dbdma_restart(&pb->planb_base->ch1);
-		}
-	} else {
-
-		DEBUG("PlanB: currently idle, so can do whatever\n");
-
-		planb_dbdma_stop(&pb->planb_base->ch2);
-		planb_dbdma_stop(&pb->planb_base->ch1);
-		st_le32 (&pb->planb_base->ch2.cmdptr,
-						virt_to_bus(pb->ch2_cmd));
-		st_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->ch1_cmd));
-		out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
-		planb_dbdma_restart(&pb->planb_base->ch2);
-		planb_dbdma_restart(&pb->planb_base->ch1);
-		pb->last_fr = -1;
-	}
-	return;
-}
-
-static void overlay_stop(struct planb *pb)
-{
-	DEBUG("PlanB: overlay_stop()\n");
-
-	if(pb->last_fr == -1) {
-
-		DEBUG("PlanB: no grabbing, it seems...\n");
-
-		planb_dbdma_stop(&pb->planb_base->ch2);
-		planb_dbdma_stop(&pb->planb_base->ch1);
-		pb->last_fr = -999;
-	} else if(pb->last_fr == -2) {
-		unsigned int cmd_dep;
-		tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
-		eieio();
-		cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
-		if(overlay_is_active(pb)) {
-
-			DEBUG("PlanB: overlay is currently active\n");
-
-			planb_dbdma_stop(&pb->planb_base->ch2);
-			planb_dbdma_stop(&pb->planb_base->ch1);
-			if(cmd_dep != pb->ch1_cmd_phys) {
-				out_le32(&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->overlay_last1));
-				planb_dbdma_restart(&pb->planb_base->ch1);
-			}
-		}
-		pb->last_fr = pb->prev_last_fr;
-		pb->prev_last_fr = -999;
-	}
-	return;
-}
-
-static void suspend_overlay(struct planb *pb)
-{
-	int fr = -1;
-	struct dbdma_cmd last;
-
-	DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
-
-	if(pb->suspend++)
-		return;
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
-		if(pb->last_fr == -2) {
-			fr = pb->prev_last_fr;
-			memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
-			tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
-		}
-		if(overlay_is_active(pb)) {
-			planb_dbdma_stop(&pb->planb_base->ch2);
-			planb_dbdma_stop(&pb->planb_base->ch1);
-			pb->suspended.overlay = 1;
-			pb->suspended.frame = fr;
-			memcpy(&pb->suspended.cmd, &last, sizeof(last));
-			return;
-		}
-	}
-	pb->suspended.overlay = 0;
-	pb->suspended.frame = fr;
-	memcpy(&pb->suspended.cmd, &last, sizeof(last));
-	return;
-}
-
-static void resume_overlay(struct planb *pb)
-{
-
-	DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
-
-	if(pb->suspend > 1)
-		return;
-	if(pb->suspended.frame != -1) {
-		memcpy((void*)pb->last_cmd[pb->suspended.frame],
-				&pb->suspended.cmd, sizeof(pb->suspended.cmd));
-	}
-	if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
-		goto finish;
-	}
-	if(pb->suspended.overlay) {
-
-		DEBUG("PlanB: overlay being resumed\n");
-
-		st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
-		st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
-		/* Set command buffer addresses */
-		st_le32(&pb->planb_base->ch1.cmdptr,
-					virt_to_bus(pb->overlay_last1));
-		out_le32(&pb->planb_base->ch2.cmdptr,
-					virt_to_bus(pb->overlay_last2));
-		/* Start the DMA controller */
-		out_le32 (&pb->planb_base->ch2.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
-		out_le32 (&pb->planb_base->ch1.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
-	} else if(pb->suspended.frame != -1) {
-		out_le32(&pb->planb_base->ch1.cmdptr,
-				virt_to_bus(pb->last_cmd[pb->suspended.frame]));
-		out_le32 (&pb->planb_base->ch1.control,
-				PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
-	}
-
-finish:
-	pb->suspend--;
-	wake_up_interruptible(&pb->suspendq);
-}
-
-static void add_clip(struct planb *pb, struct video_clip *clip)
-{
-	volatile unsigned char	*base;
-	int	xc = clip->x, yc = clip->y;
-	int	wc = clip->width, hc = clip->height;
-	int	ww = pb->win.width, hw = pb->win.height;
-	int	x, y, xtmp1, xtmp2;
-
-	DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
-
-	if(xc < 0) {
-		wc += xc;
-		xc = 0;
-	}
-	if(yc < 0) {
-		hc += yc;
-		yc = 0;
-	}
-	if(xc + wc > ww)
-		wc = ww - xc;
-	if(wc <= 0) /* Nothing to do */
-		return;
-	if(yc + hc > hw)
-		hc = hw - yc;
-
-	for (y = yc; y < yc+hc; y++) {
-		xtmp1=xc>>3;
-		xtmp2=(xc+wc)>>3;
-		base = pb->mask + y*96;
-		if(xc != 0 || wc >= 8)
-			*(base + xtmp1) &= (unsigned char)(0x00ff &
-				(0xff00 >> (xc&7)));
-		for (x = xtmp1 + 1; x < xtmp2; x++) {
-			*(base + x) = 0;
-		}
-		if(xc < (ww & ~0x7))
-			*(base + xtmp2) &= (unsigned char)(0x00ff >>
-				((xc+wc) & 7));
-	}
-
-	return;
-}
-
-static void fill_cmd_buff(struct planb *pb)
-{
-	int restore = 0;
-	volatile struct dbdma_cmd last;
-
-	DEBUG("PlanB: fill_cmd_buff()\n");
-
-	if(pb->overlay_last1 != pb->ch1_cmd) {
-		restore = 1;
-		last = *(pb->overlay_last1);
-	}
-	memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
-					* sizeof(struct dbdma_cmd));
-	cmd_buff (pb);
-	if(restore)
-		*(pb->overlay_last1) = last;
-	if(pb->suspended.overlay) {
-		unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
-		if(jump_addr != pb->ch1_cmd_phys) {
-			int i;
-
-			DEBUG("PlanB: adjusting ch1's jump address\n");
-
-			for(i = 0; i < MAX_GBUFFERS; i++) {
-				if(pb->need_pre_capture[i]) {
-				    if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
-					goto found;
-				} else {
-				    if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
-					goto found;
-				}
-			}
-
-			DEBUG("PlanB: not found...\n");
-
-			goto out;
-found:
-			if(pb->need_pre_capture[i])
-				out_le32(&pb->pre_cmd[i]->phy_addr,
-						virt_to_bus(pb->overlay_last1));
-			else
-				out_le32(&pb->cap_cmd[i]->phy_addr,
-						virt_to_bus(pb->overlay_last1));
-		}
-	}
-out:
-	pb->cmd_buff_inited = 1;
-
-	return;
-}
-
-static void cmd_buff(struct planb *pb)
-{
-	int		i, bpp, count, nlines, stepsize, interlace;
-	unsigned long	base, jump, addr_com, addr_dep;
-	volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
-	volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
-
-	interlace = pb->win.interlace;
-	bpp = pb->win.bpp;
-	count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
-		(pb->win.swidth - pb->win.x) : pb->win.width));
-	nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
-		(pb->win.sheight - pb->win.y) : pb->win.height);
-
-	/* Do video in: */
-
-	/* Preamble commands: */
-	addr_com = virt_to_bus(c1);
-	addr_dep = virt_to_bus(&c1->cmd_dep);
-	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
-	jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
-	if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
-					bpp, 1, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered serious problems\n");
-		tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
-		tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
-		return;
-	}
-	tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
-	tab_cmd_store(c1++, addr_dep, jump);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
-							PLANB_SET(FIELD_SYNC));
-		/* (1) wait for field sync to be set */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-							PLANB_SET(ODD_FIELD));
-		/* wait for field sync to be cleared */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-		/* if not odd field, wait until field sync is set again */
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
-		/* assert ch_sync to ch2 */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
-							PLANB_SET(CH_SYNC));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-							PLANB_SET(DMA_ABORT));
-
-	base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
-					+ pb->win.pad) + pb->win.x * bpp);
-
-	if (interlace) {
-		stepsize = 2;
-		jump = virt_to_bus(c1 + (nlines + 1) / 2);
-	} else {
-		stepsize = 1;
-		jump = virt_to_bus(c1 + nlines);
-	}
-
-	/* even field data: */
-	for (i=0; i < nlines; i += stepsize, c1++)
-		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
-			count, base + i * (pb->win.bpl + pb->win.pad), jump);
-
-	/* For non-interlaced, we use even fields only */
-	if (!interlace)
-		goto cmd_tab_data_end;
-
-	/* Resync to odd field */
-		/* (2) wait for field sync to be set */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-							PLANB_SET(ODD_FIELD));
-		/* wait for field sync to be cleared */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-		/* if not odd field, wait until field sync is set again */
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
-		/* assert ch_sync to ch2 */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
-							PLANB_SET(CH_SYNC));
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-							PLANB_SET(DMA_ABORT));
-
-	/* odd field data: */
-	jump = virt_to_bus(c1 + nlines / 2);
-	for (i=1; i < nlines; i += stepsize, c1++)
-		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
-			base + i * (pb->win.bpl + pb->win.pad), jump);
-
-	/* And jump back to the start */
-cmd_tab_data_end:
-	pb->overlay_last1 = c1;	/* keep a pointer to the last command */
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
-
-	/* Clipmask command buffer */
-
-	/* Preamble commands: */
-	tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
-							PLANB_SET(CH_SYNC));
-		/* wait until ch1 asserts ch_sync */
-	tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
-		/* clear ch_sync asserted by ch1 */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
-							PLANB_CLR(CH_SYNC));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
-							PLANB_SET(FIELD_SYNC));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
-							PLANB_SET(ODD_FIELD));
-
-	/* jump to end of even field if appropriate */
-	/* this points to (interlace)? pos. C: pos. B */
-	jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
-						virt_to_bus(c2 + nlines + 2);
-		/* if odd field, skip over to odd field clipmasking */
-	tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
-
-	/* even field mask: */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
-							PLANB_SET(DMA_ABORT));
-	/* this points to pos. B */
-	jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
-						virt_to_bus(c2 + nlines);
-	base = virt_to_bus(pb->mask);
-	for (i=0; i < nlines; i += stepsize, c2++)
-		tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
-			base + i * 96, jump);
-
-	/* For non-interlaced, we use only even fields */
-	if(!interlace)
-		goto cmd_tab_mask_end;
-
-	/* odd field mask: */
-/* C */	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
-							PLANB_SET(DMA_ABORT));
-	/* this points to pos. B */
-	jump = virt_to_bus(c2 + nlines / 2);
-	base = virt_to_bus(pb->mask);
-	for (i=1; i < nlines; i += 2, c2++)     /* abort if set */
-		tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
-			base + i * 96, jump);
-
-	/* Inform channel 1 and jump back to start */
-cmd_tab_mask_end:
-	/* ok, I just realized this is kind of flawed. */
-	/* this part is reached only after odd field clipmasking. */
-	/* wanna clean up? */
-		/* wait for field sync to be set */
-		/* corresponds to fsync (1) of ch1 */
-/* B */	tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
-		/* restart ch1, meant to clear any dead bit or something */
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
-							PLANB_CLR(RUN));
-	tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
-							PLANB_SET(RUN));
-	pb->overlay_last2 = c2;	/* keep a pointer to the last command */
-		/* start over even field clipmasking */
-	tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
-
-	eieio();
-	return;
-}
-
-/*********************************/
-/* grabdisplay support functions */
-/*********************************/
-
-static int palette2fmt[] = {
-	0,
-	PLANB_GRAY,
-	0,
-	0,
-	0,
-	PLANB_COLOUR32,
-	PLANB_COLOUR15,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-	0,
-};
-
-#define PLANB_PALETTE_MAX 15
-
-static int vgrab(struct planb *pb, struct video_mmap *mp)
-{
-	unsigned int fr = mp->frame;
-	unsigned int format;
-
-	if(pb->rawbuf==NULL) {
-		int err;
-		if((err=grabbuf_alloc(pb)))
-			return err;
-	}
-
-	IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
-						mp->width, mp->height, fr);
-
-	if(pb->grabbing >= MAX_GBUFFERS)
-		return -ENOBUFS;
-	if(fr > (MAX_GBUFFERS - 1) || fr < 0)
-		return -EINVAL;
-	if(mp->height <= 0 || mp->width <= 0)
-		return -EINVAL;
-	if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
-		return -EINVAL;
-	if((format = palette2fmt[mp->format]) == 0)
-		return -EINVAL;
-	if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
-		return -EINVAL;
-
-	planb_lock(pb);
-	if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
-			format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
-		int i;
-#ifndef PLANB_GSCANLINE
-		unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
-								* pb->gfmt[fr];
-		unsigned int nsize = mp->width * mp->height * format;
-#endif
-
-		IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
-					mp->width, mp->height, mp->format);
-
-#ifndef PLANB_GSCANLINE
-		if(pb->gnorm_switch[fr])
-			nsize = 0;
-		if (nsize < osize) {
-			for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
-				memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
-				osize -= PAGE_SIZE;
-			}
-		}
-		for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
-							+ pb->lnum[fr]; i++)
-			memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
-#else
-/* XXX TODO */
-/*
-		if(pb->gnorm_switch[fr])
-			memset((void *)pb->gbuffer[fr], 0,
-					pb->gbytes_per_line * pb->gheight[fr]);
-		else {
-			if(mp->
-			for(i = 0; i < pb->gheight[fr]; i++) {
-				memset((void *)(pb->gbuffer[fr]
-					+ pb->gbytes_per_line * i
-			}
-		}
-*/
-#endif
-		pb->gwidth[fr] = mp->width;
-		pb->gheight[fr] = mp->height;
-		pb->gfmt[fr] = format;
-		pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
-		planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
-		pb->need_pre_capture[fr] = 1;
-		pb->gnorm_switch[fr] = 0;
-	} else
-		pb->need_pre_capture[fr] = 0;
-	pb->frame_stat[fr] = GBUFFER_GRABBING;
-	if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
-		IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
-
-		planb_dbdma_stop(&pb->planb_base->ch1);
-		if(pb->need_pre_capture[fr]) {
-
-			IDEBUG("PlanB: padding pre-capture sequence\n");
-
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->pre_cmd[fr]));
-		} else {
-			tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
-			tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
-		/* let's be on the safe side. here is not timing critical. */
-			tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->cap_cmd[fr]));
-		}
-		planb_dbdma_restart(&pb->planb_base->ch1);
-		pb->last_fr = fr;
-	} else {
-		int i;
-
-		IDEBUG("PlanB: ch1 active, grabbing being queued\n");
-
-		if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
-						overlay_is_active(pb))) {
-
-			IDEBUG("PlanB: overlay is active, grabbing defered\n");
-
-			tab_cmd_dbdma(pb->last_cmd[fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
-			if(pb->need_pre_capture[fr]) {
-
-				IDEBUG("PlanB: padding pre-capture sequence\n");
-
-				tab_cmd_store(pb->pre_cmd[fr],
-				    virt_to_bus(&pb->overlay_last1->cmd_dep),
-						virt_to_bus(pb->ch1_cmd));
-				eieio();
-				out_le32 (&pb->overlay_last1->cmd_dep,
-						virt_to_bus(pb->pre_cmd[fr]));
-			} else {
-				tab_cmd_store(pb->cap_cmd[fr],
-				    virt_to_bus(&pb->overlay_last1->cmd_dep),
-						virt_to_bus(pb->ch1_cmd));
-				tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
-								DBDMA_NOP, 0);
-				eieio();
-				out_le32 (&pb->overlay_last1->cmd_dep,
-						virt_to_bus(pb->cap_cmd[fr]));
-			}
-			for(i = 0; overlay_is_active(pb) && i < 999; i++)
-				IDEBUG("PlanB: waiting for overlay done\n");
-			tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
-			pb->prev_last_fr = fr;
-			pb->last_fr = -2;
-		} else if(pb->last_fr == -2) {
-
-			IDEBUG("PlanB: mixed mode detected, grabbing"
-				" will be done before activating overlay\n");
-
-			tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
-			if(pb->need_pre_capture[fr]) {
-
-				IDEBUG("PlanB: padding pre-capture sequence\n");
-
-				tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
-						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->pre_cmd[fr]));
-				eieio();
-			} else {
-				tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
-				if(pb->gwidth[pb->prev_last_fr] !=
-								pb->gwidth[fr]
-					|| pb->gheight[pb->prev_last_fr] !=
-								pb->gheight[fr]
-					|| pb->gfmt[pb->prev_last_fr] !=
-								pb->gfmt[fr])
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
-								DBDMA_NOP, 0);
-				else
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
-					    DBDMA_NOP | BR_ALWAYS,
-					    virt_to_bus(pb->cap_cmd[fr] + 16));
-				tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
-						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->cap_cmd[fr]));
-				eieio();
-			}
-			tab_cmd_dbdma(pb->last_cmd[fr],
-					DBDMA_NOP | BR_ALWAYS,
-					virt_to_bus(pb->ch1_cmd));
-			eieio();
-			pb->prev_last_fr = fr;
-			pb->last_fr = -2;
-		} else {
-
-			IDEBUG("PlanB: active grabbing session detected\n");
-
-			if(pb->need_pre_capture[fr]) {
-
-				IDEBUG("PlanB: padding pre-capture sequence\n");
-
-				tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
-						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->pre_cmd[fr]));
-				eieio();
-			} else {
-				tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
-				tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
-				if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
-					|| pb->gheight[pb->last_fr] !=
-								pb->gheight[fr]
-					|| pb->gfmt[pb->last_fr] !=
-								pb->gfmt[fr])
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
-								DBDMA_NOP, 0);
-				else
-					tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
-					    DBDMA_NOP | BR_ALWAYS,
-					    virt_to_bus(pb->cap_cmd[fr] + 16));
-				tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
-						DBDMA_NOP | BR_ALWAYS,
-						virt_to_bus(pb->cap_cmd[fr]));
-				eieio();
-			}
-			pb->last_fr = fr;
-		}
-		if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
-			IDEBUG("PlanB: became inactive in the mean time..."
-				"reactivating\n");
-
-			planb_dbdma_stop(&pb->planb_base->ch1);
-			out_le32 (&pb->planb_base->ch1.cmdptr,
-						virt_to_bus(pb->cap_cmd[fr]));
-			planb_dbdma_restart(&pb->planb_base->ch1);
-		}
-	}
-	pb->grabbing++;
-	planb_unlock(pb);
-
-	return 0;
-}
-
-static void planb_pre_capture(int fr, int bpp, struct planb *pb)
-{
-	volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
-	int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
-
-	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
-	if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
-						bpp, 0, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered some problems\n");
-		tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
-		return;
-	}
-	/* Sync to even field */
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
-		PLANB_SET(FIELD_SYNC));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
-	tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
-	/* For non-interlaced, we use even fields only */
-	if (pb->gheight[fr] <= pb->maxlines/2)
-		goto cmd_tab_data_end;
-	/* Sync to odd field */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
-cmd_tab_data_end:
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
-
-	eieio();
-}
-
-static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
-{
-	int		i, bpp, count, nlines, stepsize, interlace;
-#ifdef PLANB_GSCANLINE
-	int		scanline;
-#else
-	int		nlpp, leftover1;
-	unsigned long	base;
-#endif
-	unsigned long	jump;
-	int		pagei;
-	volatile struct dbdma_cmd *c1;
-	volatile struct dbdma_cmd *jump_addr;
-
-	c1 = pb->cap_cmd[fr];
-	interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
-	bpp = pb->gfmt[fr];	/* gfmt = bpp */
-	count = bpp * pb->gwidth[fr];
-	nlines = pb->gheight[fr];
-#ifdef PLANB_GSCANLINE
-	scanline = pb->gbytes_per_line;
-#else
-	pb->lsize[fr] = count;
-	pb->lnum[fr] = 0;
-#endif
-
-	/* Do video in: */
-
-	/* Preamble commands: */
-	tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
-	if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
-						bpp, 0, pb)) == NULL) {
-		printk(KERN_WARNING "PlanB: encountered serious problems\n");
-		tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
-		return (pb->cap_cmd[fr] + 2);
-	}
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
-		PLANB_SET(FIELD_SYNC));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
-	tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
-
-	if (interlace) {
-		stepsize = 2;
-		jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
-	} else {
-		stepsize = 1;
-		jump_addr = c1 + TAB_FACTOR * nlines;
-	}
-	jump = virt_to_bus(jump_addr);
-
-	/* even field data: */
-
-	pagei = pb->gbuf_idx[fr];
-#ifdef PLANB_GSCANLINE
-	for (i = 0; i < nlines; i += stepsize) {
-		tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-					virt_to_bus(pb->rawbuf[pagei
-					+ i * scanline / PAGE_SIZE]), jump);
-	}
-#else
-	i = 0;
-	leftover1 = 0;
-	do {
-	    int j;
-
-	    base = virt_to_bus(pb->rawbuf[pagei]);
-	    nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
-	    for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
-		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
-			  count, base + count * j * stepsize + leftover1, jump);
-	    if(i < nlines) {
-		int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
-		if(lov0 == 0)
-		    leftover1 = 0;
-		else {
-		    if(lov0 >= count) {
-			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
-				+ count * nlpp * stepsize + leftover1, jump);
-		    } else {
-			pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
-					+ count * nlpp * stepsize + leftover1;
-			pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
-			pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
-			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-				virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
-						+ pb->lnum[fr]]), jump);
-			if(++pb->lnum[fr] > MAX_LNUM)
-				pb->lnum[fr]--;
-		    }
-		    leftover1 = count * stepsize - lov0;
-		    i += stepsize;
-		}
-	    }
-	    pagei++;
-	} while(i < nlines);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
-	c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
-	/* For non-interlaced, we use even fields only */
-	if (!interlace)
-		goto cmd_tab_data_end;
-
-	/* Sync to odd field */
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(ODD_FIELD));
-	tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
-		PLANB_SET(DMA_ABORT));
-
-	/* odd field data: */
-	jump_addr = c1 + TAB_FACTOR * nlines / 2;
-	jump = virt_to_bus(jump_addr);
-#ifdef PLANB_GSCANLINE
-	for (i = 1; i < nlines; i += stepsize) {
-		tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-					virt_to_bus(pb->rawbuf[pagei
-					+ i * scanline / PAGE_SIZE]), jump);
-	}
-#else
-	i = 1;
-	leftover1 = 0;
-	pagei = pb->gbuf_idx[fr];
-	if(nlines <= 1)
-	    goto skip;
-	do {
-	    int j;
-
-	    base = virt_to_bus(pb->rawbuf[pagei]);
-	    nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
-	    if(leftover1 >= count) {
-		tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
-						base + leftover1 - count, jump);
-		i += stepsize;
-	    }
-	    for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
-		tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
-			base + count * (j * stepsize + 1) + leftover1, jump);
-	    if(i < nlines) {
-		int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
-		if(lov0 == 0)
-		    leftover1 = 0;
-		else {
-		    if(lov0 > count) {
-			pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
-				+ count * (nlpp * stepsize + 1) + leftover1;
-			pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
-			pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
-									- lov0;
-			tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
-				virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
-							+ pb->lnum[fr]]), jump);
-			if(++pb->lnum[fr] > MAX_LNUM)
-				pb->lnum[fr]--;
-			i += stepsize;
-		    }
-		    leftover1 = count * stepsize - lov0;
-		}
-	    }
-	    pagei++;
-	} while(i < nlines);
-skip:
-	tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
-	c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
-cmd_tab_data_end:
-	tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
-			(fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
-	/* stop it */
-	tab_cmd_dbdma(c1, DBDMA_STOP, 0);
-
-	eieio();
-	return c1;
-}
-
-static irqreturn_t planb_irq(int irq, void *dev_id)
-{
-	unsigned int stat, astat;
-	struct planb *pb = (struct planb *)dev_id;
-
-	IDEBUG("PlanB: planb_irq()\n");
-
-	/* get/clear interrupt status bits */
-	eieio();
-	stat = in_le32(&pb->planb_base->intr_stat);
-	astat = stat & pb->intr_mask;
-	out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
-					& ~astat & stat & ~PLANB_GEN_IRQ);
-	IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
-
-	if(astat & PLANB_FRM_IRQ) {
-		unsigned int fr = stat >> 9;
-#ifndef PLANB_GSCANLINE
-		int i;
-#endif
-		IDEBUG("PlanB: PLANB_FRM_IRQ\n");
-
-		pb->gcount++;
-
-		IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
-				pb->grabbing, fr, pb->gcount);
-#ifndef PLANB_GSCANLINE
-		IDEBUG("PlanB: %d * %d bytes are being copied over\n",
-				pb->lnum[fr], pb->lsize[fr]);
-		for(i = 0; i < pb->lnum[fr]; i++) {
-			int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
-
-			memcpy(pb->l_to_addr[fr][i],
-				pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
-				first);
-			memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
-				pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
-						pb->l_to_next_size[fr][i]);
-		}
-#endif
-		pb->frame_stat[fr] = GBUFFER_DONE;
-		pb->grabbing--;
-		wake_up_interruptible(&pb->capq);
-		return IRQ_HANDLED;
-	}
-	/* incorrect interrupts? */
-	pb->intr_mask = PLANB_CLR_IRQ;
-	out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
-	printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
-							" unconditionally\n");
-	return IRQ_HANDLED;
-}
-
-/*******************************
- * Device Operations functions *
- *******************************/
-
-static int planb_open(struct video_device *dev, int mode)
-{
-	struct planb *pb = (struct planb *)dev;
-
-	if (pb->user == 0) {
-		int err;
-		if((err = planb_prepare_open(pb)) != 0)
-			return err;
-	}
-	pb->user++;
-
-	DEBUG("PlanB: device opened\n");
-	return 0;
-}
-
-static void planb_close(struct video_device *dev)
-{
-	struct planb *pb = (struct planb *)dev;
-
-	if(pb->user < 1) /* ??? */
-		return;
-	planb_lock(pb);
-	if (pb->user == 1) {
-		if (pb->overlay) {
-			planb_dbdma_stop(&pb->planb_base->ch2);
-			planb_dbdma_stop(&pb->planb_base->ch1);
-			pb->overlay = 0;
-		}
-		planb_prepare_close(pb);
-	}
-	pb->user--;
-	planb_unlock(pb);
-
-	DEBUG("PlanB: device closed\n");
-}
-
-static long planb_read(struct video_device *v, char *buf, unsigned long count,
-				int nonblock)
-{
-	DEBUG("planb: read request\n");
-	return -EINVAL;
-}
-
-static long planb_write(struct video_device *v, const char *buf,
-				unsigned long count, int nonblock)
-{
-	DEBUG("planb: write request\n");
-	return -EINVAL;
-}
-
-static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
-	struct planb *pb=(struct planb *)dev;
-
-	switch (cmd)
-	{
-		case VIDIOCGCAP:
-		{
-			struct video_capability b;
-
-			DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
-
-			strcpy (b.name, pb->video_dev.name);
-			b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
-				 VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
-				 VID_TYPE_CAPTURE;
-			b.channels = 2;	/* composite & svhs */
-			b.audios = 0;
-			b.maxwidth = PLANB_MAXPIXELS;
-			b.maxheight = PLANB_MAXLINES;
-			b.minwidth = 32; /* wild guess */
-			b.minheight = 32;
-			if (copy_to_user(arg,&b,sizeof(b)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSFBUF:
-		{
-			struct video_buffer v;
-			unsigned short bpp;
-			unsigned int fmt;
-
-			DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
-
-			if (!capable(CAP_SYS_ADMIN)
-			|| !capable(CAP_SYS_RAWIO))
-				return -EPERM;
-			if (copy_from_user(&v, arg,sizeof(v)))
-				return -EFAULT;
-			planb_lock(pb);
-			switch(v.depth) {
-			case 8:
-				bpp = 1;
-				fmt = PLANB_GRAY;
-				break;
-			case 15:
-			case 16:
-				bpp = 2;
-				fmt = PLANB_COLOUR15;
-				break;
-			case 24:
-			case 32:
-				bpp = 4;
-				fmt = PLANB_COLOUR32;
-				break;
-			default:
-				planb_unlock(pb);
-				return -EINVAL;
-			}
-			if (bpp * v.width > v.bytesperline) {
-				planb_unlock(pb);
-				return -EINVAL;
-			}
-			pb->win.bpp = bpp;
-			pb->win.color_fmt = fmt;
-			pb->frame_buffer_phys = (unsigned long) v.base;
-			pb->win.sheight = v.height;
-			pb->win.swidth = v.width;
-			pb->picture.depth = pb->win.depth = v.depth;
-			pb->win.bpl = pb->win.bpp * pb->win.swidth;
-			pb->win.pad = v.bytesperline - pb->win.bpl;
-
-			DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
-				" bpl %d (+ %d)\n", v.base, v.width,v.height,
-				pb->win.bpp, pb->win.bpl, pb->win.pad);
-
-			pb->cmd_buff_inited = 0;
-			if(pb->overlay) {
-				suspend_overlay(pb);
-				fill_cmd_buff(pb);
-				resume_overlay(pb);
-			}
-			planb_unlock(pb);
-			return 0;
-		}
-		case VIDIOCGFBUF:
-		{
-			struct video_buffer v;
-
-			DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
-
-			v.base = (void *)pb->frame_buffer_phys;
-			v.height = pb->win.sheight;
-			v.width = pb->win.swidth;
-			v.depth = pb->win.depth;
-			v.bytesperline = pb->win.bpl + pb->win.pad;
-			if (copy_to_user(arg, &v, sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCCAPTURE:
-		{
-			int i;
-
-			if(copy_from_user(&i, arg, sizeof(i)))
-				return -EFAULT;
-			if(i==0) {
-				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
-
-				if (!(pb->overlay))
-					return 0;
-				planb_lock(pb);
-				pb->overlay = 0;
-				overlay_stop(pb);
-				planb_unlock(pb);
-			} else {
-				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
-
-				if (pb->frame_buffer_phys == 0 ||
-					  pb->win.width == 0 ||
-					  pb->win.height == 0)
-					return -EINVAL;
-				if (pb->overlay)
-					return 0;
-				planb_lock(pb);
-				pb->overlay = 1;
-				if(!(pb->cmd_buff_inited))
-					fill_cmd_buff(pb);
-				overlay_start(pb);
-				planb_unlock(pb);
-			}
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			struct video_channel v;
-
-			DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
-
-			if(copy_from_user(&v, arg,sizeof(v)))
-				return -EFAULT;
-			v.flags = 0;
-			v.tuners = 0;
-			v.type = VIDEO_TYPE_CAMERA;
-			v.norm = pb->win.norm;
-			switch(v.channel)
-			{
-			case 0:
-				strcpy(v.name,"Composite");
-				break;
-			case 1:
-				strcpy(v.name,"SVHS");
-				break;
-			default:
-				return -EINVAL;
-				break;
-			}
-			if(copy_to_user(arg,&v,sizeof(v)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			struct video_channel v;
-
-			DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
-
-			if(copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-
-			if (v.norm != pb->win.norm) {
-				int i, maxlines;
-
-				switch (v.norm)
-				{
-				case VIDEO_MODE_PAL:
-				case VIDEO_MODE_SECAM:
-					maxlines = PLANB_MAXLINES;
-					break;
-				case VIDEO_MODE_NTSC:
-					maxlines = PLANB_NTSC_MAXLINES;
-					break;
-				default:
-					return -EINVAL;
-					break;
-				}
-				planb_lock(pb);
-				/* empty the grabbing queue */
-				wait_event(pb->capq, !pb->grabbing);
-				pb->maxlines = maxlines;
-				pb->win.norm = v.norm;
-				/* Stop overlay if running */
-				suspend_overlay(pb);
-				for(i = 0; i < MAX_GBUFFERS; i++)
-					pb->gnorm_switch[i] = 1;
-				/* I know it's an overkill, but.... */
-				fill_cmd_buff(pb);
-				/* ok, now init it accordingly */
-				saa_init_regs (pb);
-				/* restart overlay if it was running */
-				resume_overlay(pb);
-				planb_unlock(pb);
-			}
-
-			switch(v.channel)
-			{
-			case 0:	/* Composite	*/
-				saa_set (SAA7196_IOCC,
-					((saa_regs[pb->win.norm][SAA7196_IOCC] &
-					  ~7) | 3), pb);
-				break;
-			case 1:	/* SVHS		*/
-				saa_set (SAA7196_IOCC,
-					((saa_regs[pb->win.norm][SAA7196_IOCC] &
-					  ~7) | 4), pb);
-				break;
-			default:
-				return -EINVAL;
-				break;
-			}
-
-			return 0;
-		}
-		case VIDIOCGPICT:
-		{
-			struct video_picture vp = pb->picture;
-
-			DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
-
-			switch(pb->win.color_fmt) {
-			case PLANB_GRAY:
-				vp.palette = VIDEO_PALETTE_GREY;
-			case PLANB_COLOUR15:
-				vp.palette = VIDEO_PALETTE_RGB555;
-				break;
-			case PLANB_COLOUR32:
-				vp.palette = VIDEO_PALETTE_RGB32;
-				break;
-			default:
-				vp.palette = 0;
-				break;
-			}
-
-			if(copy_to_user(arg,&vp,sizeof(vp)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture vp;
-
-			DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
-
-			if(copy_from_user(&vp,arg,sizeof(vp)))
-				return -EFAULT;
-			pb->picture = vp;
-			/* Should we do sanity checks here? */
-			saa_set (SAA7196_BRIG, (unsigned char)
-			    ((pb->picture.brightness) >> 8), pb);
-			saa_set (SAA7196_HUEC, (unsigned char)
-			    ((pb->picture.hue) >> 8) ^ 0x80, pb);
-			saa_set (SAA7196_CSAT, (unsigned char)
-			    ((pb->picture.colour) >> 9), pb);
-			saa_set (SAA7196_CONT, (unsigned char)
-			    ((pb->picture.contrast) >> 9), pb);
-
-			return 0;
-		}
-		case VIDIOCSWIN:
-		{
-			struct video_window	vw;
-			struct video_clip	clip;
-			int 			i;
-
-			DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
-
-			if(copy_from_user(&vw,arg,sizeof(vw)))
-				return -EFAULT;
-
-			planb_lock(pb);
-			/* Stop overlay if running */
-			suspend_overlay(pb);
-			pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
-			if (pb->win.x != vw.x ||
-			    pb->win.y != vw.y ||
-			    pb->win.width != vw.width ||
-			    pb->win.height != vw.height ||
-			    !pb->cmd_buff_inited) {
-				pb->win.x = vw.x;
-				pb->win.y = vw.y;
-				pb->win.width = vw.width;
-				pb->win.height = vw.height;
-				fill_cmd_buff(pb);
-			}
-			/* Reset clip mask */
-			memset ((void *) pb->mask, 0xff, (pb->maxlines
-					* ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
-			/* Add any clip rects */
-			for (i = 0; i < vw.clipcount; i++) {
-				if (copy_from_user(&clip, vw.clips + i,
-						sizeof(struct video_clip)))
-					return -EFAULT;
-				add_clip(pb, &clip);
-			}
-			/* restart overlay if it was running */
-			resume_overlay(pb);
-			planb_unlock(pb);
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window vw;
-
-			DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
-
-			vw.x=pb->win.x;
-			vw.y=pb->win.y;
-			vw.width=pb->win.width;
-			vw.height=pb->win.height;
-			vw.chromakey=0;
-			vw.flags=0;
-			if(pb->win.interlace)
-				vw.flags|=VIDEO_WINDOW_INTERLACE;
-			if(copy_to_user(arg,&vw,sizeof(vw)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSYNC: {
-			int i;
-
-			IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
-
-			if(copy_from_user((void *)&i,arg,sizeof(int)))
-				return -EFAULT;
-
-			IDEBUG("PlanB: sync to frame %d\n", i);
-
-			if(i > (MAX_GBUFFERS - 1) || i < 0)
-				return -EINVAL;
-chk_grab:
-			switch (pb->frame_stat[i]) {
-			case GBUFFER_UNUSED:
-				return -EINVAL;
-			case GBUFFER_GRABBING:
-				IDEBUG("PlanB: waiting for grab"
-							" done (%d)\n", i);
-				interruptible_sleep_on(&pb->capq);
-				if(signal_pending(current))
-					return -EINTR;
-				goto chk_grab;
-			case GBUFFER_DONE:
-				pb->frame_stat[i] = GBUFFER_UNUSED;
-				break;
-			}
-			return 0;
-		}
-
-		case VIDIOCMCAPTURE:
-		{
-			struct video_mmap vm;
-			volatile unsigned int status;
-
-			IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
-
-			if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
-				return -EFAULT;
-			status = pb->frame_stat[vm.frame];
-			if (status != GBUFFER_UNUSED)
-				return -EBUSY;
-
-			return vgrab(pb, &vm);
-		}
-
-		case VIDIOCGMBUF:
-		{
-			int i;
-			struct video_mbuf vm;
-
-			DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
-
-			memset(&vm, 0 , sizeof(vm));
-			vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
-			vm.frames = MAX_GBUFFERS;
-			for(i = 0; i<MAX_GBUFFERS; i++)
-				vm.offsets[i] = PLANB_MAX_FBUF * i;
-			if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
-				return -EFAULT;
-			return 0;
-		}
-
-		case PLANBIOCGSAAREGS:
-		{
-			struct planb_saa_regs preg;
-
-			DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
-
-			if(copy_from_user(&preg, arg, sizeof(preg)))
-				return -EFAULT;
-			if(preg.addr >= SAA7196_NUMREGS)
-				return -EINVAL;
-			preg.val = saa_regs[pb->win.norm][preg.addr];
-			if(copy_to_user((void *)arg, (void *)&preg,
-								sizeof(preg)))
-				return -EFAULT;
-			return 0;
-		}
-
-		case PLANBIOCSSAAREGS:
-		{
-			struct planb_saa_regs preg;
-
-			DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
-
-			if(copy_from_user(&preg, arg, sizeof(preg)))
-				return -EFAULT;
-			if(preg.addr >= SAA7196_NUMREGS)
-				return -EINVAL;
-			saa_set (preg.addr, preg.val, pb);
-			return 0;
-		}
-
-		case PLANBIOCGSTAT:
-		{
-			struct planb_stat_regs pstat;
-
-			DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
-
-			pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
-			pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
-			pstat.saa_stat0 = saa_status(0, pb);
-			pstat.saa_stat1 = saa_status(1, pb);
-
-			if(copy_to_user((void *)arg, (void *)&pstat,
-							sizeof(pstat)))
-				return -EFAULT;
-			return 0;
-		}
-
-		case PLANBIOCSMODE: {
-			int v;
-
-			DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
-
-			if(copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-
-			switch(v)
-			{
-			case PLANB_TV_MODE:
-				saa_set (SAA7196_STDC,
-					(saa_regs[pb->win.norm][SAA7196_STDC] &
-					  0x7f), pb);
-				break;
-			case PLANB_VTR_MODE:
-				saa_set (SAA7196_STDC,
-					(saa_regs[pb->win.norm][SAA7196_STDC] |
-					  0x80), pb);
-				break;
-			default:
-				return -EINVAL;
-				break;
-			}
-			pb->win.mode = v;
-			return 0;
-		}
-		case PLANBIOCGMODE: {
-			int v=pb->win.mode;
-
-			DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
-
-			if(copy_to_user(arg,&v,sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-#ifdef PLANB_GSCANLINE
-		case PLANBG_GRAB_BPL: {
-			int v=pb->gbytes_per_line;
-
-			DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
-
-			if(copy_to_user(arg,&v,sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-#endif /* PLANB_GSCANLINE */
-		case PLANB_INTR_DEBUG: {
-			int i;
-
-			DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
-
-			if(copy_from_user(&i, arg, sizeof(i)))
-				return -EFAULT;
-
-			/* avoid hang ups all together */
-			for (i = 0; i < MAX_GBUFFERS; i++) {
-				if(pb->frame_stat[i] == GBUFFER_GRABBING) {
-					pb->frame_stat[i] = GBUFFER_DONE;
-				}
-			}
-			if(pb->grabbing)
-				pb->grabbing--;
-			wake_up_interruptible(&pb->capq);
-			return 0;
-		}
-		case PLANB_INV_REGS: {
-			int i;
-			struct planb_any_regs any;
-
-			DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
-
-			if(copy_from_user(&any, arg, sizeof(any)))
-				return -EFAULT;
-			if(any.offset < 0 || any.offset + any.bytes > 0x400)
-				return -EINVAL;
-			if(any.bytes > 128)
-				return -EINVAL;
-			for (i = 0; i < any.bytes; i++) {
-				any.data[i] =
-					in_8((unsigned char *)pb->planb_base
-							+ any.offset + i);
-			}
-			if(copy_to_user(arg,&any,sizeof(any)))
-				return -EFAULT;
-			return 0;
-		}
-		default:
-		{
-			DEBUG("PlanB: Unimplemented IOCTL\n");
-			return -ENOIOCTLCMD;
-		}
-	/* Some IOCTLs are currently unsupported on PlanB */
-		case VIDIOCGTUNER: {
-		DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
-			goto unimplemented; }
-		case VIDIOCSTUNER: {
-		DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
-			goto unimplemented; }
-		case VIDIOCSFREQ: {
-		DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
-			goto unimplemented; }
-		case VIDIOCGFREQ: {
-		DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
-			goto unimplemented; }
-		case VIDIOCKEY: {
-		DEBUG("PlanB: IOCTL VIDIOCKEY\n");
-			goto unimplemented; }
-		case VIDIOCSAUDIO: {
-		DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
-			goto unimplemented; }
-		case VIDIOCGAUDIO: {
-		DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
-			goto unimplemented; }
-unimplemented:
-		DEBUG("       Unimplemented\n");
-			return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size)
-{
-	int i;
-	struct planb *pb = (struct planb *)dev;
-	unsigned long start = (unsigned long)adr;
-
-	if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
-		return -EINVAL;
-	if (!pb->rawbuf) {
-		int err;
-		if((err=grabbuf_alloc(pb)))
-			return err;
-	}
-	for (i = 0; i < pb->rawbuf_size; i++) {
-		unsigned long pfn;
-
-		pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT;
-		if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
-			return -EAGAIN;
-		start += PAGE_SIZE;
-		if (size <= PAGE_SIZE)
-			break;
-		size -= PAGE_SIZE;
-	}
-	return 0;
-}
-
-static struct video_device planb_template=
-{
-	.owner		= THIS_MODULE,
-	.name		= PLANB_DEVICE_NAME,
-	.type		= VID_TYPE_OVERLAY,
-	.open		= planb_open,
-	.close		= planb_close,
-	.read		= planb_read,
-	.write		= planb_write,
-	.ioctl		= planb_ioctl,
-	.mmap		= planb_mmap,	/* mmap? */
-};
-
-static int init_planb(struct planb *pb)
-{
-	unsigned char saa_rev;
-	int i, result;
-
-	memset ((void *) &pb->win, 0, sizeof (struct planb_window));
-	/* Simple sanity check */
-	if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
-		printk(KERN_ERR "PlanB: Option(s) invalid\n");
-		return -2;
-	}
-	pb->win.norm = def_norm;
-	pb->win.mode = PLANB_TV_MODE;	/* TV mode */
-	pb->win.interlace=1;
-	pb->win.x=0;
-	pb->win.y=0;
-	pb->win.width=768; /* 640 */
-	pb->win.height=576; /* 480 */
-	pb->maxlines=576;
-#if 0
-	btv->win.cropwidth=768; /* 640 */
-	btv->win.cropheight=576; /* 480 */
-	btv->win.cropx=0;
-	btv->win.cropy=0;
-#endif
-	pb->win.pad=0;
-	pb->win.bpp=4;
-	pb->win.depth=32;
-	pb->win.color_fmt=PLANB_COLOUR32;
-	pb->win.bpl=1024*pb->win.bpp;
-	pb->win.swidth=1024;
-	pb->win.sheight=768;
-#ifdef PLANB_GSCANLINE
-	if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
-				|| (pb->gbytes_per_line <= 0))
-		return -3;
-	else {
-		/* page align pb->gbytes_per_line for DMA purpose */
-		for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
-			i>>=1;
-		pb->gbytes_per_line = i;
-	}
-#endif
-	pb->tab_size = PLANB_MAXLINES + 40;
-	pb->suspend = 0;
-	mutex_init(&pb->lock);
-	pb->ch1_cmd = 0;
-	pb->ch2_cmd = 0;
-	pb->mask = 0;
-	pb->priv_space = 0;
-	pb->offset = 0;
-	pb->user = 0;
-	pb->overlay = 0;
-	init_waitqueue_head(&pb->suspendq);
-	pb->cmd_buff_inited = 0;
-	pb->frame_buffer_phys = 0;
-
-	/* Reset DMA controllers */
-	planb_dbdma_stop(&pb->planb_base->ch2);
-	planb_dbdma_stop(&pb->planb_base->ch1);
-
-	saa_rev =  (saa_status(0, pb) & 0xf0) >> 4;
-	printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev);
-	/* Initialize the SAA registers in memory and on chip */
-	saa_init_regs (pb);
-
-	/* clear interrupt mask */
-	pb->intr_mask = PLANB_CLR_IRQ;
-
-	result = request_irq(pb->irq, planb_irq, 0, "PlanB", pb);
-	if (result < 0) {
-		if (result==-EINVAL)
-			printk(KERN_ERR "PlanB: Bad irq number (%d) "
-						"or handler\n", (int)pb->irq);
-		else if (result==-EBUSY)
-			printk(KERN_ERR "PlanB: I don't know why, "
-					"but IRQ %d is busy\n", (int)pb->irq);
-		return result;
-	}
-	disable_irq(pb->irq);
-
-	/* Now add the template and register the device unit. */
-	memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
-
-	pb->picture.brightness=0x90<<8;
-	pb->picture.contrast = 0x70 << 8;
-	pb->picture.colour = 0x70<<8;
-	pb->picture.hue = 0x8000;
-	pb->picture.whiteness = 0;
-	pb->picture.depth = pb->win.depth;
-
-	pb->frame_stat=NULL;
-	init_waitqueue_head(&pb->capq);
-	for(i=0; i<MAX_GBUFFERS; i++) {
-		pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
-		pb->gwidth[i]=0;
-		pb->gheight[i]=0;
-		pb->gfmt[i]=0;
-		pb->cap_cmd[i]=NULL;
-#ifndef PLANB_GSCANLINE
-		pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
-						/ PAGE_SIZE + 1) + MAX_LNUM * i;
-		pb->lsize[i] = 0;
-		pb->lnum[i] = 0;
-#endif
-	}
-	pb->rawbuf=NULL;
-	pb->grabbing=0;
-
-	/* enable interrupts */
-	out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
-	pb->intr_mask = PLANB_FRM_IRQ;
-	enable_irq(pb->irq);
-
-	if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
-		return -1;
-
-	return 0;
-}
-
-/*
- *	Scan for a PlanB controller, request the irq and map the io memory
- */
-
-static int find_planb(void)
-{
-	struct planb		*pb;
-	struct device_node	*planb_devices;
-	unsigned char		dev_fn, confreg, bus;
-	unsigned int		old_base, new_base;
-	unsigned int		irq;
-	struct pci_dev 		*pdev;
-	int rc;
-
-	if (!machine_is(powermac))
-		return 0;
-
-	planb_devices = of_find_node_by_name(NULL, "planb");
-	if (planb_devices == 0) {
-		planb_num=0;
-		printk(KERN_WARNING "PlanB: no device found!\n");
-		return planb_num;
-	}
-
-	if (planb_devices->next != NULL)
-		printk(KERN_ERR "Warning: only using first PlanB device!\n");
-	pb = &planbs[0];
-	planb_num = 1;
-
-	if (planb_devices->n_addrs != 1) {
-		printk (KERN_WARNING "PlanB: expecting 1 address for planb "
-			"(got %d)", planb_devices->n_addrs);
-		of_node_put(planb_devices);
-		return 0;
-	}
-
-	if (planb_devices->n_intrs == 0) {
-		printk(KERN_WARNING "PlanB: no intrs for device %s\n",
-		       planb_devices->full_name);
-		of_node_put(planb_devices);
-		return 0;
-	} else {
-		irq = planb_devices->intrs[0].line;
-	}
-
-	/* Initialize PlanB's PCI registers */
-
-	/* There is a bug with the way OF assigns addresses
-	   to the devices behind the chaos bridge.
-	   control needs only 0x1000 of space, but decodes only
-	   the upper 16 bits. It therefore occupies a full 64K.
-	   OF assigns the planb controller memory within this space;
-	   so we need to change that here in order to access planb. */
-
-	/* We remap to 0xf1000000 in hope that nobody uses it ! */
-
-	bus = (planb_devices->addrs[0].space >> 16) & 0xff;
-	dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
-	confreg = planb_devices->addrs[0].space & 0xff;
-	old_base = planb_devices->addrs[0].address;
-	new_base = 0xf1000000;
-	of_node_put(planb_devices);
-
-	DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
-		"membase 0x%x (base reg. 0x%x)\n",
-		bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
-
-	pdev = pci_get_bus_and_slot(bus, dev_fn);
-	if (!pdev) {
-		printk(KERN_ERR "planb: cannot find slot\n");
-		goto err_out;
-	}
-
-	/* Enable response in memory space, bus mastering,
-	   use memory write and invalidate */
-	rc = pci_enable_device(pdev);
-	if (rc) {
-		printk(KERN_ERR "planb: cannot enable PCI device %s\n",
-		       pci_name(pdev));
-		goto err_out;
-	}
-	rc = pci_set_mwi(pdev);
-	if (rc) {
-		printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n",
-		       pci_name(pdev));
-		goto err_out_disable;
-	}
-	pci_set_master(pdev);
-
-	/* Set the new base address */
-	pci_write_config_dword (pdev, confreg, new_base);
-
-	planb_regs = (volatile struct planb_registers *)
-						ioremap (new_base, 0x400);
-	pb->planb_base = planb_regs;
-	pb->planb_base_phys = (struct planb_registers *)new_base;
-	pb->irq	= irq;
-	pb->dev = pdev;
-
-	return planb_num;
-
-err_out_disable:
-	pci_disable_device(pdev);
-err_out:
-	/* FIXME handle error */   /* comment moved from pci_find_slot, above */
-	pci_dev_put(pdev);
-	return 0;
-}
-
-static void release_planb(void)
-{
-	int i;
-	struct planb *pb;
-
-	for (i=0;i<planb_num; i++)
-	{
-		pb=&planbs[i];
-
-		/* stop and flash DMAs unconditionally */
-		planb_dbdma_stop(&pb->planb_base->ch2);
-		planb_dbdma_stop(&pb->planb_base->ch1);
-
-		/* clear and free interrupts */
-		pb->intr_mask = PLANB_CLR_IRQ;
-		out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
-		free_irq(pb->irq, pb);
-
-		/* make sure all allocated memory are freed */
-		planb_prepare_close(pb);
-
-		printk(KERN_INFO "PlanB: unregistering with v4l\n");
-		video_unregister_device(&pb->video_dev);
-
-		pci_dev_put(pb->dev);
-
-		/* note that iounmap() does nothing on the PPC right now */
-		iounmap ((void *)pb->planb_base);
-	}
-}
-
-static int __init init_planbs(void)
-{
-	int i;
-
-	if (find_planb()<=0)
-		return -EIO;
-
-	for (i=0; i<planb_num; i++) {
-		if (init_planb(&planbs[i])<0) {
-			printk(KERN_ERR "PlanB: error registering device %d"
-							" with v4l\n", i);
-			release_planb();
-			return -EIO;
-		}
-		printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
-	}
-	return 0;
-}
-
-static void __exit exit_planbs(void)
-{
-	release_planb();
-}
-
-module_init(init_planbs);
-module_exit(exit_planbs);
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h
index e21b573..e69de29 100644
--- a/drivers/media/video/planb.h
+++ b/drivers/media/video/planb.h
@@ -1,232 +0,0 @@
-/*
-    planb - PlanB frame grabber driver
-
-    PlanB is used in the 7x00/8x00 series of PowerMacintosh
-    Computers as video input DMA controller.
-
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
-    Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
-    Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
-
-    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.
-*/
-
-/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
-
-#ifndef _PLANB_H_
-#define _PLANB_H_
-
-#ifdef __KERNEL__
-#include <asm/dbdma.h>
-#include "saa7196.h"
-#endif /* __KERNEL__ */
-
-#define PLANB_DEVICE_NAME	"Apple PlanB Video-In"
-#define PLANB_REV		"1.0"
-
-#ifdef __KERNEL__
-//#define PLANB_GSCANLINE	/* use this if apps have the notion of */
-				/* grab buffer scanline */
-/* This should be safe for both PAL and NTSC */
-#define PLANB_MAXPIXELS 768
-#define PLANB_MAXLINES 576
-#define PLANB_NTSC_MAXLINES 480
-
-/* Uncomment your preferred norm ;-) */
-#define PLANB_DEF_NORM VIDEO_MODE_PAL
-//#define PLANB_DEF_NORM VIDEO_MODE_NTSC
-//#define PLANB_DEF_NORM VIDEO_MODE_SECAM
-
-/* fields settings */
-#define PLANB_GRAY	0x1	/*  8-bit mono? */
-#define PLANB_COLOUR15	0x2	/* 16-bit mode */
-#define PLANB_COLOUR32	0x4	/* 32-bit mode */
-#define PLANB_CLIPMASK	0x8	/* hardware clipmasking */
-
-/* misc. flags for PlanB DMA operation */
-#define	CH_SYNC		0x1	/* synchronize channels (set by ch1;
-				   cleared by ch2) */
-#define FIELD_SYNC	0x2     /* used for the start of each field
-				   (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */
-#define EVEN_FIELD	0x0	/* even field is detected if unset */
-#define DMA_ABORT	0x2	/* error or just out of sync if set */
-#define ODD_FIELD	0x4	/* odd field is detected if set */
-
-/* for capture operations */
-#define MAX_GBUFFERS	2
-/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
-#ifdef PLANB_GSCANLINE
-#define PLANB_MAX_FBUF	0x240000	/* 576 * 1024 * 4 */
-#define TAB_FACTOR	(1)
-#else
-#define PLANB_MAX_FBUF	0x1b0000	/* 576 * 768 * 4 */
-#define TAB_FACTOR	(2)
-#endif
-#endif /* __KERNEL__ */
-
-struct planb_saa_regs {
-	unsigned char addr;
-	unsigned char val;
-};
-
-struct planb_stat_regs {
-	unsigned int ch1_stat;
-	unsigned int ch2_stat;
-	unsigned char saa_stat0;
-	unsigned char saa_stat1;
-};
-
-struct planb_any_regs {
-	unsigned int offset;
-	unsigned int bytes;
-	unsigned char data[128];
-};
-
-/* planb private ioctls */
-#define PLANBIOCGSAAREGS	_IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs)	/* Read a saa7196 reg value */
-#define PLANBIOCSSAAREGS	_IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs)	/* Set a saa7196 reg value */
-#define PLANBIOCGSTAT		_IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs)	/* Read planb status */
-#define PLANB_TV_MODE		1
-#define PLANB_VTR_MODE		2
-#define PLANBIOCGMODE		_IOR('v', BASE_VIDIOCPRIVATE + 3, int)	/* Get TV/VTR mode */
-#define PLANBIOCSMODE		_IOW('v', BASE_VIDIOCPRIVATE + 4, int)	/* Set TV/VTR mode */
-
-#ifdef PLANB_GSCANLINE
-#define PLANBG_GRAB_BPL		_IOR('v', BASE_VIDIOCPRIVATE + 5, int)	/* # of bytes per scanline in grab buffer */
-#endif
-
-/* call wake_up_interruptible() with appropriate actions */
-#define PLANB_INTR_DEBUG	_IOW('v', BASE_VIDIOCPRIVATE + 20, int)
-/* investigate which reg does what */
-#define PLANB_INV_REGS		_IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
-
-#ifdef __KERNEL__
-
-/* Potentially useful macros */
-#define PLANB_SET(x)	((x) << 16 | (x))
-#define PLANB_CLR(x)	((x) << 16)
-
-/* This represents the physical register layout */
-struct planb_registers {
-	volatile struct dbdma_regs	ch1;		/* 0x00: video in */
-	volatile unsigned int		even;		/* 0x40: even field setting */
-	volatile unsigned int		odd;		/* 0x44; odd field setting */
-	unsigned int			pad1[14];	/* empty? */
-	volatile struct dbdma_regs	ch2;		/* 0x80: clipmask out */
-	unsigned int			pad2[16];	/* 0xc0: empty? */
-	volatile unsigned int		reg3;		/* 0x100: ???? */
-	volatile unsigned int		intr_stat;	/* 0x104: irq status */
-#define PLANB_CLR_IRQ		0x00		/* clear Plan B interrupt */
-#define PLANB_GEN_IRQ		0x01		/* assert Plan B interrupt */
-#define PLANB_FRM_IRQ		0x0100		/* end of frame */
-	unsigned int			pad3[1];	/* empty? */
-	volatile unsigned int		reg5;		/* 0x10c: ??? */
-	unsigned int			pad4[60];	/* empty? */
-	volatile unsigned char		saa_addr;	/* 0x200: SAA subadr */
-	char				pad5[3];
-	volatile unsigned char		saa_regval;	/* SAA7196 write reg. val */
-	char				pad6[3];
-	volatile unsigned char		saa_status;	/* SAA7196 status byte */
-	/* There is more unused stuff here */
-};
-
-struct planb_window {
-	int	x, y;
-	ushort	width, height;
-	ushort	bpp, bpl, depth, pad;
-	ushort	swidth, sheight;
-	int	norm;
-	int	interlace;
-	u32	color_fmt;
-	int	chromakey;
-	int	mode;		/* used to switch between TV/VTR modes */
-};
-
-struct planb_suspend {
-	int overlay;
-	int frame;
-	struct dbdma_cmd cmd;
-};
-
-struct planb {
-	struct	video_device video_dev;
-	struct	video_picture picture;		/* Current picture params */
-	struct	video_audio audio_dev;		/* Current audio params */
-
-	volatile struct planb_registers *planb_base;	/* virt base of planb */
-	struct planb_registers *planb_base_phys;	/* phys base of planb */
-	void	*priv_space;			/* Org. alloc. mem for kfree */
-	int	user;
-	unsigned int tab_size;
-	int     maxlines;
-	struct mutex lock;
-	unsigned int	irq;			/* interrupt number */
-	volatile unsigned int intr_mask;
-	struct pci_dev *dev;			/* Our PCI device */
-
-	int	overlay;			/* overlay running? */
-	struct	planb_window win;
-	unsigned long frame_buffer_phys;	/* We need phys for DMA */
-	int	offset;				/* offset of pixel 1 */
-	volatile struct dbdma_cmd *ch1_cmd;	/* Video In DMA cmd buffer */
-	volatile struct dbdma_cmd *ch2_cmd;	/* Clip Out DMA cmd buffer */
-	volatile struct dbdma_cmd *overlay_last1;
-	volatile struct dbdma_cmd *overlay_last2;
-	unsigned long ch1_cmd_phys;
-	volatile unsigned char *mask;		/* Clipmask buffer */
-	int suspend;
-	wait_queue_head_t suspendq;
-	struct planb_suspend suspended;
-	int	cmd_buff_inited;		/* cmd buffer inited? */
-
-	int grabbing;
-	unsigned int gcount;
-	wait_queue_head_t capq;
-	int last_fr;
-	int prev_last_fr;
-	unsigned char **rawbuf;
-	int rawbuf_size;
-	int gbuf_idx[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
-	volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
-	int need_pre_capture[MAX_GBUFFERS];
-#define PLANB_DUMMY 40	/* # of command buf's allocated for pre-capture seq. */
-	int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
-	unsigned int gfmt[MAX_GBUFFERS];
-	int gnorm_switch[MAX_GBUFFERS];
-	volatile unsigned int *frame_stat;
-#define GBUFFER_UNUSED       0x00U
-#define GBUFFER_GRABBING     0x01U
-#define GBUFFER_DONE         0x02U
-#ifdef PLANB_GSCANLINE
-	int gbytes_per_line;
-#else
-#define MAX_LNUM 431	/* change this if PLANB_MAXLINES or */
-			/* PLANB_MAXPIXELS changes */
-	int l_fr_addr_idx[MAX_GBUFFERS];
-	unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
-	int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
-	int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
-	int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
-#endif
-};
-
-#endif /* __KERNEL__ */
-
-#endif /* _PLANB_H_ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 51b1461..00425d7 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 
 #include <asm/uaccess.h>
@@ -894,9 +895,7 @@
 
 static struct video_device pms_template=
 {
-	.owner		= THIS_MODULE,
 	.name		= "Mediavision PMS",
-	.type		= VID_TYPE_CAPTURE,
 	.fops           = &pms_fops,
 };
 
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 4482b2c..19eb274 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -2,8 +2,6 @@
 	tristate "Hauppauge WinTV-PVR USB2 support"
 	depends on VIDEO_V4L2 && I2C
 	depends on VIDEO_MEDIA	# Avoids pvrusb = Y / DVB = M
-	depends on HOTPLUG	# due to FW_LOADER
-	select FW_LOADER
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
index 6180129..d657e53 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.h
@@ -16,8 +16,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
-#ifndef __PVRUSB2_BASE_H
-#define __PVRUSB2_BASE_H
+#ifndef __PVRUSB2_CONTEXT_H
+#define __PVRUSB2_CONTEXT_H
 
 #include <linux/mutex.h>
 #include <linux/usb.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 5d036e7..88e1751 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -97,13 +97,13 @@
 		.flag_has_cx25840 = !0,
 		.flag_has_wm8775 = !0,
 		.flag_has_hauppauge_rom = !0,
-		.flag_has_hauppauge_custom_ir = !0,
 		.flag_has_analogtuner = !0,
 		.flag_has_fmradio = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_24XXX,
 };
 
 
@@ -330,7 +330,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_73xxx = {
-		.description = "WinTV PVR USB2 Model Category 73xxx",
+		.description = "WinTV HVR-1900 Model Category 73xxx",
 		.shortname = "73xxx",
 		.client_modules.lst = pvr2_client_73xxx,
 		.client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx),
@@ -344,6 +344,7 @@
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
 		.dvb_props = &pvr2_73xxx_dvb_props,
 #endif
@@ -438,7 +439,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_750xx = {
-		.description = "WinTV PVR USB2 Model Category 750xx",
+		.description = "WinTV HVR-1950 Model Category 750xx",
 		.shortname = "750xx",
 		.client_modules.lst = pvr2_client_75xxx,
 		.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
@@ -453,13 +454,14 @@
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
 		.dvb_props = &pvr2_750xx_dvb_props,
 #endif
 };
 
 static const struct pvr2_device_desc pvr2_device_751xx = {
-		.description = "WinTV PVR USB2 Model Category 751xx",
+		.description = "WinTV HVR-1950 Model Category 751xx",
 		.shortname = "751xx",
 		.client_modules.lst = pvr2_client_75xxx,
 		.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
@@ -474,6 +476,7 @@
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
 		.dvb_props = &pvr2_751xx_dvb_props,
 #endif
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index e23ce1d..cb3a33e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -48,6 +48,10 @@
 #define PVR2_LED_SCHEME_NONE 0
 #define PVR2_LED_SCHEME_HAUPPAUGE 1
 
+#define PVR2_IR_SCHEME_NONE 0
+#define PVR2_IR_SCHEME_24XXX 1
+#define PVR2_IR_SCHEME_ZILOG 2
+
 /* This describes a particular hardware type (except for the USB device ID
    which must live in a separate structure due to environmental
    constraints).  See the top of pvrusb2-hdw.c for where this is
@@ -126,15 +130,19 @@
 	   ensure that it is found. */
 	unsigned int flag_has_wm8775:1;
 
-	/* Device has IR hardware that can be faked into looking like a
-	   normal Hauppauge i2c IR receiver.  This is currently very
-	   specific to the 24xxx device, where Hauppauge had replaced their
-	   'standard' I2C IR receiver with a bunch of FPGA logic controlled
-	   directly via the FX2.  Turning this on tells the pvrusb2 driver
-	   to virtualize the presence of the non-existant IR receiver chip and
-	   implement the virtual receiver in terms of appropriate FX2
-	   commands. */
-	unsigned int flag_has_hauppauge_custom_ir:1;
+	/* Indicate any specialized IR scheme that might need to be
+	   supported by this driver.  If not set, then it is assumed that
+	   IR can work without help from the driver (which is frequently
+	   the case).  This is otherwise set to one of
+	   PVR2_IR_SCHEME_xxxx.  For "xxxx", the value "24XXX" indicates a
+	   Hauppauge 24xxx class device which has an FPGA-hosted IR
+	   receiver that can only be reached via FX2 command codes.  In
+	   that case the pvrusb2 driver will emulate the behavior of the
+	   older 29xxx device's IR receiver (a "virtual" I2C chip) in terms
+	   of those command codes.  For the value "ZILOG", we're dealing
+	   with an IR chip that must be taken out of reset via another FX2
+	   command code (which is the case for HVR-1950 devices). */
+	unsigned int ir_scheme:2;
 
 	/* These bits define which kinds of sources the device can handle.
 	   Note: Digital tuner presence is inferred by the
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
index b58369e..614755e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
@@ -24,6 +24,8 @@
 #define FX2CMD_MEM_WRITE_DWORD  0x01u
 #define FX2CMD_MEM_READ_DWORD   0x02u
 
+#define FX2CMD_HCW_ZILOG_RESET  0x10u /* 1=reset 0=release */
+
 #define FX2CMD_MEM_READ_64BYTES 0x28u
 
 #define FX2CMD_REG_WRITE        0x04u
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index a5217a2..f051c6a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -250,6 +250,7 @@
 static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
 	{FX2CMD_MEM_WRITE_DWORD, "write encoder dword"},
 	{FX2CMD_MEM_READ_DWORD, "read encoder dword"},
+	{FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"},
 	{FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"},
 	{FX2CMD_REG_WRITE, "write encoder register"},
 	{FX2CMD_REG_READ, "read encoder register"},
@@ -1711,6 +1712,14 @@
 		if (!pvr2_hdw_dev_ok(hdw)) return;
 	}
 
+	/* Take the IR chip out of reset, if appropriate */
+	if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) {
+		pvr2_issue_simple_cmd(hdw,
+				      FX2CMD_HCW_ZILOG_RESET |
+				      (1 << 8) |
+				      ((0) << 16));
+	}
+
 	// This step MUST happen after the earlier powerup step.
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9d3c18b..e600576 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -979,7 +979,9 @@
 		printk(KERN_INFO "%s: IR disabled\n",hdw->name);
 		hdw->i2c_func[0x18] = i2c_black_hole;
 	} else if (ir_mode[hdw->unit_number] == 1) {
-		if (hdw->hdw_desc->flag_has_hauppauge_custom_ir) {
+		if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) {
+			/* This comment is present PURELY to get
+			   checkpatch.pl to STFU.  Lovely, eh? */
 			hdw->i2c_func[0x18] = i2c_24xxx_ir;
 		}
 	}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 0d72dc4..00306fa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -30,6 +30,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 struct pvr2_v4l2_dev;
 struct pvr2_v4l2_fh;
@@ -1160,11 +1161,6 @@
 
 
 static struct video_device vdev_template = {
-	.owner      = THIS_MODULE,
-	.type       = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
-	.type2      = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
-		       | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
-		       | V4L2_CAP_READWRITE),
 	.fops       = &vdev_fops,
 };
 
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 423fa7c..9aee7cb 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -165,9 +165,7 @@
 	.llseek =       no_llseek,
 };
 static struct video_device pwc_template = {
-	.owner =	THIS_MODULE,
 	.name =		"Philips Webcam",	/* Filled in later */
-	.type =		VID_TYPE_CAPTURE,
 	.release =	video_device_release,
 	.fops =         &pwc_fops,
 	.minor =        -1,
@@ -1048,19 +1046,20 @@
 	struct pwc_device *pdev = video_get_drvdata(vdev);
 	int rc;
 
-	rc = video_device_create_file(vdev, &dev_attr_button);
+	rc = device_create_file(&vdev->dev, &dev_attr_button);
 	if (rc)
 		goto err;
 	if (pdev->features & FEATURE_MOTOR_PANTILT) {
-		rc = video_device_create_file(vdev, &dev_attr_pan_tilt);
+		rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
 		if (rc) goto err_button;
 	}
 
 	return 0;
 
 err_button:
-	video_device_remove_file(vdev, &dev_attr_button);
+	device_remove_file(&vdev->dev, &dev_attr_button);
 err:
+	PWC_ERROR("Could not create sysfs files.\n");
 	return rc;
 }
 
@@ -1068,8 +1067,8 @@
 {
 	struct pwc_device *pdev = video_get_drvdata(vdev);
 	if (pdev->features & FEATURE_MOTOR_PANTILT)
-		video_device_remove_file(vdev, &dev_attr_pan_tilt);
-	video_device_remove_file(vdev, &dev_attr_button);
+		device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
+	device_remove_file(&vdev->dev, &dev_attr_button);
 }
 
 #ifdef CONFIG_USB_PWC_DEBUG
@@ -1767,9 +1766,8 @@
 		return -ENOMEM;
 	}
 	memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
-	pdev->vdev->dev = &(udev->dev);
+	pdev->vdev->parent = &(udev->dev);
 	strcpy(pdev->vdev->name, name);
-	pdev->vdev->owner = THIS_MODULE;
 	video_set_drvdata(pdev->vdev, pdev);
 
 	pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 8e8e5b2..7417875 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -32,9 +32,11 @@
 #include <linux/smp_lock.h>
 #include <linux/version.h>
 #include <linux/mutex.h>
+#include <linux/mm.h>
 #include <asm/errno.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include "pwc-uncompress.h"
 #include <media/pwc-ioctl.h>
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 04eb2c3..b1d09d8 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -47,8 +47,10 @@
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <linux/version.h>
+#include <linux/mm.h>
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/vmalloc.h>
 #include <linux/usb.h>
 
@@ -184,6 +186,7 @@
 #define S2255_FW_LOADED_DSPWAIT	1
 #define S2255_FW_SUCCESS	2
 #define S2255_FW_FAILED		3
+#define S2255_FW_DISCONNECTING  4
 
 struct s2255_fw {
 	int		      fw_loaded;
@@ -263,7 +266,6 @@
 
 struct s2255_fh {
 	struct s2255_dev	*dev;
-	unsigned int		resources;
 	const struct s2255_fmt	*fmt;
 	unsigned int		width;
 	unsigned int		height;
@@ -273,14 +275,9 @@
 	/* mode below is the desired mode.
 	   mode in s2255_dev is the current mode that was last set */
 	struct s2255_mode	mode;
+	int			resources[MAX_CHANNELS];
 };
 
-/*
- * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles.
- * Limit V4L to one stream at a time.
- */
-#define S2255_MAX_USERS         1
-
 #define CUR_USB_FWVER	774	/* current cypress EEPROM firmware version */
 #define S2255_MAJOR_VERSION	1
 #define S2255_MINOR_VERSION	13
@@ -476,10 +473,9 @@
 	dprintk(100, "s2255 timer\n");
 	if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
 		printk(KERN_ERR "s2255: can't submit urb\n");
-		if (data->fw) {
-			release_firmware(data->fw);
-			data->fw = NULL;
-		}
+		atomic_set(&data->fw_state, S2255_FW_FAILED);
+		/* wake up anything waiting for the firmware */
+		wake_up(&data->wait_fw);
 		return;
 	}
 }
@@ -509,13 +505,18 @@
 	struct usb_device *udev = urb->dev;
 	int len;
 	dprintk(100, "udev %p urb %p", udev, urb);
-	/* TODO: fixme.  reflect change in status */
 	if (urb->status) {
 		dev_err(&udev->dev, "URB failed with status %d", urb->status);
+		atomic_set(&data->fw_state, S2255_FW_FAILED);
+		/* wake up anything waiting for the firmware */
+		wake_up(&data->wait_fw);
 		return;
 	}
 	if (data->fw_urb == NULL) {
-		dev_err(&udev->dev, "early disconncect\n");
+		dev_err(&udev->dev, "s2255 disconnected\n");
+		atomic_set(&data->fw_state, S2255_FW_FAILED);
+		/* wake up anything waiting for the firmware */
+		wake_up(&data->wait_fw);
 		return;
 	}
 #define CHUNK_SIZE 512
@@ -789,7 +790,8 @@
 	}
 	/* it's free, grab it */
 	dev->resources[fh->channel] = 1;
-	dprintk(1, "res: get\n");
+	fh->resources[fh->channel] = 1;
+	dprintk(1, "s2255: res: get\n");
 	mutex_unlock(&dev->lock);
 	return 1;
 }
@@ -799,9 +801,18 @@
 	return dev->resources[fh->channel];
 }
 
+static int res_check(struct s2255_fh *fh)
+{
+	return fh->resources[fh->channel];
+}
+
+
 static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
 {
+	mutex_lock(&dev->lock);
 	dev->resources[fh->channel] = 0;
+	fh->resources[fh->channel] = 0;
+	mutex_unlock(&dev->lock);
 	dprintk(1, "res: put\n");
 }
 
@@ -1232,7 +1243,7 @@
 	}
 
 	if (!res_get(dev, fh)) {
-		dev_err(&dev->udev->dev, "res get busy\n");
+		dev_err(&dev->udev->dev, "s2255: stream busy\n");
 		return -EBUSY;
 	}
 
@@ -1288,8 +1299,10 @@
 	}
 	s2255_stop_acquire(dev, fh->channel);
 	res = videobuf_streamoff(&fh->vb_vidq);
+	if (res < 0)
+		return res;
 	res_free(dev, fh);
-	return res;
+	return 0;
 }
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
@@ -1462,12 +1475,7 @@
 	mutex_lock(&dev->open_lock);
 
 	dev->users[cur_channel]++;
-	if (dev->users[cur_channel] > S2255_MAX_USERS) {
-		dev->users[cur_channel]--;
-		mutex_unlock(&dev->open_lock);
-		printk(KERN_INFO "s2255drv: too many open handles!\n");
-		return -EBUSY;
-	}
+	dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]);
 
 	if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) {
 		err("2255 firmware load failed. retrying.\n");
@@ -1478,7 +1486,8 @@
 				   msecs_to_jiffies(S2255_LOAD_TIMEOUT));
 		if (atomic_read(&dev->fw_data->fw_state)
 		    != S2255_FW_SUCCESS) {
-			printk(KERN_INFO "2255 FW load failed after 2 tries\n");
+			printk(KERN_INFO "2255 FW load failed.\n");
+			dev->users[cur_channel]--;
 			mutex_unlock(&dev->open_lock);
 			return -EFAULT;
 		}
@@ -1494,6 +1503,7 @@
 		    != S2255_FW_SUCCESS) {
 			printk(KERN_INFO "2255 firmware not loaded"
 			       "try again\n");
+			dev->users[cur_channel]--;
 			mutex_unlock(&dev->open_lock);
 			return -EBUSY;
 		}
@@ -1502,6 +1512,7 @@
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
 	if (NULL == fh) {
+		dev->users[cur_channel]--;
 		mutex_unlock(&dev->open_lock);
 		return -ENOMEM;
 	}
@@ -1561,44 +1572,48 @@
 		printk(KERN_ERR "s2255drv: kref problem\n");
 		return;
 	}
+
+	/*
+	 * Wake up any firmware load waiting (only done in .open,
+	 * which holds the open_lock mutex)
+	 */
+	atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
+	wake_up(&dev->fw_data->wait_fw);
+
 	/* prevent s2255_disconnect from racing s2255_open */
 	mutex_lock(&dev->open_lock);
 	s2255_exit_v4l(dev);
-	/* device unregistered so no longer possible to open. open_mutex
-	   can be unlocked */
+	/*
+	 * device unregistered so no longer possible to open. open_mutex
+	 *  can be unlocked and timers deleted afterwards.
+	 */
 	mutex_unlock(&dev->open_lock);
 
 	/* board shutdown stops the read pipe if it is running */
 	s2255_board_shutdown(dev);
 
 	/* make sure firmware still not trying to load */
+	del_timer(&dev->timer);  /* only started in .probe and .open */
+
 	if (dev->fw_data->fw_urb) {
 		dprintk(2, "kill fw_urb\n");
 		usb_kill_urb(dev->fw_data->fw_urb);
 		usb_free_urb(dev->fw_data->fw_urb);
 		dev->fw_data->fw_urb = NULL;
 	}
+
 	/*
-	 * TODO: fixme(above, below): potentially leaving timers alive.
-	 *                            do not ignore timeout below if
-	 *                            it occurs.
+	 * delete the dsp_wait timer, which sets the firmware
+	 * state on completion.  This is done before fw_data
+	 * is freed below.
 	 */
 
-	/* make sure we aren't waiting for the DSP */
-	if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) {
-		/* if we are, wait for the wakeup for fw_success or timeout */
-		wait_event_timeout(dev->fw_data->wait_fw,
-				   (atomic_read(&dev->fw_data->fw_state)
-				   == S2255_FW_SUCCESS),
-				   msecs_to_jiffies(S2255_LOAD_TIMEOUT));
-	}
+	del_timer(&dev->fw_data->dsp_wait); /* only started in .open */
 
-	if (dev->fw_data) {
-		if (dev->fw_data->fw)
-			release_firmware(dev->fw_data->fw);
-		kfree(dev->fw_data->pfw_data);
-		kfree(dev->fw_data);
-	}
+	if (dev->fw_data->fw)
+		release_firmware(dev->fw_data->fw);
+	kfree(dev->fw_data->pfw_data);
+	kfree(dev->fw_data);
 
 	usb_put_dev(dev->udev);
 	dprintk(1, "%s", __func__);
@@ -1615,17 +1630,23 @@
 
 	mutex_lock(&dev->open_lock);
 
-	if (dev->b_acquire[fh->channel])
-		s2255_stop_acquire(dev, fh->channel);
-	res_free(dev, fh);
+	/* turn off stream */
+	if (res_check(fh)) {
+		if (dev->b_acquire[fh->channel])
+			s2255_stop_acquire(dev, fh->channel);
+		videobuf_streamoff(&fh->vb_vidq);
+		res_free(dev, fh);
+	}
+
 	videobuf_mmap_free(&fh->vb_vidq);
-	kfree(fh);
 	dev->users[fh->channel]--;
+
 	mutex_unlock(&dev->open_lock);
 
 	kref_put(&dev->kref, s2255_destroy);
 	dprintk(1, "s2255: close called (minor=%d, users=%d)\n",
 		minor, dev->users[fh->channel]);
+	kfree(fh);
 	return 0;
 }
 
@@ -1658,12 +1679,7 @@
 	.llseek = no_llseek,
 };
 
-static struct video_device template = {
-	.name = "s2255v",
-	.type = VID_TYPE_CAPTURE,
-	.fops = &s2255_fops_v4l,
-	.minor = -1,
-	.release = video_device_release,
+static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
 	.vidioc_querycap = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1685,6 +1701,14 @@
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	.vidiocgmbuf = vidioc_cgmbuf,
 #endif
+};
+
+static struct video_device template = {
+	.name = "s2255v",
+	.fops = &s2255_fops_v4l,
+	.ioctl_ops = &s2255_ioctl_ops,
+	.minor = -1,
+	.release = video_device_release,
 	.tvnorms = S2255_NORMS,
 	.current_norm = V4L2_STD_NTSC_M,
 };
@@ -1706,7 +1730,7 @@
 		/* register 4 video devices */
 		dev->vdev[i] = video_device_alloc();
 		memcpy(dev->vdev[i], &template, sizeof(struct video_device));
-		dev->vdev[i]->dev = &dev->interface->dev;
+		dev->vdev[i]->parent = &dev->interface->dev;
 		if (video_nr == -1)
 			ret = video_register_device(dev->vdev[i],
 						    VFL_TYPE_GRABBER,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 03e7721..6ee63e6 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,6 +46,7 @@
 #include <linux/videotext.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 
 #include "saa5246a.h"
@@ -829,9 +830,7 @@
 
 static struct video_device saa_template =
 {
-	.owner	  = THIS_MODULE,
 	.name	  = IF_NAME,
-	.type	  = VID_TYPE_TELETEXT,
 	.fops	  = &saa_fops,
 	.release  = video_device_release,
 	.minor    = -1,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index fde99d9..0d63973 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -57,6 +57,7 @@
 #include <linux/videotext.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 
 
@@ -710,9 +711,7 @@
 
 static struct video_device saa_template =
 {
-	.owner		= THIS_MODULE,
 	.name		= IF_NAME,
-	.type		= VID_TYPE_TELETEXT,	/*| VID_TYPE_TUNER ?? */
 	.fops           = &saa_fops,
 };
 
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 83f076a..7021bbf 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -27,9 +27,7 @@
 config VIDEO_SAA7134_DVB
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	depends on VIDEO_SAA7134 && DVB_CORE
-	depends on HOTPLUG	# due to FW_LOADER
 	select VIDEOBUF_DVB
-	select FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 6893f99..98364d1 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5853,9 +5853,6 @@
 	unsigned char buf;
 	int board;
 
-	dev->tuner_type = saa7134_boards[dev->board].tuner_type;
-	dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
-
 	switch (dev->board) {
 	case SAA7134_BOARD_BMK_MPEX_NOTUNER:
 	case SAA7134_BOARD_BMK_MPEX_TUNER:
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index cfee84e..75d6184 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -798,7 +798,7 @@
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->dev     = &dev->pci->dev;
+	vfd->parent  = &dev->pci->dev;
 	vfd->release = video_device_release;
 	vfd->debug   = video_debug;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
@@ -945,11 +945,12 @@
 		dev->board = SAA7134_BOARD_UNKNOWN;
 	}
 	dev->autodetected = card[dev->nr] != dev->board;
-	dev->tuner_type   = saa7134_boards[dev->board].tuner_type;
+	dev->tuner_type = saa7134_boards[dev->board].tuner_type;
+	dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
 	dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
 	if (UNSET != tuner[dev->nr])
 		dev->tuner_type = tuner[dev->nr];
-		printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+	printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
 		dev->name,pci_dev->subsystem_vendor,
 		pci_dev->subsystem_device,saa7134_boards[dev->board].name,
 		dev->board, dev->autodetected ?
@@ -1007,11 +1008,9 @@
 	v4l2_prio_init(&dev->prio);
 
 	/* register v4l devices */
-	if (saa7134_no_overlay <= 0) {
-		saa7134_video_template.type |= VID_TYPE_OVERLAY;
-	} else {
-		printk("%s: Overlay support disabled.\n",dev->name);
-	}
+	if (saa7134_no_overlay > 0)
+		printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
+
 	dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
 	err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
 				    video_nr[dev->nr]);
@@ -1024,7 +1023,6 @@
 	       dev->name,dev->video_dev->minor & 0x1f);
 
 	dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
-	dev->vbi_dev->type = VID_TYPE_TUNER | VID_TYPE_TELETEXT;
 
 	err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
 				    vbi_nr[dev->nr]);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 2a5ab95..c0c5d75 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -89,14 +89,14 @@
 	err = -EBUSY;
 	if (!mutex_trylock(&dev->empress_tsq.vb_lock))
 		goto done;
-	if (dev->empress_users)
+	if (atomic_read(&dev->empress_users))
 		goto done_up;
 
 	/* Unmute audio */
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
 		saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
 
-	dev->empress_users++;
+	atomic_inc(&dev->empress_users);
 	file->private_data = dev;
 	err = 0;
 
@@ -110,8 +110,6 @@
 {
 	struct saa7134_dev *dev = file->private_data;
 
-	mutex_lock(&dev->empress_tsq.vb_lock);
-
 	videobuf_stop(&dev->empress_tsq);
 	videobuf_mmap_free(&dev->empress_tsq);
 
@@ -122,9 +120,7 @@
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
 		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
 
-	dev->empress_users--;
-
-	mutex_unlock(&dev->empress_tsq.vb_lock);
+	atomic_dec(&dev->empress_users);
 
 	return 0;
 }
@@ -333,6 +329,22 @@
 	return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
 }
 
+static int empress_g_ctrl(struct file *file, void *priv,
+					struct v4l2_control *c)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	return saa7134_g_ctrl_internal(dev, NULL, c);
+}
+
+static int empress_s_ctrl(struct file *file, void *priv,
+					struct v4l2_control *c)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	return saa7134_s_ctrl_internal(dev, NULL, c);
+}
+
 static int empress_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *c)
 {
@@ -400,16 +412,7 @@
 	.llseek   = no_llseek,
 };
 
-/* ----------------------------------------------------------- */
-
-static struct video_device saa7134_empress_template =
-{
-	.name          = "saa7134-empress",
-	.type          = 0 /* FIXME */,
-	.type2         = 0 /* FIXME */,
-	.fops          = &ts_fops,
-	.minor	       = -1,
-
+static const struct v4l2_ioctl_ops ts_ioctl_ops = {
 	.vidioc_querycap		= empress_querycap,
 	.vidioc_enum_fmt_vid_cap	= empress_enum_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,
@@ -428,8 +431,17 @@
 
 	.vidioc_queryctrl		= empress_queryctrl,
 	.vidioc_querymenu		= empress_querymenu,
-	.vidioc_g_ctrl			= saa7134_g_ctrl,
-	.vidioc_s_ctrl			= saa7134_s_ctrl,
+	.vidioc_g_ctrl			= empress_g_ctrl,
+	.vidioc_s_ctrl			= empress_s_ctrl,
+};
+
+/* ----------------------------------------------------------- */
+
+static struct video_device saa7134_empress_template = {
+	.name          = "saa7134-empress",
+	.fops          = &ts_fops,
+	.minor	       = -1,
+	.ioctl_ops     = &ts_ioctl_ops,
 
 	.tvnorms			= SAA7134_NORMS,
 	.current_norm			= V4L2_STD_PAL,
@@ -445,7 +457,7 @@
 		ts_reset_encoder(dev);
 	} else {
 		dprintk("video signal acquired\n");
-		if (dev->empress_users)
+		if (atomic_read(&dev->empress_users))
 			ts_init_encoder(dev);
 	}
 }
@@ -465,7 +477,7 @@
 	if (NULL == dev->empress_dev)
 		return -ENOMEM;
 	*(dev->empress_dev) = saa7134_empress_template;
-	dev->empress_dev->dev     = &dev->pci->dev;
+	dev->empress_dev->parent  = &dev->pci->dev;
 	dev->empress_dev->release = video_device_release;
 	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
 		 "%s empress (%s)", dev->name,
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 1a51375..68c2689 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1112,10 +1112,8 @@
 
 /* ------------------------------------------------------------------ */
 
-int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
+int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
 {
-	struct saa7134_fh *fh = priv;
-	struct saa7134_dev *dev = fh->dev;
 	const struct v4l2_queryctrl* ctrl;
 
 	ctrl = ctrl_by_id(c->id);
@@ -1160,20 +1158,31 @@
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(saa7134_g_ctrl);
+EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal);
 
-int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
+static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
+{
+	struct saa7134_fh *fh = priv;
+
+	return saa7134_g_ctrl_internal(fh->dev, fh, c);
+}
+
+int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c)
 {
 	const struct v4l2_queryctrl* ctrl;
-	struct saa7134_fh *fh = f;
-	struct saa7134_dev *dev = fh->dev;
 	unsigned long flags;
 	int restart_overlay = 0;
-	int err = -EINVAL;
+	int err;
 
-	err = v4l2_prio_check(&dev->prio, &fh->prio);
-	if (0 != err)
-		return err;
+	/* When called from the empress code fh == NULL.
+	   That needs to be fixed somehow, but for now this is
+	   good enough. */
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+	err = -EINVAL;
 
 	mutex_lock(&dev->lock);
 
@@ -1274,7 +1283,14 @@
 	mutex_unlock(&dev->lock);
 	return err;
 }
-EXPORT_SYMBOL_GPL(saa7134_s_ctrl);
+EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal);
+
+static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
+{
+	struct saa7134_fh *fh = f;
+
+	return saa7134_s_ctrl_internal(fh->dev, fh, c);
+}
 
 /* ------------------------------------------------------------------ */
 
@@ -2353,26 +2369,7 @@
 	.llseek   = no_llseek,
 };
 
-static const struct file_operations radio_fops =
-{
-	.owner	  = THIS_MODULE,
-	.open	  = video_open,
-	.release  = video_release,
-	.ioctl	  = video_ioctl2,
-	.compat_ioctl	= v4l_compat_ioctl32,
-	.llseek   = no_llseek,
-};
-
-/* ----------------------------------------------------------- */
-/* exported stuff                                              */
-
-struct video_device saa7134_video_template =
-{
-	.name				= "saa7134-video",
-	.type				= VID_TYPE_CAPTURE|VID_TYPE_TUNER |
-					VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-	.fops				= &video_fops,
-	.minor				= -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap		= saa7134_querycap,
 	.vidioc_enum_fmt_vid_cap	= saa7134_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap		= saa7134_g_fmt_vid_cap,
@@ -2421,16 +2418,18 @@
 	.vidioc_g_register              = vidioc_g_register,
 	.vidioc_s_register              = vidioc_s_register,
 #endif
-	.tvnorms			= SAA7134_NORMS,
-	.current_norm			= V4L2_STD_PAL,
 };
 
-struct video_device saa7134_radio_template =
-{
-	.name			= "saa7134-radio",
-	.type			= VID_TYPE_TUNER,
-	.fops			= &radio_fops,
-	.minor			= -1,
+static const struct file_operations radio_fops = {
+	.owner	  = THIS_MODULE,
+	.open	  = video_open,
+	.release  = video_release,
+	.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_g_tuner		= radio_g_tuner,
 	.vidioc_enum_input	= radio_enum_input,
@@ -2447,6 +2446,25 @@
 	.vidioc_s_frequency	= saa7134_s_frequency,
 };
 
+/* ----------------------------------------------------------- */
+/* exported stuff                                              */
+
+struct video_device saa7134_video_template = {
+	.name				= "saa7134-video",
+	.fops				= &video_fops,
+	.ioctl_ops 			= &video_ioctl_ops,
+	.minor				= -1,
+	.tvnorms			= SAA7134_NORMS,
+	.current_norm			= V4L2_STD_PAL,
+};
+
+struct video_device saa7134_radio_template = {
+	.name			= "saa7134-radio",
+	.fops			= &radio_fops,
+	.ioctl_ops 		= &radio_ioctl_ops,
+	.minor			= -1,
+};
+
 int saa7134_video_init1(struct saa7134_dev *dev)
 {
 	/* sanitycheck insmod options */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 6927cbe..a0884f6 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -34,6 +34,7 @@
 #include <asm/io.h>
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tuner.h>
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
@@ -560,7 +561,7 @@
 	/* SAA7134_MPEG_EMPRESS only */
 	struct video_device        *empress_dev;
 	struct videobuf_queue      empress_tsq;
-	unsigned int               empress_users;
+	atomic_t 		   empress_users;
 	struct work_struct         empress_workqueue;
 	int                        empress_started;
 
@@ -662,8 +663,8 @@
 extern struct video_device saa7134_video_template;
 extern struct video_device saa7134_radio_template;
 
-int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c);
-int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c);
+int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c);
+int saa7134_g_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, struct v4l2_control *c);
 int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c);
 
 int saa7134_videoport_init(struct saa7134_dev *dev);
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 2220f95..af60ede 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -35,7 +35,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-common.h>
diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h
index cd4b635..e69de29 100644
--- a/drivers/media/video/saa7196.h
+++ b/drivers/media/video/saa7196.h
@@ -1,117 +0,0 @@
-/*
-    Definitions for the Philips SAA7196 digital video decoder,
-    scaler, and clock generator circuit (DESCpro), as used in
-    the PlanB video input of the Powermac 7x00/8x00 series.
-
-    Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
-    The register defines are shamelessly copied from the meteor
-    driver out of NetBSD (with permission),
-    and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
-    (Thanks !)
-
-    Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
-
-    The default values used for PlanB are my mistakes.
-*/
-
-/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
-
-#ifndef _SAA7196_H_
-#define _SAA7196_H_
-
-#define SAA7196_NUMREGS	0x31	/* Number of registers (used)*/
-#define NUM_SUPPORTED_NORM 3	/* Number of supported norms by PlanB */
-
-/* Decoder part: */
-#define SAA7196_IDEL    0x00    /* Increment delay */
-#define SAA7196_HSB5    0x01    /* H-sync begin; 50 hz */
-#define SAA7196_HSS5    0x02    /* H-sync stop; 50 hz */
-#define SAA7196_HCB5    0x03    /* H-clamp begin; 50 hz */
-#define SAA7196_HCS5    0x04    /* H-clamp stop; 50 hz */
-#define SAA7196_HSP5    0x05    /* H-sync after PHI1; 50 hz */
-#define SAA7196_LUMC    0x06    /* Luminance control */
-#define SAA7196_HUEC    0x07    /* Hue control */
-#define SAA7196_CKTQ    0x08    /* Colour Killer Threshold QAM (PAL, NTSC) */
-#define SAA7196_CKTS    0x09    /* Colour Killer Threshold SECAM */
-#define SAA7196_PALS    0x0a    /* PAL switch sensitivity */
-#define SAA7196_SECAMS  0x0b    /* SECAM switch sensitivity */
-#define SAA7196_CGAINC  0x0c    /* Chroma gain control */
-#define SAA7196_STDC    0x0d    /* Standard/Mode control */
-#define SAA7196_IOCC    0x0e    /* I/O and Clock Control */
-#define SAA7196_CTRL1   0x0f    /* Control #1 */
-#define SAA7196_CTRL2   0x10    /* Control #2 */
-#define SAA7196_CGAINR  0x11    /* Chroma Gain Reference */
-#define SAA7196_CSAT    0x12    /* Chroma Saturation */
-#define SAA7196_CONT    0x13    /* Luminance Contrast */
-#define SAA7196_HSB6    0x14    /* H-sync begin; 60 hz */
-#define SAA7196_HSS6    0x15    /* H-sync stop; 60 hz */
-#define SAA7196_HCB6    0x16    /* H-clamp begin; 60 hz */
-#define SAA7196_HCS6    0x17    /* H-clamp stop; 60 hz */
-#define SAA7196_HSP6    0x18    /* H-sync after PHI1; 60 hz */
-#define SAA7196_BRIG    0x19    /* Luminance Brightness */
-
-/* Scaler part: */
-#define SAA7196_FMTS    0x20    /* Formats and sequence */
-#define SAA7196_OUTPIX  0x21    /* Output data pixel/line */
-#define SAA7196_INPIX   0x22    /* Input data pixel/line */
-#define SAA7196_HWS     0x23    /* Horiz. window start */
-#define SAA7196_HFILT   0x24    /* Horiz. filter */
-#define SAA7196_OUTLINE 0x25    /* Output data lines/field */
-#define SAA7196_INLINE  0x26    /* Input data lines/field */
-#define SAA7196_VWS     0x27    /* Vertical window start */
-#define SAA7196_VYP     0x28    /* AFS/vertical Y processing */
-#define SAA7196_VBS     0x29    /* Vertical Bypass start */
-#define SAA7196_VBCNT   0x2a    /* Vertical Bypass count */
-#define SAA7196_VBP     0x2b    /* veritcal Bypass Polarity */
-#define SAA7196_VLOW    0x2c    /* Colour-keying lower V limit */
-#define SAA7196_VHIGH   0x2d    /* Colour-keying upper V limit */
-#define SAA7196_ULOW    0x2e    /* Colour-keying lower U limit */
-#define SAA7196_UHIGH   0x2f    /* Colour-keying upper U limit */
-#define SAA7196_DPATH   0x30    /* Data path setting  */
-
-/* Initialization default values: */
-
-unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = {
-
-/* PAL, 768x576 (no scaling), composite video-in */
-/* Decoder: */
-      { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
-	0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98,
-	0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
-	0xe9, 0xa2,
-/* Padding */
-		    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
-	0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
-	0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
-	0x87 },
-
-/* NTSC, 640x480? (no scaling), composite video-in */
-/* Decoder: */
-      { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00,
-	0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98,
-	0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2,
-	0xe9, 0x98,
-/* Padding */
-		    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
-	0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d,
-	0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
-	0x87 },
-
-/* SECAM, 768x576 (no scaling), composite video-in */
-/* Decoder: */
-      { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
-	0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98,
-	0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
-	0xe9, 0xa2,
-/* Padding */
-		    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
-	0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
-	0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
-	0x87 }
-	};
-
-#endif /* _SAA7196_H_ */
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 1cd6293..f481277 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1230,9 +1230,7 @@
 	.llseek =       no_llseek,
 };
 static struct video_device se401_template = {
-	.owner =	THIS_MODULE,
 	.name =         "se401 USB camera",
-	.type =         VID_TYPE_CAPTURE,
 	.fops =         &se401_fops,
 };
 
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index 835ef87..2ce685d 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -5,6 +5,7 @@
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
 
 #define se401_DEBUG	/* Turn on debug messages */
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 012005e..f7ca3cb 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -91,6 +91,7 @@
 	void __iomem *base;
 	unsigned long video_limit;
 
+	/* lock used to protect videobuf */
 	spinlock_t lock;
 	struct list_head capture;
 	struct videobuf_buffer *active;
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
index 0c8d87d..cbfc444 100644
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ b/drivers/media/video/sn9c102/sn9c102.h
@@ -25,6 +25,7 @@
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 7f9c7bc..2340876 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1038,8 +1038,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1064,8 +1063,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1098,8 +1096,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1132,8 +1129,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1170,8 +1166,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1198,8 +1193,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1232,8 +1226,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1271,8 +1264,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1318,8 +1310,7 @@
 	if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
 		return -ERESTARTSYS;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam) {
 		mutex_unlock(&sn9c102_sysfs_lock);
 		return -ENODEV;
@@ -1400,8 +1391,7 @@
 	struct sn9c102_device* cam;
 	ssize_t count;
 
-	cam = video_get_drvdata(container_of(cd, struct video_device,
-					     class_dev));
+	cam = video_get_drvdata(container_of(cd, struct video_device, dev));
 	if (!cam)
 		return -ENODEV;
 
@@ -1428,49 +1418,49 @@
 
 static int sn9c102_create_sysfs(struct sn9c102_device* cam)
 {
-	struct device *classdev = &(cam->v4ldev->class_dev);
+	struct device *dev = &(cam->v4ldev->dev);
 	int err = 0;
 
-	if ((err = device_create_file(classdev, &dev_attr_reg)))
+	if ((err = device_create_file(dev, &dev_attr_reg)))
 		goto err_out;
-	if ((err = device_create_file(classdev, &dev_attr_val)))
+	if ((err = device_create_file(dev, &dev_attr_val)))
 		goto err_reg;
-	if ((err = device_create_file(classdev, &dev_attr_frame_header)))
+	if ((err = device_create_file(dev, &dev_attr_frame_header)))
 		goto err_val;
 
 	if (cam->sensor.sysfs_ops) {
-		if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
+		if ((err = device_create_file(dev, &dev_attr_i2c_reg)))
 			goto err_frame_header;
-		if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
+		if ((err = device_create_file(dev, &dev_attr_i2c_val)))
 			goto err_i2c_reg;
 	}
 
 	if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
-		if ((err = device_create_file(classdev, &dev_attr_green)))
+		if ((err = device_create_file(dev, &dev_attr_green)))
 			goto err_i2c_val;
 	} else {
-		if ((err = device_create_file(classdev, &dev_attr_blue)))
+		if ((err = device_create_file(dev, &dev_attr_blue)))
 			goto err_i2c_val;
-		if ((err = device_create_file(classdev, &dev_attr_red)))
+		if ((err = device_create_file(dev, &dev_attr_red)))
 			goto err_blue;
 	}
 
 	return 0;
 
 err_blue:
-	device_remove_file(classdev, &dev_attr_blue);
+	device_remove_file(dev, &dev_attr_blue);
 err_i2c_val:
 	if (cam->sensor.sysfs_ops)
-		device_remove_file(classdev, &dev_attr_i2c_val);
+		device_remove_file(dev, &dev_attr_i2c_val);
 err_i2c_reg:
 	if (cam->sensor.sysfs_ops)
-		device_remove_file(classdev, &dev_attr_i2c_reg);
+		device_remove_file(dev, &dev_attr_i2c_reg);
 err_frame_header:
-	device_remove_file(classdev, &dev_attr_frame_header);
+	device_remove_file(dev, &dev_attr_frame_header);
 err_val:
-	device_remove_file(classdev, &dev_attr_val);
+	device_remove_file(dev, &dev_attr_val);
 err_reg:
-	device_remove_file(classdev, &dev_attr_reg);
+	device_remove_file(dev, &dev_attr_reg);
 err_out:
 	return err;
 }
@@ -3319,8 +3309,6 @@
 	}
 
 	strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
-	cam->v4ldev->owner = THIS_MODULE;
-	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index e39b98f..b6be5ee 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,6 +25,7 @@
 #include <linux/vmalloc.h>
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-core.h>
 #include <media/soc_camera.h>
@@ -193,7 +194,7 @@
 	mutex_lock(&video_lock);
 
 	vdev = video_devdata(file);
-	icd = container_of(vdev->dev, struct soc_camera_device, dev);
+	icd = container_of(vdev->parent, struct soc_camera_device, dev);
 	ici = to_soc_camera_host(icd->dev.parent);
 
 	if (!try_module_get(icd->ops->owner)) {
@@ -258,7 +259,7 @@
 
 	vfree(icf);
 
-	dev_dbg(vdev->dev, "camera device close\n");
+	dev_dbg(vdev->parent, "camera device close\n");
 
 	return 0;
 }
@@ -271,7 +272,7 @@
 	struct video_device *vdev = icd->vdev;
 	int err = -EINVAL;
 
-	dev_err(vdev->dev, "camera device read not implemented\n");
+	dev_err(vdev->parent, "camera device read not implemented\n");
 
 	return err;
 }
@@ -861,6 +862,35 @@
 }
 EXPORT_SYMBOL(soc_camera_device_unregister);
 
+static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+	.vidioc_querycap	 = soc_camera_querycap,
+	.vidioc_g_fmt_vid_cap    = soc_camera_g_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap    = soc_camera_s_fmt_vid_cap,
+	.vidioc_enum_input	 = soc_camera_enum_input,
+	.vidioc_g_input		 = soc_camera_g_input,
+	.vidioc_s_input		 = soc_camera_s_input,
+	.vidioc_s_std		 = soc_camera_s_std,
+	.vidioc_reqbufs		 = soc_camera_reqbufs,
+	.vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
+	.vidioc_querybuf	 = soc_camera_querybuf,
+	.vidioc_qbuf		 = soc_camera_qbuf,
+	.vidioc_dqbuf		 = soc_camera_dqbuf,
+	.vidioc_streamon	 = soc_camera_streamon,
+	.vidioc_streamoff	 = soc_camera_streamoff,
+	.vidioc_queryctrl	 = soc_camera_queryctrl,
+	.vidioc_g_ctrl		 = soc_camera_g_ctrl,
+	.vidioc_s_ctrl		 = soc_camera_s_ctrl,
+	.vidioc_cropcap		 = soc_camera_cropcap,
+	.vidioc_g_crop		 = soc_camera_g_crop,
+	.vidioc_s_crop		 = soc_camera_s_crop,
+	.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register	 = soc_camera_g_register,
+	.vidioc_s_register	 = soc_camera_s_register,
+#endif
+};
+
 int soc_camera_video_start(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -877,45 +907,19 @@
 
 	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 	/* Maybe better &ici->dev */
-	vdev->dev		= &icd->dev;
-	vdev->type		= VID_TYPE_CAPTURE;
+	vdev->parent		= &icd->dev;
 	vdev->current_norm	= V4L2_STD_UNKNOWN;
 	vdev->fops		= &soc_camera_fops;
+	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
 	vdev->release		= video_device_release;
 	vdev->minor		= -1;
 	vdev->tvnorms		= V4L2_STD_UNKNOWN,
-	vdev->vidioc_querycap	= soc_camera_querycap;
-	vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap;
-	vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap;
-	vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap;
-	vdev->vidioc_enum_input	= soc_camera_enum_input;
-	vdev->vidioc_g_input	= soc_camera_g_input;
-	vdev->vidioc_s_input	= soc_camera_s_input;
-	vdev->vidioc_s_std	= soc_camera_s_std;
-	vdev->vidioc_reqbufs	= soc_camera_reqbufs;
-	vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap;
-	vdev->vidioc_querybuf	= soc_camera_querybuf;
-	vdev->vidioc_qbuf	= soc_camera_qbuf;
-	vdev->vidioc_dqbuf	= soc_camera_dqbuf;
-	vdev->vidioc_streamon	= soc_camera_streamon;
-	vdev->vidioc_streamoff	= soc_camera_streamoff;
-	vdev->vidioc_queryctrl	= soc_camera_queryctrl;
-	vdev->vidioc_g_ctrl	= soc_camera_g_ctrl;
-	vdev->vidioc_s_ctrl	= soc_camera_s_ctrl;
-	vdev->vidioc_cropcap	= soc_camera_cropcap;
-	vdev->vidioc_g_crop	= soc_camera_g_crop;
-	vdev->vidioc_s_crop	= soc_camera_s_crop;
-	vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	vdev->vidioc_g_register	= soc_camera_g_register;
-	vdev->vidioc_s_register	= soc_camera_s_register;
-#endif
 
 	icd->current_fmt = &icd->formats[0];
 
 	err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
 	if (err < 0) {
-		dev_err(vdev->dev, "video_register_device failed\n");
+		dev_err(vdev->parent, "video_register_device failed\n");
 		goto evidregd;
 	}
 	icd->vdev = vdev;
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index f308c38..ad36af3 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -34,6 +34,7 @@
 #include <linux/vmalloc.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include "stk-webcam.h"
 
@@ -340,17 +341,19 @@
 {
 	int ret;
 
-	ret = video_device_create_file(vdev, &dev_attr_brightness);
-	ret += video_device_create_file(vdev, &dev_attr_hflip);
-	ret += video_device_create_file(vdev, &dev_attr_vflip);
+	ret = device_create_file(&vdev->dev, &dev_attr_brightness);
+	ret += device_create_file(&vdev->dev, &dev_attr_hflip);
+	ret += device_create_file(&vdev->dev, &dev_attr_vflip);
+	if (ret)
+		STK_WARNING("Could not create sysfs files\n");
 	return ret;
 }
 
 static void stk_remove_sysfs_files(struct video_device *vdev)
 {
-	video_device_remove_file(vdev, &dev_attr_brightness);
-	video_device_remove_file(vdev, &dev_attr_hflip);
-	video_device_remove_file(vdev, &dev_attr_vflip);
+	device_remove_file(&vdev->dev, &dev_attr_brightness);
+	device_remove_file(&vdev->dev, &dev_attr_hflip);
+	device_remove_file(&vdev->dev, &dev_attr_vflip);
 }
 
 #else
@@ -442,18 +445,19 @@
 				fb->v4lbuf.bytesused = 0;
 				fill = fb->buffer;
 			} else if (fb->v4lbuf.bytesused == dev->frame_size) {
-				list_move_tail(dev->sio_avail.next,
-					&dev->sio_full);
-				wake_up(&dev->wait_frame);
-				if (list_empty(&dev->sio_avail)) {
-					(void) (printk_ratelimit() &&
-					STK_ERROR("No buffer available\n"));
-					goto resubmit;
+				if (list_is_singular(&dev->sio_avail)) {
+					/* Always reuse the last buffer */
+					fb->v4lbuf.bytesused = 0;
+					fill = fb->buffer;
+				} else {
+					list_move_tail(dev->sio_avail.next,
+						&dev->sio_full);
+					wake_up(&dev->wait_frame);
+					fb = list_first_entry(&dev->sio_avail,
+						struct stk_sio_buffer, list);
+					fb->v4lbuf.bytesused = 0;
+					fill = fb->buffer;
 				}
-				fb = list_first_entry(&dev->sio_avail,
-					struct stk_sio_buffer, list);
-				fb->v4lbuf.bytesused = 0;
-				fill = fb->buffer;
 			}
 		} else {
 			framelen -= 4;
@@ -1327,20 +1331,7 @@
 	.llseek = no_llseek
 };
 
-static void stk_v4l_dev_release(struct video_device *vd)
-{
-}
-
-static struct video_device stk_v4l_data = {
-	.name = "stkwebcam",
-	.type = VFL_TYPE_GRABBER,
-	.type2 = VID_TYPE_CAPTURE,
-	.minor = -1,
-	.tvnorms = V4L2_STD_UNKNOWN,
-	.current_norm = V4L2_STD_UNKNOWN,
-	.fops = &v4l_stk_fops,
-	.release = stk_v4l_dev_release,
-
+static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
 	.vidioc_querycap = stk_vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap,
@@ -1362,6 +1353,20 @@
 	.vidioc_g_parm = stk_vidioc_g_parm,
 };
 
+static void stk_v4l_dev_release(struct video_device *vd)
+{
+}
+
+static struct video_device stk_v4l_data = {
+	.name = "stkwebcam",
+	.minor = -1,
+	.tvnorms = V4L2_STD_UNKNOWN,
+	.current_norm = V4L2_STD_UNKNOWN,
+	.fops = &v4l_stk_fops,
+	.ioctl_ops = &v4l_stk_ioctl_ops,
+	.release = stk_v4l_dev_release,
+};
+
 
 static int stk_register_video_device(struct stk_camera *dev)
 {
@@ -1369,7 +1374,7 @@
 
 	dev->vdev = stk_v4l_data;
 	dev->vdev.debug = debug;
-	dev->vdev.dev = &dev->interface->dev;
+	dev->vdev.parent = &dev->interface->dev;
 	dev->vdev.priv = dev;
 	err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
 	if (err)
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index c109511..276bded 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -43,6 +43,7 @@
 #include <linux/vmalloc.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include "saa7146.h"
 #include "saa7146reg.h"
@@ -1918,7 +1919,6 @@
 /* template for video_device-structure */
 static struct video_device saa_template = {
 	.name = "SAA7146A",
-	.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
 	.fops = &saa_fops,
 	.minor = -1,
 };
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index d7f130b..56dc3d6 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -66,6 +66,7 @@
 #include <linux/errno.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
 
@@ -524,53 +525,54 @@
 {
 	int rc;
 
-	rc = video_device_create_file(vdev, &dev_attr_model);
+	rc = device_create_file(&vdev->dev, &dev_attr_model);
 	if (rc) goto err;
-	rc = video_device_create_file(vdev, &dev_attr_in_use);
+	rc = device_create_file(&vdev->dev, &dev_attr_in_use);
 	if (rc) goto err_model;
-	rc = video_device_create_file(vdev, &dev_attr_streaming);
+	rc = device_create_file(&vdev->dev, &dev_attr_streaming);
 	if (rc) goto err_inuse;
-	rc = video_device_create_file(vdev, &dev_attr_palette);
+	rc = device_create_file(&vdev->dev, &dev_attr_palette);
 	if (rc) goto err_stream;
-	rc = video_device_create_file(vdev, &dev_attr_frames_total);
+	rc = device_create_file(&vdev->dev, &dev_attr_frames_total);
 	if (rc) goto err_pal;
-	rc = video_device_create_file(vdev, &dev_attr_frames_read);
+	rc = device_create_file(&vdev->dev, &dev_attr_frames_read);
 	if (rc) goto err_framtot;
-	rc = video_device_create_file(vdev, &dev_attr_packets_dropped);
+	rc = device_create_file(&vdev->dev, &dev_attr_packets_dropped);
 	if (rc) goto err_framread;
-	rc = video_device_create_file(vdev, &dev_attr_decoding_errors);
+	rc = device_create_file(&vdev->dev, &dev_attr_decoding_errors);
 	if (rc) goto err_dropped;
 
 	return 0;
 
 err_dropped:
-	video_device_remove_file(vdev, &dev_attr_packets_dropped);
+	device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
 err_framread:
-	video_device_remove_file(vdev, &dev_attr_frames_read);
+	device_remove_file(&vdev->dev, &dev_attr_frames_read);
 err_framtot:
-	video_device_remove_file(vdev, &dev_attr_frames_total);
+	device_remove_file(&vdev->dev, &dev_attr_frames_total);
 err_pal:
-	video_device_remove_file(vdev, &dev_attr_palette);
+	device_remove_file(&vdev->dev, &dev_attr_palette);
 err_stream:
-	video_device_remove_file(vdev, &dev_attr_streaming);
+	device_remove_file(&vdev->dev, &dev_attr_streaming);
 err_inuse:
-	video_device_remove_file(vdev, &dev_attr_in_use);
+	device_remove_file(&vdev->dev, &dev_attr_in_use);
 err_model:
-	video_device_remove_file(vdev, &dev_attr_model);
+	device_remove_file(&vdev->dev, &dev_attr_model);
 err:
+	PDEBUG(0, "STV(e): Could not create sysfs files");
 	return rc;
 }
 
 static void stv680_remove_sysfs_files(struct video_device *vdev)
 {
-	video_device_remove_file(vdev, &dev_attr_model);
-	video_device_remove_file(vdev, &dev_attr_in_use);
-	video_device_remove_file(vdev, &dev_attr_streaming);
-	video_device_remove_file(vdev, &dev_attr_palette);
-	video_device_remove_file(vdev, &dev_attr_frames_total);
-	video_device_remove_file(vdev, &dev_attr_frames_read);
-	video_device_remove_file(vdev, &dev_attr_packets_dropped);
-	video_device_remove_file(vdev, &dev_attr_decoding_errors);
+	device_remove_file(&vdev->dev, &dev_attr_model);
+	device_remove_file(&vdev->dev, &dev_attr_in_use);
+	device_remove_file(&vdev->dev, &dev_attr_streaming);
+	device_remove_file(&vdev->dev, &dev_attr_palette);
+	device_remove_file(&vdev->dev, &dev_attr_frames_total);
+	device_remove_file(&vdev->dev, &dev_attr_frames_read);
+	device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
+	device_remove_file(&vdev->dev, &dev_attr_decoding_errors);
 }
 
 /********************************************************************
@@ -1400,9 +1402,7 @@
 	.llseek =       no_llseek,
 };
 static struct video_device stv680_template = {
-	.owner =	THIS_MODULE,
 	.name =		"STV0680 USB camera",
-	.type =		VID_TYPE_CAPTURE,
 	.fops =         &stv680_fops,
 	.release =	video_device_release,
 	.minor = 	-1,
@@ -1454,7 +1454,7 @@
 		goto error;
 	}
 	memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template));
-	stv680->vdev->dev = &intf->dev;
+	stv680->vdev->parent = &intf->dev;
 	video_set_drvdata(stv680->vdev, stv680);
 
 	memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index ae75c18..4963d42 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -44,10 +44,11 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/i2c-addr.h>
 
 #ifndef VIDEO_AUDIO_BALANCE
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7a8ce8f..792f0b0 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -25,7 +25,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 9220378..281065b 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -29,7 +29,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 93d879d..d806a35 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -19,6 +19,7 @@
 #include <media/tuner.h>
 #include <media/tuner-types.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 #include "mt20xx.h"
 #include "tda8290.h"
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 9da0e18..bcc32fa 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -34,13 +34,13 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
 
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/audiochip.h>
+#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
 MODULE_AUTHOR("John Klar");
@@ -261,70 +261,72 @@
 	{ TUNER_ABSENT,        		"MaxLinear MXL5005_v2"},
 	{ TUNER_PHILIPS_TDA8290, 	"Philips 18271_8295"},
 	/* 150-159 */
-	{ TUNER_ABSENT,        "Xceive XC5000"},
+	{ TUNER_ABSENT,                 "Xceive XC5000"},
 };
 
+/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+ * internal to a video chip, i.e. not a separate audio chip. */
 static struct HAUPPAUGE_AUDIOIC
 {
-	enum audiochip  id;
+	u32   id;
 	char *name;
 }
 audioIC[] =
 {
 	/* 0-4 */
-	{AUDIO_CHIP_NONE,     "None"},
-	{AUDIO_CHIP_TEA6300,  "TEA6300"},
-	{AUDIO_CHIP_TEA6300,  "TEA6320"},
-	{AUDIO_CHIP_TDA985X,  "TDA9850"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3400C"},
+	{ V4L2_IDENT_NONE,      "None"      },
+	{ V4L2_IDENT_UNKNOWN,   "TEA6300"   },
+	{ V4L2_IDENT_UNKNOWN,   "TEA6320"   },
+	{ V4L2_IDENT_UNKNOWN,   "TDA9850"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3400C"  },
 	/* 5-9 */
-	{AUDIO_CHIP_MSP34XX,  "MSP3410D"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3415"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3430"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3438"},
-	{AUDIO_CHIP_UNKNOWN,  "CS5331"},
+	{ V4L2_IDENT_MSPX4XX,   "MSP3410D"  },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3415"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3430"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3438"   },
+	{ V4L2_IDENT_UNKNOWN,   "CS5331"    },
 	/* 10-14 */
-	{AUDIO_CHIP_MSP34XX,  "MSP3435"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3440"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3445"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3411"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3416"},
+	{ V4L2_IDENT_MSPX4XX,   "MSP3435"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3440"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3445"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3411"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3416"   },
 	/* 15-19 */
-	{AUDIO_CHIP_MSP34XX,  "MSP3425"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3451"},
-	{AUDIO_CHIP_MSP34XX,  "MSP3418"},
-	{AUDIO_CHIP_UNKNOWN,  "Type 0x12"},
-	{AUDIO_CHIP_UNKNOWN,  "OKI7716"},
+	{ V4L2_IDENT_MSPX4XX,   "MSP3425"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3451"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP3418"   },
+	{ V4L2_IDENT_UNKNOWN,   "Type 0x12" },
+	{ V4L2_IDENT_UNKNOWN,   "OKI7716"   },
 	/* 20-24 */
-	{AUDIO_CHIP_MSP34XX,  "MSP4410"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4420"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4440"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4450"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4408"},
+	{ V4L2_IDENT_MSPX4XX,   "MSP4410"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4420"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4440"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4450"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4408"   },
 	/* 25-29 */
-	{AUDIO_CHIP_MSP34XX,  "MSP4418"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4428"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4448"},
-	{AUDIO_CHIP_MSP34XX,  "MSP4458"},
-	{AUDIO_CHIP_MSP34XX,  "Type 0x1d"},
+	{ V4L2_IDENT_MSPX4XX,   "MSP4418"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4428"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4448"   },
+	{ V4L2_IDENT_MSPX4XX,   "MSP4458"   },
+	{ V4L2_IDENT_MSPX4XX,   "Type 0x1d" },
 	/* 30-34 */
-	{AUDIO_CHIP_INTERNAL, "CX880"},
-	{AUDIO_CHIP_INTERNAL, "CX881"},
-	{AUDIO_CHIP_INTERNAL, "CX883"},
-	{AUDIO_CHIP_INTERNAL, "CX882"},
-	{AUDIO_CHIP_INTERNAL, "CX25840"},
+	{ V4L2_IDENT_AMBIGUOUS, "CX880"     },
+	{ V4L2_IDENT_AMBIGUOUS, "CX881"     },
+	{ V4L2_IDENT_AMBIGUOUS, "CX883"     },
+	{ V4L2_IDENT_AMBIGUOUS, "CX882"     },
+	{ V4L2_IDENT_AMBIGUOUS, "CX25840"   },
 	/* 35-39 */
-	{AUDIO_CHIP_INTERNAL, "CX25841"},
-	{AUDIO_CHIP_INTERNAL, "CX25842"},
-	{AUDIO_CHIP_INTERNAL, "CX25843"},
-	{AUDIO_CHIP_INTERNAL, "CX23418"},
-	{AUDIO_CHIP_INTERNAL, "CX23885"},
+	{ V4L2_IDENT_AMBIGUOUS, "CX25841"   },
+	{ V4L2_IDENT_AMBIGUOUS, "CX25842"   },
+	{ V4L2_IDENT_AMBIGUOUS, "CX25843"   },
+	{ V4L2_IDENT_AMBIGUOUS, "CX23418"   },
+	{ V4L2_IDENT_AMBIGUOUS, "CX23885"   },
 	/* 40-44 */
-	{AUDIO_CHIP_INTERNAL, "CX23888"},
-	{AUDIO_CHIP_INTERNAL, "SAA7131"},
-	{AUDIO_CHIP_INTERNAL, "CX23887"},
-	{AUDIO_CHIP_INTERNAL, "SAA7164"},
-	{AUDIO_CHIP_INTERNAL, "AU8522"},
+	{ V4L2_IDENT_AMBIGUOUS, "CX23888"   },
+	{ V4L2_IDENT_AMBIGUOUS, "SAA7131"   },
+	{ V4L2_IDENT_AMBIGUOUS, "CX23887"   },
+	{ V4L2_IDENT_AMBIGUOUS, "SAA7164"   },
+	{ V4L2_IDENT_AMBIGUOUS, "AU8522"    },
 };
 
 /* This list is supplied by Hauppauge. Thanks! */
@@ -483,7 +485,7 @@
 			tvee->has_radio = eeprom_data[i+len-1];
 			/* old style tag, don't know how to detect
 			IR presence, mark as unknown. */
-			tvee->has_ir = -1;
+			tvee->has_ir = 0;
 			tvee->model =
 				eeprom_data[i+8] +
 				(eeprom_data[i+9] << 8);
@@ -509,7 +511,7 @@
 			if (audioic < ARRAY_SIZE(audioIC))
 				tvee->audio_processor = audioIC[audioic].id;
 			else
-				tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
 			break;
 
 		/* case 0x03: tag 'EEInfo' */
@@ -542,7 +544,7 @@
 			if (audioic < ARRAY_SIZE(audioIC))
 				tvee->audio_processor = audioIC[audioic].id;
 			else
-				tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
 
 			break;
 
@@ -603,7 +605,7 @@
 
 		case 0x0f:
 			/* tag 'IRInfo' */
-			tvee->has_ir = eeprom_data[i+1];
+			tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
 			break;
 
 		/* case 0x10: tag 'VBIInfo' */
@@ -690,7 +692,7 @@
 			t_fmt_name2[6], t_fmt_name2[7], t_format2);
 	if (audioic < 0) {
 		tveeprom_info("audio processor is unknown (no idx)\n");
-		tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+		tvee->audio_processor = V4L2_IDENT_UNKNOWN;
 	} else {
 		if (audioic < ARRAY_SIZE(audioIC))
 			tveeprom_info("audio processor is %s (idx %d)\n",
@@ -703,14 +705,14 @@
 		tveeprom_info("decoder processor is %s (idx %d)\n",
 			STRM(decoderIC, tvee->decoder_processor),
 			tvee->decoder_processor);
-	if (tvee->has_ir == -1)
-		tveeprom_info("has %sradio\n",
-				tvee->has_radio ? "" : "no ");
-	else
+	if (tvee->has_ir)
 		tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
 				tvee->has_radio ? "" : "no ",
-				(tvee->has_ir & 1) ? "" : "no ",
-				(tvee->has_ir & 2) ? "" : "no ");
+				(tvee->has_ir & 2) ? "" : "no ",
+				(tvee->has_ir & 4) ? "" : "no ");
+	else
+		tveeprom_info("has %sradio\n",
+				tvee->has_radio ? "" : "no ");
 }
 EXPORT_SYMBOL(tveeprom_hauppauge_analog);
 
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 6a3af10..28af5ce 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -6,7 +6,7 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <linux/video_decoder.h>
 #include <media/v4l2-common.h>
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 4128ee2..bf1bc2f 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -952,8 +952,6 @@
 	.llseek = no_llseek,
 };
 static const struct video_device usbvideo_template = {
-	.owner =      THIS_MODULE,
-	.type =       VID_TYPE_CAPTURE,
 	.fops =       &usbvideo_fops,
 };
 
@@ -1040,7 +1038,7 @@
 		err("%s: uvd->dev == NULL", __func__);
 		return -EINVAL;
 	}
-	uvd->vdev.dev = &uvd->dev->dev;
+	uvd->vdev.parent = &uvd->dev->dev;
 	if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
 		err("%s: video_register_device failed", __func__);
 		return -EPIPE;
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h
index 051775d..c66985b 100644
--- a/drivers/media/video/usbvideo/usbvideo.h
+++ b/drivers/media/video/usbvideo/usbvideo.h
@@ -18,6 +18,7 @@
 
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
 
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 40d053e..b779245 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -41,6 +41,7 @@
 #include <linux/videodev.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
@@ -791,9 +792,7 @@
 };
 
 static struct video_device vicam_template = {
-	.owner 		= THIS_MODULE,
 	.name 		= "ViCam-based USB Camera",
-	.type 		= VID_TYPE_CAPTURE,
 	.fops 		= &vicam_fops,
 	.minor 		= -1,
 };
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index abf6854..c317ed7 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -30,7 +30,6 @@
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/highmem.h>
-#include <linux/videodev.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -43,7 +42,6 @@
 #include <media/saa7115.h>
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
-#include <media/audiochip.h>
 
 #include <linux/workqueue.h>
 
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index cd6c41d..b977116 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -53,7 +53,6 @@
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/highmem.h>
-#include <linux/videodev.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -65,8 +64,8 @@
 
 #include <media/saa7115.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/tuner.h>
-#include <media/audiochip.h>
 
 #include <linux/workqueue.h>
 
@@ -184,7 +183,7 @@
 static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	return video_get_drvdata(vdev);
 }
 
@@ -199,7 +198,7 @@
 			  struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	return sprintf(buf, "%s\n",
 		       usbvision_device_data[usbvision->DevModel].ModelString);
@@ -210,7 +209,7 @@
 			struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	struct v4l2_control ctrl;
 	ctrl.id = V4L2_CID_HUE;
@@ -225,7 +224,7 @@
 			     struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	struct v4l2_control ctrl;
 	ctrl.id = V4L2_CID_CONTRAST;
@@ -240,7 +239,7 @@
 			       struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	struct v4l2_control ctrl;
 	ctrl.id = V4L2_CID_BRIGHTNESS;
@@ -255,7 +254,7 @@
 			       struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	struct v4l2_control ctrl;
 	ctrl.id = V4L2_CID_SATURATION;
@@ -270,7 +269,7 @@
 			      struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	return sprintf(buf, "%s\n",
 		       YES_NO(usbvision->streaming==Stream_On?1:0));
@@ -281,7 +280,7 @@
 				struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	return sprintf(buf, "%s\n",
 		       YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
@@ -292,7 +291,7 @@
 				  struct device_attribute *attr, char *buf)
 {
 	struct video_device *vdev =
-		container_of(cd, struct video_device, class_dev);
+		container_of(cd, struct video_device, dev);
 	struct usb_usbvision *usbvision = video_get_drvdata(vdev);
 	return sprintf(buf, "%d\n", usbvision->bridgeType);
 }
@@ -304,40 +303,31 @@
 	if (!vdev)
 		return;
 	do {
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_version);
+		res = device_create_file(&vdev->dev, &dev_attr_version);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_model);
+		res = device_create_file(&vdev->dev, &dev_attr_model);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_hue);
+		res = device_create_file(&vdev->dev, &dev_attr_hue);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_contrast);
+		res = device_create_file(&vdev->dev, &dev_attr_contrast);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_brightness);
+		res = device_create_file(&vdev->dev, &dev_attr_brightness);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_saturation);
+		res = device_create_file(&vdev->dev, &dev_attr_saturation);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_streaming);
+		res = device_create_file(&vdev->dev, &dev_attr_streaming);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_compression);
+		res = device_create_file(&vdev->dev, &dev_attr_compression);
 		if (res<0)
 			break;
-		res = device_create_file(&vdev->class_dev,
-					 &dev_attr_bridge);
+		res = device_create_file(&vdev->dev, &dev_attr_bridge);
 		if (res>=0)
 			return;
 	} while (0);
@@ -348,24 +338,15 @@
 static void usbvision_remove_sysfs(struct video_device *vdev)
 {
 	if (vdev) {
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_version);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_model);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_hue);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_contrast);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_brightness);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_saturation);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_streaming);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_compression);
-		device_remove_file(&vdev->class_dev,
-					 &dev_attr_bridge);
+		device_remove_file(&vdev->dev, &dev_attr_version);
+		device_remove_file(&vdev->dev, &dev_attr_model);
+		device_remove_file(&vdev->dev, &dev_attr_hue);
+		device_remove_file(&vdev->dev, &dev_attr_contrast);
+		device_remove_file(&vdev->dev, &dev_attr_brightness);
+		device_remove_file(&vdev->dev, &dev_attr_saturation);
+		device_remove_file(&vdev->dev, &dev_attr_streaming);
+		device_remove_file(&vdev->dev, &dev_attr_compression);
+		device_remove_file(&vdev->dev, &dev_attr_bridge);
 	}
 }
 
@@ -1388,13 +1369,8 @@
 /* 	.poll          = video_poll, */
 	.compat_ioctl  = v4l_compat_ioctl32,
 };
-static struct video_device usbvision_video_template = {
-	.owner             = THIS_MODULE,
-	.type		= VID_TYPE_TUNER | VID_TYPE_CAPTURE,
-	.fops		= &usbvision_fops,
-	.name           = "usbvision-video",
-	.release	= video_device_release,
-	.minor		= -1,
+
+static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1426,6 +1402,14 @@
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
 #endif
+};
+
+static struct video_device usbvision_video_template = {
+	.fops		= &usbvision_fops,
+	.ioctl_ops 	= &usbvision_ioctl_ops,
+	.name           = "usbvision-video",
+	.release	= video_device_release,
+	.minor		= -1,
 	.tvnorms              = USBVISION_NORMS,
 	.current_norm         = V4L2_STD_PAL
 };
@@ -1441,14 +1425,7 @@
 	.compat_ioctl  = v4l_compat_ioctl32,
 };
 
-static struct video_device usbvision_radio_template=
-{
-	.owner             = THIS_MODULE,
-	.type		= VID_TYPE_TUNER,
-	.fops		= &usbvision_radio_fops,
-	.name           = "usbvision-radio",
-	.release	= video_device_release,
-	.minor		= -1,
+static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
@@ -1462,6 +1439,14 @@
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
+};
+
+static struct video_device usbvision_radio_template = {
+	.fops		= &usbvision_radio_fops,
+	.name           = "usbvision-radio",
+	.release	= video_device_release,
+	.minor		= -1,
+	.ioctl_ops 	= &usbvision_radio_ioctl_ops,
 
 	.tvnorms              = USBVISION_NORMS,
 	.current_norm         = V4L2_STD_PAL
@@ -1479,8 +1464,6 @@
 
 static struct video_device usbvision_vbi_template=
 {
-	.owner             = THIS_MODULE,
-	.type		= VID_TYPE_TUNER,
 	.fops		= &usbvision_vbi_fops,
 	.release	= video_device_release,
 	.name           = "usbvision-vbi",
@@ -1506,7 +1489,7 @@
 	}
 	*vdev = *vdev_template;
 //	vdev->minor   = -1;
-	vdev->dev     = &usb_dev->dev;
+	vdev->parent  = &usb_dev->dev;
 	snprintf(vdev->name, sizeof(vdev->name), "%s", name);
 	video_set_drvdata(vdev, usbvision);
 	return vdev;
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 3ae9551..626f4ad 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -195,8 +195,8 @@
 };
 
 static struct uvc_menu_info exposure_auto_controls[] = {
-	{ 1, "Manual Mode" },
 	{ 2, "Auto Mode" },
+	{ 1, "Manual Mode" },
 	{ 4, "Shutter Priority Mode" },
 	{ 8, "Aperture Priority Mode" },
 };
@@ -592,6 +592,7 @@
 	if (ctrl == NULL)
 		return -EINVAL;
 
+	memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
 	v4l2_ctrl->id = mapping->id;
 	v4l2_ctrl->type = mapping->v4l2_type;
 	strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
@@ -608,7 +609,8 @@
 		v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
 	}
 
-	if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+	switch (mapping->v4l2_type) {
+	case V4L2_CTRL_TYPE_MENU:
 		v4l2_ctrl->minimum = 0;
 		v4l2_ctrl->maximum = mapping->menu_count - 1;
 		v4l2_ctrl->step = 1;
@@ -622,6 +624,15 @@
 		}
 
 		return 0;
+
+	case V4L2_CTRL_TYPE_BOOLEAN:
+		v4l2_ctrl->minimum = 0;
+		v4l2_ctrl->maximum = 1;
+		v4l2_ctrl->step = 1;
+		return 0;
+
+	default:
+		break;
 	}
 
 	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index f2b2983..b3c4d75 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1458,9 +1458,7 @@
 	 * unregistered before the reference is released, so we don't need to
 	 * get another one.
 	 */
-	vdev->dev = &dev->intf->dev;
-	vdev->type = 0;
-	vdev->type2 = 0;
+	vdev->parent = &dev->intf->dev;
 	vdev->minor = -1;
 	vdev->fops = &uvc_fops;
 	vdev->release = video_device_release;
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index b5a11eb..d7bd71b 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -23,6 +23,7 @@
 #include <asm/atomic.h>
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include "uvcvideo.h"
 
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index a0f6c60..79937d1 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index e9dd996..88ca131 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -64,7 +64,7 @@
 #include <linux/kmod.h>
 #endif
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 
 MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
 MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
new file mode 100644
index 0000000..556615f
--- /dev/null
+++ b/drivers/media/video/v4l2-dev.c
@@ -0,0 +1,422 @@
+/*
+ * Video capture interface for Linux version 2
+ *
+ *	A generic video device interface for the LINUX operating system
+ *	using a set of device structures/vectors for low level operations.
+ *
+ *	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.
+ *
+ * Authors:	Alan Cox, <alan@redhat.com> (version 1)
+ *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
+ *
+ * Fixes:	20000516  Claudio Matsuoka <claudio@conectiva.com>
+ *		- Added procfs support
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <media/v4l2-common.h>
+
+#define VIDEO_NUM_DEVICES	256
+#define VIDEO_NAME              "video4linux"
+
+/*
+ *	sysfs stuff
+ */
+
+static ssize_t show_index(struct device *cd,
+			 struct device_attribute *attr, char *buf)
+{
+	struct video_device *vfd = container_of(cd, struct video_device, dev);
+	return sprintf(buf, "%i\n", vfd->index);
+}
+
+static ssize_t show_name(struct device *cd,
+			 struct device_attribute *attr, char *buf)
+{
+	struct video_device *vfd = container_of(cd, struct video_device, dev);
+	return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
+}
+
+static struct device_attribute video_device_attrs[] = {
+	__ATTR(name, S_IRUGO, show_name, NULL),
+	__ATTR(index, S_IRUGO, show_index, NULL),
+	__ATTR_NULL
+};
+
+struct video_device *video_device_alloc(void)
+{
+	struct video_device *vfd;
+
+	vfd = kzalloc(sizeof(*vfd), GFP_KERNEL);
+	return vfd;
+}
+EXPORT_SYMBOL(video_device_alloc);
+
+void video_device_release(struct video_device *vfd)
+{
+	kfree(vfd);
+}
+EXPORT_SYMBOL(video_device_release);
+
+static void video_release(struct device *cd)
+{
+	struct video_device *vfd = container_of(cd, struct video_device, dev);
+
+#if 1
+	/* needed until all drivers are fixed */
+	if (!vfd->release)
+		return;
+#endif
+	vfd->release(vfd);
+}
+
+static struct class video_class = {
+	.name = VIDEO_NAME,
+	.dev_attrs = video_device_attrs,
+	.dev_release = video_release,
+};
+
+/*
+ *	Active devices
+ */
+
+static struct video_device *video_device[VIDEO_NUM_DEVICES];
+static DEFINE_MUTEX(videodev_lock);
+
+struct video_device *video_devdata(struct file *file)
+{
+	return video_device[iminor(file->f_path.dentry->d_inode)];
+}
+EXPORT_SYMBOL(video_devdata);
+
+/*
+ *	Open a video device - FIXME: Obsoleted
+ */
+static int video_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = iminor(inode);
+	int err = 0;
+	struct video_device *vfl;
+	const struct file_operations *old_fops;
+
+	if (minor >= VIDEO_NUM_DEVICES)
+		return -ENODEV;
+	lock_kernel();
+	mutex_lock(&videodev_lock);
+	vfl = video_device[minor];
+	if (vfl == NULL) {
+		mutex_unlock(&videodev_lock);
+		request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
+		mutex_lock(&videodev_lock);
+		vfl = video_device[minor];
+		if (vfl == NULL) {
+			mutex_unlock(&videodev_lock);
+			unlock_kernel();
+			return -ENODEV;
+		}
+	}
+	old_fops = file->f_op;
+	file->f_op = fops_get(vfl->fops);
+	if (file->f_op->open)
+		err = file->f_op->open(inode, file);
+	if (err) {
+		fops_put(file->f_op);
+		file->f_op = fops_get(old_fops);
+	}
+	fops_put(old_fops);
+	mutex_unlock(&videodev_lock);
+	unlock_kernel();
+	return err;
+}
+
+/*
+ * open/release helper functions -- handle exclusive opens
+ * Should be removed soon
+ */
+int video_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct video_device *vfl = video_devdata(file);
+	int retval = 0;
+
+	mutex_lock(&vfl->lock);
+	if (vfl->users)
+		retval = -EBUSY;
+	else
+		vfl->users++;
+	mutex_unlock(&vfl->lock);
+	return retval;
+}
+EXPORT_SYMBOL(video_exclusive_open);
+
+int video_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct video_device *vfl = video_devdata(file);
+
+	vfl->users--;
+	return 0;
+}
+EXPORT_SYMBOL(video_exclusive_release);
+
+/**
+ * get_index - assign stream number based on parent device
+ * @vdev: video_device to assign index number to, vdev->dev should be assigned
+ * @num: -1 if auto assign, requested number otherwise
+ *
+ *
+ * returns -ENFILE if num is already in use, a free index number if
+ * successful.
+ */
+static int get_index(struct video_device *vdev, int num)
+{
+	u32 used = 0;
+	const int max_index = sizeof(used) * 8 - 1;
+	int i;
+
+	/* Currently a single v4l driver instance cannot create more than
+	   32 devices.
+	   Increase to u64 or an array of u32 if more are needed. */
+	if (num > max_index) {
+		printk(KERN_ERR "videodev: %s num is too large\n", __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
+		if (video_device[i] != NULL &&
+		    video_device[i] != vdev &&
+		    video_device[i]->parent == vdev->parent) {
+			used |= 1 << video_device[i]->index;
+		}
+	}
+
+	if (num >= 0) {
+		if (used & (1 << num))
+			return -ENFILE;
+		return num;
+	}
+
+	i = ffz(used);
+	return i > max_index ? -ENFILE : i;
+}
+
+static const struct file_operations video_fops;
+
+int video_register_device(struct video_device *vfd, int type, int nr)
+{
+	return video_register_device_index(vfd, type, nr, -1);
+}
+EXPORT_SYMBOL(video_register_device);
+
+/**
+ *	video_register_device - register video4linux devices
+ *	@vfd:  video device structure we want to register
+ *	@type: type of device to register
+ *	@nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
+ *             -1 == first free)
+ *
+ *	The registration code assigns minor numbers based on the type
+ *	requested. -ENFILE is returned in all the device slots for this
+ *	category are full. If not then the minor field is set and the
+ *	driver initialize function is called (if non %NULL).
+ *
+ *	Zero is returned on success.
+ *
+ *	Valid types are
+ *
+ *	%VFL_TYPE_GRABBER - A frame grabber
+ *
+ *	%VFL_TYPE_VTX - A teletext device
+ *
+ *	%VFL_TYPE_VBI - Vertical blank data (undecoded)
+ *
+ *	%VFL_TYPE_RADIO - A radio card
+ */
+
+int video_register_device_index(struct video_device *vfd, int type, int nr,
+					int index)
+{
+	int i = 0;
+	int base;
+	int end;
+	int ret;
+	char *name_base;
+
+	switch (type) {
+	case VFL_TYPE_GRABBER:
+		base = MINOR_VFL_TYPE_GRABBER_MIN;
+		end = MINOR_VFL_TYPE_GRABBER_MAX+1;
+		name_base = "video";
+		break;
+	case VFL_TYPE_VTX:
+		base = MINOR_VFL_TYPE_VTX_MIN;
+		end = MINOR_VFL_TYPE_VTX_MAX+1;
+		name_base = "vtx";
+		break;
+	case VFL_TYPE_VBI:
+		base = MINOR_VFL_TYPE_VBI_MIN;
+		end = MINOR_VFL_TYPE_VBI_MAX+1;
+		name_base = "vbi";
+		break;
+	case VFL_TYPE_RADIO:
+		base = MINOR_VFL_TYPE_RADIO_MIN;
+		end = MINOR_VFL_TYPE_RADIO_MAX+1;
+		name_base = "radio";
+		break;
+	default:
+		printk(KERN_ERR "%s called with unknown type: %d\n",
+		       __func__, type);
+		return -1;
+	}
+
+	/* pick a minor number */
+	mutex_lock(&videodev_lock);
+	if (nr >= 0  &&  nr < end-base) {
+		/* use the one the driver asked for */
+		i = base + nr;
+		if (NULL != video_device[i]) {
+			mutex_unlock(&videodev_lock);
+			return -ENFILE;
+		}
+	} else {
+		/* use first free */
+		for (i = base; i < end; i++)
+			if (NULL == video_device[i])
+				break;
+		if (i == end) {
+			mutex_unlock(&videodev_lock);
+			return -ENFILE;
+		}
+	}
+	video_device[i] = vfd;
+	vfd->vfl_type = type;
+	vfd->minor = i;
+
+	ret = get_index(vfd, index);
+	vfd->index = ret;
+
+	mutex_unlock(&videodev_lock);
+
+	if (ret < 0) {
+		printk(KERN_ERR "%s: get_index failed\n", __func__);
+		goto fail_minor;
+	}
+
+	mutex_init(&vfd->lock);
+
+	/* sysfs class */
+	memset(&vfd->dev, 0x00, sizeof(vfd->dev));
+	vfd->dev.class = &video_class;
+	vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
+	if (vfd->parent)
+		vfd->dev.parent = vfd->parent;
+	sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base);
+	ret = device_register(&vfd->dev);
+	if (ret < 0) {
+		printk(KERN_ERR "%s: device_register failed\n", __func__);
+		goto fail_minor;
+	}
+
+#if 1
+	/* needed until all drivers are fixed */
+	if (!vfd->release)
+		printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
+		       "Please fix your driver for proper sysfs support, see "
+		       "http://lwn.net/Articles/36850/\n", vfd->name);
+#endif
+	return 0;
+
+fail_minor:
+	mutex_lock(&videodev_lock);
+	video_device[vfd->minor] = NULL;
+	vfd->minor = -1;
+	mutex_unlock(&videodev_lock);
+	return ret;
+}
+EXPORT_SYMBOL(video_register_device_index);
+
+/**
+ *	video_unregister_device - unregister a video4linux device
+ *	@vfd: the device to unregister
+ *
+ *	This unregisters the passed device and deassigns the minor
+ *	number. Future open calls will be met with errors.
+ */
+
+void video_unregister_device(struct video_device *vfd)
+{
+	mutex_lock(&videodev_lock);
+	if (video_device[vfd->minor] != vfd)
+		panic("videodev: bad unregister");
+
+	video_device[vfd->minor] = NULL;
+	device_unregister(&vfd->dev);
+	mutex_unlock(&videodev_lock);
+}
+EXPORT_SYMBOL(video_unregister_device);
+
+/*
+ * Video fs operations
+ */
+static const struct file_operations video_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= video_open,
+};
+
+/*
+ *	Initialise video for linux
+ */
+
+static int __init videodev_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Linux video capture interface: v2.00\n");
+	if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
+		printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
+		return -EIO;
+	}
+
+	ret = class_register(&video_class);
+	if (ret < 0) {
+		unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
+		printk(KERN_WARNING "video_dev: class_register failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit videodev_exit(void)
+{
+	class_unregister(&video_class);
+	unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
+}
+
+module_init(videodev_init)
+module_exit(videodev_exit)
+
+MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
new file mode 100644
index 0000000..fdfe773
--- /dev/null
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -0,0 +1,1875 @@
+/*
+ * Video capture interface for Linux version 2
+ *
+ * A generic framework to process V4L2 ioctl commands.
+ *
+ * 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.
+ *
+ * Authors:	Alan Cox, <alan@redhat.com> (version 1)
+ *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#define __OLD_VIDIOC_ /* To allow fixing old calls */
+#include <linux/videodev2.h>
+
+#ifdef CONFIG_VIDEO_V4L1
+#include <linux/videodev.h>
+#endif
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/video_decoder.h>
+
+#define dbgarg(cmd, fmt, arg...) \
+		do {							\
+		    if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {		\
+			printk(KERN_DEBUG "%s: ",  vfd->name);		\
+			v4l_printk_ioctl(cmd);				\
+			printk(" " fmt,  ## arg);			\
+		    }							\
+		} while (0)
+
+#define dbgarg2(fmt, arg...) \
+		do {							\
+		    if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)		\
+			printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
+		} while (0)
+
+struct std_descr {
+	v4l2_std_id std;
+	const char *descr;
+};
+
+static const struct std_descr standards[] = {
+	{ V4L2_STD_NTSC, 	"NTSC"      },
+	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
+	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
+	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
+	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
+	{ V4L2_STD_PAL, 	"PAL"       },
+	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
+	{ V4L2_STD_PAL_B, 	"PAL-B"     },
+	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
+	{ V4L2_STD_PAL_G, 	"PAL-G"     },
+	{ V4L2_STD_PAL_H, 	"PAL-H"     },
+	{ V4L2_STD_PAL_I, 	"PAL-I"     },
+	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
+	{ V4L2_STD_PAL_D, 	"PAL-D"     },
+	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
+	{ V4L2_STD_PAL_K, 	"PAL-K"     },
+	{ V4L2_STD_PAL_M, 	"PAL-M"     },
+	{ V4L2_STD_PAL_N, 	"PAL-N"     },
+	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
+	{ V4L2_STD_PAL_60, 	"PAL-60"    },
+	{ V4L2_STD_SECAM, 	"SECAM"     },
+	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
+	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
+	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
+	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
+	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
+	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
+	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
+	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
+	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
+	{ 0, 			"Unknown"   }
+};
+
+/* video4linux standard ID conversion to standard name
+ */
+const char *v4l2_norm_to_name(v4l2_std_id id)
+{
+	u32 myid = id;
+	int i;
+
+	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
+	   64 bit comparations. So, on that architecture, with some gcc
+	   variants, compilation fails. Currently, the max value is 30bit wide.
+	 */
+	BUG_ON(myid != id);
+
+	for (i = 0; standards[i].std; i++)
+		if (myid == standards[i].std)
+			break;
+	return standards[i].descr;
+}
+EXPORT_SYMBOL(v4l2_norm_to_name);
+
+/* Fill in the fields of a v4l2_standard structure according to the
+   'id' and 'transmission' parameters.  Returns negative on error.  */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+			     int id, const char *name)
+{
+	u32 index = vs->index;
+
+	memset(vs, 0, sizeof(struct v4l2_standard));
+	vs->index = index;
+	vs->id    = id;
+	if (id & V4L2_STD_525_60) {
+		vs->frameperiod.numerator = 1001;
+		vs->frameperiod.denominator = 30000;
+		vs->framelines = 525;
+	} else {
+		vs->frameperiod.numerator = 1;
+		vs->frameperiod.denominator = 25;
+		vs->framelines = 625;
+	}
+	strlcpy(vs->name, name, sizeof(vs->name));
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_video_std_construct);
+
+/* ----------------------------------------------------------------- */
+/* some arrays for pretty-printing debug messages of enum types      */
+
+const char *v4l2_field_names[] = {
+	[V4L2_FIELD_ANY]        = "any",
+	[V4L2_FIELD_NONE]       = "none",
+	[V4L2_FIELD_TOP]        = "top",
+	[V4L2_FIELD_BOTTOM]     = "bottom",
+	[V4L2_FIELD_INTERLACED] = "interlaced",
+	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
+	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
+	[V4L2_FIELD_ALTERNATE]  = "alternate",
+	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+};
+EXPORT_SYMBOL(v4l2_field_names);
+
+const char *v4l2_type_names[] = {
+	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
+	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
+	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
+	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
+	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
+	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
+	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
+	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
+};
+EXPORT_SYMBOL(v4l2_type_names);
+
+static const char *v4l2_memory_names[] = {
+	[V4L2_MEMORY_MMAP]    = "mmap",
+	[V4L2_MEMORY_USERPTR] = "userptr",
+	[V4L2_MEMORY_OVERLAY] = "overlay",
+};
+
+#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
+			   arr[a] : "unknown")
+
+/* ------------------------------------------------------------------ */
+/* debug help functions                                               */
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static const char *v4l1_ioctls[] = {
+	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
+	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
+	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
+	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
+	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
+	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
+	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
+	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
+	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
+	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
+	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
+	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
+	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
+	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
+	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
+	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
+	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
+	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
+	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
+	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
+	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
+	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
+	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
+	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
+	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
+	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
+	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
+};
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+#endif
+
+static const char *v4l2_ioctls[] = {
+	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
+	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
+	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
+	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
+	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
+	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
+	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
+	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
+	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
+	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
+	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
+	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
+	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
+	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
+	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
+	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
+	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
+	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
+	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
+	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
+	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
+	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
+	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
+	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
+	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
+	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
+	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
+	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
+	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
+	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
+	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
+	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
+	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
+	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
+	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
+	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
+	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
+	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
+	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
+	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
+	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
+	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
+	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
+	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
+	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
+	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
+	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
+	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
+	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
+	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
+	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
+	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
+	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
+	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
+#if 1
+	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
+	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
+	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
+	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
+
+	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
+	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
+
+	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
+	[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)]   = "VIDIOC_S_HW_FREQ_SEEK",
+#endif
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+static const char *v4l2_int_ioctls[] = {
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
+	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
+	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
+	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
+	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
+	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
+	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
+	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
+	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
+	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
+	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
+#endif
+	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
+
+	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
+	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
+	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
+
+	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
+	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
+	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
+	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
+	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
+	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
+	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
+	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
+	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
+	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
+};
+#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+
+/* Common ioctl debug function. This function can be used by
+   external ioctl messages as well as internal V4L ioctl */
+void v4l_printk_ioctl(unsigned int cmd)
+{
+	char *dir, *type;
+
+	switch (_IOC_TYPE(cmd)) {
+	case 'd':
+		if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
+			type = "v4l2_int";
+			break;
+		}
+		printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
+		return;
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	case 'v':
+		if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
+			type = "v4l1";
+			break;
+		}
+		printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
+		return;
+#endif
+	case 'V':
+		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
+			type = "v4l2";
+			break;
+		}
+		printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
+		return;
+	default:
+		type = "unknown";
+	}
+
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:              dir = "--"; break;
+	case _IOC_READ:              dir = "r-"; break;
+	case _IOC_WRITE:             dir = "-w"; break;
+	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+	default:                     dir = "*ERR*"; break;
+	}
+	printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
+		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+}
+EXPORT_SYMBOL(v4l_printk_ioctl);
+
+/*
+ * helper function -- handles userspace copying for ioctl arguments
+ */
+
+#ifdef __OLD_VIDIOC_
+static unsigned int
+video_fix_command(unsigned int cmd)
+{
+	switch (cmd) {
+	case VIDIOC_OVERLAY_OLD:
+		cmd = VIDIOC_OVERLAY;
+		break;
+	case VIDIOC_S_PARM_OLD:
+		cmd = VIDIOC_S_PARM;
+		break;
+	case VIDIOC_S_CTRL_OLD:
+		cmd = VIDIOC_S_CTRL;
+		break;
+	case VIDIOC_G_AUDIO_OLD:
+		cmd = VIDIOC_G_AUDIO;
+		break;
+	case VIDIOC_G_AUDOUT_OLD:
+		cmd = VIDIOC_G_AUDOUT;
+		break;
+	case VIDIOC_CROPCAP_OLD:
+		cmd = VIDIOC_CROPCAP;
+		break;
+	}
+	return cmd;
+}
+#endif
+
+/*
+ * Obsolete usercopy function - Should be removed soon
+ */
+int
+video_usercopy(struct inode *inode, struct file *file,
+	       unsigned int cmd, unsigned long arg,
+	       int (*func)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg))
+{
+	char	sbuf[128];
+	void    *mbuf = NULL;
+	void	*parg = NULL;
+	int	err  = -EINVAL;
+	int     is_ext_ctrl;
+	size_t  ctrls_size = 0;
+	void __user *user_ptr = NULL;
+
+#ifdef __OLD_VIDIOC_
+	cmd = video_fix_command(cmd);
+#endif
+	is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
+		       cmd == VIDIOC_TRY_EXT_CTRLS);
+
+	/*  Copy arguments into temp kernel buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:
+		parg = NULL;
+		break;
+	case _IOC_READ:
+	case _IOC_WRITE:
+	case (_IOC_WRITE | _IOC_READ):
+		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+			parg = sbuf;
+		} else {
+			/* too big to allocate from stack */
+			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+			if (NULL == mbuf)
+				return -ENOMEM;
+			parg = mbuf;
+		}
+
+		err = -EFAULT;
+		if (_IOC_DIR(cmd) & _IOC_WRITE)
+			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+				goto out;
+		break;
+	}
+	if (is_ext_ctrl) {
+		struct v4l2_ext_controls *p = parg;
+
+		/* In case of an error, tell the caller that it wasn't
+		   a specific control that caused it. */
+		p->error_idx = p->count;
+		user_ptr = (void __user *)p->controls;
+		if (p->count) {
+			ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
+			/* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
+			mbuf = kmalloc(ctrls_size, GFP_KERNEL);
+			err = -ENOMEM;
+			if (NULL == mbuf)
+				goto out_ext_ctrl;
+			err = -EFAULT;
+			if (copy_from_user(mbuf, user_ptr, ctrls_size))
+				goto out_ext_ctrl;
+			p->controls = mbuf;
+		}
+	}
+
+	/* call driver */
+	err = func(inode, file, cmd, parg);
+	if (err == -ENOIOCTLCMD)
+		err = -EINVAL;
+	if (is_ext_ctrl) {
+		struct v4l2_ext_controls *p = parg;
+
+		p->controls = (void *)user_ptr;
+		if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
+			err = -EFAULT;
+		goto out_ext_ctrl;
+	}
+	if (err < 0)
+		goto out;
+
+out_ext_ctrl:
+	/*  Copy results into user buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_READ:
+	case (_IOC_WRITE | _IOC_READ):
+		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+			err = -EFAULT;
+		break;
+	}
+
+out:
+	kfree(mbuf);
+	return err;
+}
+EXPORT_SYMBOL(video_usercopy);
+
+static void dbgbuf(unsigned int cmd, struct video_device *vfd,
+					struct v4l2_buffer *p)
+{
+	struct v4l2_timecode *tc = &p->timecode;
+
+	dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
+		"bytesused=%d, flags=0x%08d, "
+		"field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
+			p->timestamp.tv_sec / 3600,
+			(int)(p->timestamp.tv_sec / 60) % 60,
+			(int)(p->timestamp.tv_sec % 60),
+			p->timestamp.tv_usec,
+			p->index,
+			prt_names(p->type, v4l2_type_names),
+			p->bytesused, p->flags,
+			p->field, p->sequence,
+			prt_names(p->memory, v4l2_memory_names),
+			p->m.userptr, p->length);
+	dbgarg2("timecode=%02d:%02d:%02d type=%d, "
+		"flags=0x%08d, frames=%d, userbits=0x%08x\n",
+			tc->hours, tc->minutes, tc->seconds,
+			tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
+}
+
+static inline void dbgrect(struct video_device *vfd, char *s,
+							struct v4l2_rect *r)
+{
+	dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
+						r->width, r->height);
+};
+
+static inline void v4l_print_pix_fmt(struct video_device *vfd,
+						struct v4l2_pix_format *fmt)
+{
+	dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
+		"bytesperline=%d sizeimage=%d, colorspace=%d\n",
+		fmt->width, fmt->height,
+		(fmt->pixelformat & 0xff),
+		(fmt->pixelformat >>  8) & 0xff,
+		(fmt->pixelformat >> 16) & 0xff,
+		(fmt->pixelformat >> 24) & 0xff,
+		prt_names(fmt->field, v4l2_field_names),
+		fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
+};
+
+static inline void v4l_print_ext_ctrls(unsigned int cmd,
+	struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
+{
+	__u32 i;
+
+	if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
+		return;
+	dbgarg(cmd, "");
+	printk(KERN_CONT "class=0x%x", c->ctrl_class);
+	for (i = 0; i < c->count; i++) {
+		if (show_vals)
+			printk(KERN_CONT " id/val=0x%x/0x%x",
+				c->controls[i].id, c->controls[i].value);
+		else
+			printk(KERN_CONT " id=0x%x", c->controls[i].id);
+	}
+	printk(KERN_CONT "\n");
+};
+
+static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
+{
+	__u32 i;
+
+	/* zero the reserved fields */
+	c->reserved[0] = c->reserved[1] = 0;
+	for (i = 0; i < c->count; i++) {
+		c->controls[i].reserved2[0] = 0;
+		c->controls[i].reserved2[1] = 0;
+	}
+	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
+	   when using extended controls.
+	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
+	   is it allowed for backwards compatibility.
+	 */
+	if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
+		return 0;
+	/* Check that all controls are from the same control class. */
+	for (i = 0; i < c->count; i++) {
+		if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
+			c->error_idx = i;
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
+{
+	if (ops == NULL)
+		return -EINVAL;
+
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (ops->vidioc_try_fmt_vid_cap)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		if (ops->vidioc_try_fmt_vid_overlay)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		if (ops->vidioc_try_fmt_vid_out)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+		if (ops->vidioc_try_fmt_vid_out_overlay)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		if (ops->vidioc_try_fmt_vbi_cap)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_VBI_OUTPUT:
+		if (ops->vidioc_try_fmt_vbi_out)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+		if (ops->vidioc_try_fmt_sliced_vbi_cap)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+		if (ops->vidioc_try_fmt_sliced_vbi_out)
+			return 0;
+		break;
+	case V4L2_BUF_TYPE_PRIVATE:
+		if (ops->vidioc_try_fmt_type_private)
+			return 0;
+		break;
+	}
+	return -EINVAL;
+}
+
+static int __video_do_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, void *arg)
+{
+	struct video_device *vfd = video_devdata(file);
+	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
+	void                 *fh = file->private_data;
+	int                  ret = -EINVAL;
+
+	if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
+				!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
+		v4l_print_ioctl(vfd->name, cmd);
+		printk(KERN_CONT "\n");
+	}
+
+	if (ops == NULL) {
+		printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
+				vfd->name);
+		return -EINVAL;
+	}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	/***********************************************************
+	 Handles calls to the obsoleted V4L1 API
+	 Due to the nature of VIDIOCGMBUF, each driver that supports
+	 V4L1 should implement its own handler for this ioctl.
+	 ***********************************************************/
+
+	/* --- streaming capture ------------------------------------- */
+	if (cmd == VIDIOCGMBUF) {
+		struct video_mbuf *p = arg;
+
+		memset(p, 0, sizeof(*p));
+
+		if (!ops->vidiocgmbuf)
+			return ret;
+		ret = ops->vidiocgmbuf(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+						p->size, p->frames,
+						(unsigned long)p->offsets);
+		return ret;
+	}
+
+	/********************************************************
+	 All other V4L1 calls are handled by v4l1_compat module.
+	 Those calls will be translated into V4L2 calls, and
+	 __video_do_ioctl will be called again, with one or more
+	 V4L2 ioctls.
+	 ********************************************************/
+	if (_IOC_TYPE(cmd) == 'v')
+		return v4l_compat_translate_ioctl(inode, file, cmd, arg,
+						__video_do_ioctl);
+#endif
+
+	switch (cmd) {
+	/* --- capabilities ------------------------------------------ */
+	case VIDIOC_QUERYCAP:
+	{
+		struct v4l2_capability *cap = (struct v4l2_capability *)arg;
+		memset(cap, 0, sizeof(*cap));
+
+		if (!ops->vidioc_querycap)
+			break;
+
+		ret = ops->vidioc_querycap(file, fh, cap);
+		if (!ret)
+			dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
+					"version=0x%08x, "
+					"capabilities=0x%08x\n",
+					cap->driver, cap->card, cap->bus_info,
+					cap->version,
+					cap->capabilities);
+		break;
+	}
+
+	/* --- priority ------------------------------------------ */
+	case VIDIOC_G_PRIORITY:
+	{
+		enum v4l2_priority *p = arg;
+
+		if (!ops->vidioc_g_priority)
+			break;
+		ret = ops->vidioc_g_priority(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "priority is %d\n", *p);
+		break;
+	}
+	case VIDIOC_S_PRIORITY:
+	{
+		enum v4l2_priority *p = arg;
+
+		if (!ops->vidioc_s_priority)
+			break;
+		dbgarg(cmd, "setting priority to %d\n", *p);
+		ret = ops->vidioc_s_priority(file, fh, *p);
+		break;
+	}
+
+	/* --- capture ioctls ---------------------------------------- */
+	case VIDIOC_ENUM_FMT:
+	{
+		struct v4l2_fmtdesc *f = arg;
+		enum v4l2_buf_type type;
+		unsigned int index;
+
+		index = f->index;
+		type  = f->type;
+		memset(f, 0, sizeof(*f));
+		f->index = index;
+		f->type  = type;
+
+		switch (type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			if (ops->vidioc_enum_fmt_vid_cap)
+				ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (ops->vidioc_enum_fmt_vid_overlay)
+				ret = ops->vidioc_enum_fmt_vid_overlay(file,
+					fh, f);
+			break;
+#if 1
+		/* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
+		 * according to the spec. The bttv and saa7134 drivers support
+		 * it though, so just warn that this is deprecated and will be
+		 * removed in the near future. */
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			if (ops->vidioc_enum_fmt_vbi_cap) {
+				printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
+				ret = ops->vidioc_enum_fmt_vbi_cap(file, fh, f);
+			}
+			break;
+#endif
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			if (ops->vidioc_enum_fmt_vid_out)
+				ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_PRIVATE:
+			if (ops->vidioc_enum_fmt_type_private)
+				ret = ops->vidioc_enum_fmt_type_private(file,
+								fh, f);
+			break;
+		default:
+			break;
+		}
+		if (!ret)
+			dbgarg(cmd, "index=%d, type=%d, flags=%d, "
+				"pixelformat=%c%c%c%c, description='%s'\n",
+				f->index, f->type, f->flags,
+				(f->pixelformat & 0xff),
+				(f->pixelformat >>  8) & 0xff,
+				(f->pixelformat >> 16) & 0xff,
+				(f->pixelformat >> 24) & 0xff,
+				f->description);
+		break;
+	}
+	case VIDIOC_G_FMT:
+	{
+		struct v4l2_format *f = (struct v4l2_format *)arg;
+
+		memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
+
+		/* FIXME: Should be one dump per type */
+		dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			if (ops->vidioc_g_fmt_vid_cap)
+				ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
+			if (!ret)
+				v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (ops->vidioc_g_fmt_vid_overlay)
+				ret = ops->vidioc_g_fmt_vid_overlay(file,
+								    fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			if (ops->vidioc_g_fmt_vid_out)
+				ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
+			if (!ret)
+				v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+			if (ops->vidioc_g_fmt_vid_out_overlay)
+				ret = ops->vidioc_g_fmt_vid_out_overlay(file,
+				       fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			if (ops->vidioc_g_fmt_vbi_cap)
+				ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_OUTPUT:
+			if (ops->vidioc_g_fmt_vbi_out)
+				ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+			if (ops->vidioc_g_fmt_sliced_vbi_cap)
+				ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
+									fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+			if (ops->vidioc_g_fmt_sliced_vbi_out)
+				ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
+									fh, f);
+			break;
+		case V4L2_BUF_TYPE_PRIVATE:
+			if (ops->vidioc_g_fmt_type_private)
+				ret = ops->vidioc_g_fmt_type_private(file,
+								fh, f);
+			break;
+		}
+
+		break;
+	}
+	case VIDIOC_S_FMT:
+	{
+		struct v4l2_format *f = (struct v4l2_format *)arg;
+
+		/* FIXME: Should be one dump per type */
+		dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
+
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			if (ops->vidioc_s_fmt_vid_cap)
+				ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (ops->vidioc_s_fmt_vid_overlay)
+				ret = ops->vidioc_s_fmt_vid_overlay(file,
+								    fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			if (ops->vidioc_s_fmt_vid_out)
+				ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+			if (ops->vidioc_s_fmt_vid_out_overlay)
+				ret = ops->vidioc_s_fmt_vid_out_overlay(file,
+					fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			if (ops->vidioc_s_fmt_vbi_cap)
+				ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_OUTPUT:
+			if (ops->vidioc_s_fmt_vbi_out)
+				ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+			if (ops->vidioc_s_fmt_sliced_vbi_cap)
+				ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
+									fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+			if (ops->vidioc_s_fmt_sliced_vbi_out)
+				ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
+									fh, f);
+			break;
+		case V4L2_BUF_TYPE_PRIVATE:
+			if (ops->vidioc_s_fmt_type_private)
+				ret = ops->vidioc_s_fmt_type_private(file,
+								fh, f);
+			break;
+		}
+		break;
+	}
+	case VIDIOC_TRY_FMT:
+	{
+		struct v4l2_format *f = (struct v4l2_format *)arg;
+
+		/* FIXME: Should be one dump per type */
+		dbgarg(cmd, "type=%s\n", prt_names(f->type,
+						v4l2_type_names));
+		switch (f->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			if (ops->vidioc_try_fmt_vid_cap)
+				ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
+			if (!ret)
+				v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			if (ops->vidioc_try_fmt_vid_overlay)
+				ret = ops->vidioc_try_fmt_vid_overlay(file,
+					fh, f);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			if (ops->vidioc_try_fmt_vid_out)
+				ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
+			if (!ret)
+				v4l_print_pix_fmt(vfd, &f->fmt.pix);
+			break;
+		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+			if (ops->vidioc_try_fmt_vid_out_overlay)
+				ret = ops->vidioc_try_fmt_vid_out_overlay(file,
+				       fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			if (ops->vidioc_try_fmt_vbi_cap)
+				ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_VBI_OUTPUT:
+			if (ops->vidioc_try_fmt_vbi_out)
+				ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+			if (ops->vidioc_try_fmt_sliced_vbi_cap)
+				ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
+								fh, f);
+			break;
+		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+			if (ops->vidioc_try_fmt_sliced_vbi_out)
+				ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
+								fh, f);
+			break;
+		case V4L2_BUF_TYPE_PRIVATE:
+			if (ops->vidioc_try_fmt_type_private)
+				ret = ops->vidioc_try_fmt_type_private(file,
+								fh, f);
+			break;
+		}
+
+		break;
+	}
+	/* FIXME: Those buf reqs could be handled here,
+	   with some changes on videobuf to allow its header to be included at
+	   videodev2.h or being merged at videodev2.
+	 */
+	case VIDIOC_REQBUFS:
+	{
+		struct v4l2_requestbuffers *p = arg;
+
+		if (!ops->vidioc_reqbufs)
+			break;
+		ret = check_fmt(ops, p->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_reqbufs(file, fh, p);
+		dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
+				p->count,
+				prt_names(p->type, v4l2_type_names),
+				prt_names(p->memory, v4l2_memory_names));
+		break;
+	}
+	case VIDIOC_QUERYBUF:
+	{
+		struct v4l2_buffer *p = arg;
+
+		if (!ops->vidioc_querybuf)
+			break;
+		ret = check_fmt(ops, p->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_querybuf(file, fh, p);
+		if (!ret)
+			dbgbuf(cmd, vfd, p);
+		break;
+	}
+	case VIDIOC_QBUF:
+	{
+		struct v4l2_buffer *p = arg;
+
+		if (!ops->vidioc_qbuf)
+			break;
+		ret = check_fmt(ops, p->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_qbuf(file, fh, p);
+		if (!ret)
+			dbgbuf(cmd, vfd, p);
+		break;
+	}
+	case VIDIOC_DQBUF:
+	{
+		struct v4l2_buffer *p = arg;
+
+		if (!ops->vidioc_dqbuf)
+			break;
+		ret = check_fmt(ops, p->type);
+		if (ret)
+			break;
+
+		ret = ops->vidioc_dqbuf(file, fh, p);
+		if (!ret)
+			dbgbuf(cmd, vfd, p);
+		break;
+	}
+	case VIDIOC_OVERLAY:
+	{
+		int *i = arg;
+
+		if (!ops->vidioc_overlay)
+			break;
+		dbgarg(cmd, "value=%d\n", *i);
+		ret = ops->vidioc_overlay(file, fh, *i);
+		break;
+	}
+	case VIDIOC_G_FBUF:
+	{
+		struct v4l2_framebuffer *p = arg;
+
+		if (!ops->vidioc_g_fbuf)
+			break;
+		ret = ops->vidioc_g_fbuf(file, fh, arg);
+		if (!ret) {
+			dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+					p->capability, p->flags,
+					(unsigned long)p->base);
+			v4l_print_pix_fmt(vfd, &p->fmt);
+		}
+		break;
+	}
+	case VIDIOC_S_FBUF:
+	{
+		struct v4l2_framebuffer *p = arg;
+
+		if (!ops->vidioc_s_fbuf)
+			break;
+		dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+			p->capability, p->flags, (unsigned long)p->base);
+		v4l_print_pix_fmt(vfd, &p->fmt);
+		ret = ops->vidioc_s_fbuf(file, fh, arg);
+		break;
+	}
+	case VIDIOC_STREAMON:
+	{
+		enum v4l2_buf_type i = *(int *)arg;
+
+		if (!ops->vidioc_streamon)
+			break;
+		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+		ret = ops->vidioc_streamon(file, fh, i);
+		break;
+	}
+	case VIDIOC_STREAMOFF:
+	{
+		enum v4l2_buf_type i = *(int *)arg;
+
+		if (!ops->vidioc_streamoff)
+			break;
+		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+		ret = ops->vidioc_streamoff(file, fh, i);
+		break;
+	}
+	/* ---------- tv norms ---------- */
+	case VIDIOC_ENUMSTD:
+	{
+		struct v4l2_standard *p = arg;
+		v4l2_std_id id = vfd->tvnorms, curr_id = 0;
+		unsigned int index = p->index, i, j = 0;
+		const char *descr = "";
+
+		/* Return norm array in a canonical way */
+		for (i = 0; i <= index && id; i++) {
+			/* last std value in the standards array is 0, so this
+			   while always ends there since (id & 0) == 0. */
+			while ((id & standards[j].std) != standards[j].std)
+				j++;
+			curr_id = standards[j].std;
+			descr = standards[j].descr;
+			j++;
+			if (curr_id == 0)
+				break;
+			if (curr_id != V4L2_STD_PAL &&
+			    curr_id != V4L2_STD_SECAM &&
+			    curr_id != V4L2_STD_NTSC)
+				id &= ~curr_id;
+		}
+		if (i <= index)
+			return -EINVAL;
+
+		v4l2_video_std_construct(p, curr_id, descr);
+		p->index = index;
+
+		dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
+				"framelines=%d\n", p->index,
+				(unsigned long long)p->id, p->name,
+				p->frameperiod.numerator,
+				p->frameperiod.denominator,
+				p->framelines);
+
+		ret = 0;
+		break;
+	}
+	case VIDIOC_G_STD:
+	{
+		v4l2_std_id *id = arg;
+
+		ret = 0;
+		/* Calls the specific handler */
+		if (ops->vidioc_g_std)
+			ret = ops->vidioc_g_std(file, fh, id);
+		else
+			*id = vfd->current_norm;
+
+		if (!ret)
+			dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
+		break;
+	}
+	case VIDIOC_S_STD:
+	{
+		v4l2_std_id *id = arg, norm;
+
+		dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
+
+		norm = (*id) & vfd->tvnorms;
+		if (vfd->tvnorms && !norm)	/* Check if std is supported */
+			break;
+
+		/* Calls the specific handler */
+		if (ops->vidioc_s_std)
+			ret = ops->vidioc_s_std(file, fh, &norm);
+		else
+			ret = -EINVAL;
+
+		/* Updates standard information */
+		if (ret >= 0)
+			vfd->current_norm = norm;
+		break;
+	}
+	case VIDIOC_QUERYSTD:
+	{
+		v4l2_std_id *p = arg;
+
+		if (!ops->vidioc_querystd)
+			break;
+		ret = ops->vidioc_querystd(file, fh, arg);
+		if (!ret)
+			dbgarg(cmd, "detected std=%08Lx\n",
+						(unsigned long long)*p);
+		break;
+	}
+	/* ------ input switching ---------- */
+	/* FIXME: Inputs can be handled inside videodev2 */
+	case VIDIOC_ENUMINPUT:
+	{
+		struct v4l2_input *p = arg;
+		int i = p->index;
+
+		if (!ops->vidioc_enum_input)
+			break;
+		memset(p, 0, sizeof(*p));
+		p->index = i;
+
+		ret = ops->vidioc_enum_input(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, type=%d, "
+				"audioset=%d, "
+				"tuner=%d, std=%08Lx, status=%d\n",
+				p->index, p->name, p->type, p->audioset,
+				p->tuner,
+				(unsigned long long)p->std,
+				p->status);
+		break;
+	}
+	case VIDIOC_G_INPUT:
+	{
+		unsigned int *i = arg;
+
+		if (!ops->vidioc_g_input)
+			break;
+		ret = ops->vidioc_g_input(file, fh, i);
+		if (!ret)
+			dbgarg(cmd, "value=%d\n", *i);
+		break;
+	}
+	case VIDIOC_S_INPUT:
+	{
+		unsigned int *i = arg;
+
+		if (!ops->vidioc_s_input)
+			break;
+		dbgarg(cmd, "value=%d\n", *i);
+		ret = ops->vidioc_s_input(file, fh, *i);
+		break;
+	}
+
+	/* ------ output switching ---------- */
+	case VIDIOC_ENUMOUTPUT:
+	{
+		struct v4l2_output *p = arg;
+		int i = p->index;
+
+		if (!ops->vidioc_enum_output)
+			break;
+		memset(p, 0, sizeof(*p));
+		p->index = i;
+
+		ret = ops->vidioc_enum_output(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, type=%d, "
+				"audioset=0x%x, "
+				"modulator=%d, std=0x%08Lx\n",
+				p->index, p->name, p->type, p->audioset,
+				p->modulator, (unsigned long long)p->std);
+		break;
+	}
+	case VIDIOC_G_OUTPUT:
+	{
+		unsigned int *i = arg;
+
+		if (!ops->vidioc_g_output)
+			break;
+		ret = ops->vidioc_g_output(file, fh, i);
+		if (!ret)
+			dbgarg(cmd, "value=%d\n", *i);
+		break;
+	}
+	case VIDIOC_S_OUTPUT:
+	{
+		unsigned int *i = arg;
+
+		if (!ops->vidioc_s_output)
+			break;
+		dbgarg(cmd, "value=%d\n", *i);
+		ret = ops->vidioc_s_output(file, fh, *i);
+		break;
+	}
+
+	/* --- controls ---------------------------------------------- */
+	case VIDIOC_QUERYCTRL:
+	{
+		struct v4l2_queryctrl *p = arg;
+
+		if (!ops->vidioc_queryctrl)
+			break;
+		ret = ops->vidioc_queryctrl(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
+					"step=%d, default=%d, flags=0x%08x\n",
+					p->id, p->type, p->name,
+					p->minimum, p->maximum,
+					p->step, p->default_value, p->flags);
+		else
+			dbgarg(cmd, "id=0x%x\n", p->id);
+		break;
+	}
+	case VIDIOC_G_CTRL:
+	{
+		struct v4l2_control *p = arg;
+
+		if (ops->vidioc_g_ctrl)
+			ret = ops->vidioc_g_ctrl(file, fh, p);
+		else if (ops->vidioc_g_ext_ctrls) {
+			struct v4l2_ext_controls ctrls;
+			struct v4l2_ext_control ctrl;
+
+			ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+			ctrls.count = 1;
+			ctrls.controls = &ctrl;
+			ctrl.id = p->id;
+			ctrl.value = p->value;
+			if (check_ext_ctrls(&ctrls, 1)) {
+				ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
+				if (ret == 0)
+					p->value = ctrl.value;
+			}
+		} else
+			break;
+		if (!ret)
+			dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+		else
+			dbgarg(cmd, "id=0x%x\n", p->id);
+		break;
+	}
+	case VIDIOC_S_CTRL:
+	{
+		struct v4l2_control *p = arg;
+		struct v4l2_ext_controls ctrls;
+		struct v4l2_ext_control ctrl;
+
+		if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
+			break;
+
+		dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+
+		if (ops->vidioc_s_ctrl) {
+			ret = ops->vidioc_s_ctrl(file, fh, p);
+			break;
+		}
+		if (!ops->vidioc_s_ext_ctrls)
+			break;
+
+		ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+		ctrls.count = 1;
+		ctrls.controls = &ctrl;
+		ctrl.id = p->id;
+		ctrl.value = p->value;
+		if (check_ext_ctrls(&ctrls, 1))
+			ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
+		break;
+	}
+	case VIDIOC_G_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *p = arg;
+
+		p->error_idx = p->count;
+		if (!ops->vidioc_g_ext_ctrls)
+			break;
+		if (check_ext_ctrls(p, 0))
+			ret = ops->vidioc_g_ext_ctrls(file, fh, p);
+		v4l_print_ext_ctrls(cmd, vfd, p, !ret);
+		break;
+	}
+	case VIDIOC_S_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *p = arg;
+
+		p->error_idx = p->count;
+		if (!ops->vidioc_s_ext_ctrls)
+			break;
+		v4l_print_ext_ctrls(cmd, vfd, p, 1);
+		if (check_ext_ctrls(p, 0))
+			ret = ops->vidioc_s_ext_ctrls(file, fh, p);
+		break;
+	}
+	case VIDIOC_TRY_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *p = arg;
+
+		p->error_idx = p->count;
+		if (!ops->vidioc_try_ext_ctrls)
+			break;
+		v4l_print_ext_ctrls(cmd, vfd, p, 1);
+		if (check_ext_ctrls(p, 0))
+			ret = ops->vidioc_try_ext_ctrls(file, fh, p);
+		break;
+	}
+	case VIDIOC_QUERYMENU:
+	{
+		struct v4l2_querymenu *p = arg;
+
+		if (!ops->vidioc_querymenu)
+			break;
+		ret = ops->vidioc_querymenu(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
+				p->id, p->index, p->name);
+		else
+			dbgarg(cmd, "id=0x%x, index=%d\n",
+				p->id, p->index);
+		break;
+	}
+	/* --- audio ---------------------------------------------- */
+	case VIDIOC_ENUMAUDIO:
+	{
+		struct v4l2_audio *p = arg;
+
+		if (!ops->vidioc_enumaudio)
+			break;
+		ret = ops->vidioc_enumaudio(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+					"mode=0x%x\n", p->index, p->name,
+					p->capability, p->mode);
+		else
+			dbgarg(cmd, "index=%d\n", p->index);
+		break;
+	}
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *p = arg;
+		__u32 index = p->index;
+
+		if (!ops->vidioc_g_audio)
+			break;
+
+		memset(p, 0, sizeof(*p));
+		p->index = index;
+		ret = ops->vidioc_g_audio(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+					"mode=0x%x\n", p->index,
+					p->name, p->capability, p->mode);
+		else
+			dbgarg(cmd, "index=%d\n", p->index);
+		break;
+	}
+	case VIDIOC_S_AUDIO:
+	{
+		struct v4l2_audio *p = arg;
+
+		if (!ops->vidioc_s_audio)
+			break;
+		dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+					"mode=0x%x\n", p->index, p->name,
+					p->capability, p->mode);
+		ret = ops->vidioc_s_audio(file, fh, p);
+		break;
+	}
+	case VIDIOC_ENUMAUDOUT:
+	{
+		struct v4l2_audioout *p = arg;
+
+		if (!ops->vidioc_enumaudout)
+			break;
+		dbgarg(cmd, "Enum for index=%d\n", p->index);
+		ret = ops->vidioc_enumaudout(file, fh, p);
+		if (!ret)
+			dbgarg2("index=%d, name=%s, capability=%d, "
+					"mode=%d\n", p->index, p->name,
+					p->capability, p->mode);
+		break;
+	}
+	case VIDIOC_G_AUDOUT:
+	{
+		struct v4l2_audioout *p = arg;
+
+		if (!ops->vidioc_g_audout)
+			break;
+		dbgarg(cmd, "Enum for index=%d\n", p->index);
+		ret = ops->vidioc_g_audout(file, fh, p);
+		if (!ret)
+			dbgarg2("index=%d, name=%s, capability=%d, "
+					"mode=%d\n", p->index, p->name,
+					p->capability, p->mode);
+		break;
+	}
+	case VIDIOC_S_AUDOUT:
+	{
+		struct v4l2_audioout *p = arg;
+
+		if (!ops->vidioc_s_audout)
+			break;
+		dbgarg(cmd, "index=%d, name=%s, capability=%d, "
+					"mode=%d\n", p->index, p->name,
+					p->capability, p->mode);
+
+		ret = ops->vidioc_s_audout(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_MODULATOR:
+	{
+		struct v4l2_modulator *p = arg;
+
+		if (!ops->vidioc_g_modulator)
+			break;
+		ret = ops->vidioc_g_modulator(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, "
+					"capability=%d, rangelow=%d,"
+					" rangehigh=%d, txsubchans=%d\n",
+					p->index, p->name, p->capability,
+					p->rangelow, p->rangehigh,
+					p->txsubchans);
+		break;
+	}
+	case VIDIOC_S_MODULATOR:
+	{
+		struct v4l2_modulator *p = arg;
+
+		if (!ops->vidioc_s_modulator)
+			break;
+		dbgarg(cmd, "index=%d, name=%s, capability=%d, "
+				"rangelow=%d, rangehigh=%d, txsubchans=%d\n",
+				p->index, p->name, p->capability, p->rangelow,
+				p->rangehigh, p->txsubchans);
+			ret = ops->vidioc_s_modulator(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_CROP:
+	{
+		struct v4l2_crop *p = arg;
+
+		if (!ops->vidioc_g_crop)
+			break;
+		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+		ret = ops->vidioc_g_crop(file, fh, p);
+		if (!ret)
+			dbgrect(vfd, "", &p->c);
+		break;
+	}
+	case VIDIOC_S_CROP:
+	{
+		struct v4l2_crop *p = arg;
+
+		if (!ops->vidioc_s_crop)
+			break;
+		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+		dbgrect(vfd, "", &p->c);
+		ret = ops->vidioc_s_crop(file, fh, p);
+		break;
+	}
+	case VIDIOC_CROPCAP:
+	{
+		struct v4l2_cropcap *p = arg;
+
+		/*FIXME: Should also show v4l2_fract pixelaspect */
+		if (!ops->vidioc_cropcap)
+			break;
+		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+		ret = ops->vidioc_cropcap(file, fh, p);
+		if (!ret) {
+			dbgrect(vfd, "bounds ", &p->bounds);
+			dbgrect(vfd, "defrect ", &p->defrect);
+		}
+		break;
+	}
+	case VIDIOC_G_JPEGCOMP:
+	{
+		struct v4l2_jpegcompression *p = arg;
+
+		if (!ops->vidioc_g_jpegcomp)
+			break;
+		ret = ops->vidioc_g_jpegcomp(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "quality=%d, APPn=%d, "
+					"APP_len=%d, COM_len=%d, "
+					"jpeg_markers=%d\n",
+					p->quality, p->APPn, p->APP_len,
+					p->COM_len, p->jpeg_markers);
+		break;
+	}
+	case VIDIOC_S_JPEGCOMP:
+	{
+		struct v4l2_jpegcompression *p = arg;
+
+		if (!ops->vidioc_g_jpegcomp)
+			break;
+		dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
+					"COM_len=%d, jpeg_markers=%d\n",
+					p->quality, p->APPn, p->APP_len,
+					p->COM_len, p->jpeg_markers);
+			ret = ops->vidioc_s_jpegcomp(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_ENC_INDEX:
+	{
+		struct v4l2_enc_idx *p = arg;
+
+		if (!ops->vidioc_g_enc_index)
+			break;
+		ret = ops->vidioc_g_enc_index(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "entries=%d, entries_cap=%d\n",
+					p->entries, p->entries_cap);
+		break;
+	}
+	case VIDIOC_ENCODER_CMD:
+	{
+		struct v4l2_encoder_cmd *p = arg;
+
+		if (!ops->vidioc_encoder_cmd)
+			break;
+		memset(&p->raw, 0, sizeof(p->raw));
+		ret = ops->vidioc_encoder_cmd(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+		break;
+	}
+	case VIDIOC_TRY_ENCODER_CMD:
+	{
+		struct v4l2_encoder_cmd *p = arg;
+
+		if (!ops->vidioc_try_encoder_cmd)
+			break;
+		memset(&p->raw, 0, sizeof(p->raw));
+		ret = ops->vidioc_try_encoder_cmd(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+		break;
+	}
+	case VIDIOC_G_PARM:
+	{
+		struct v4l2_streamparm *p = arg;
+		__u32 type = p->type;
+
+		memset(p, 0, sizeof(*p));
+		p->type = type;
+
+		if (ops->vidioc_g_parm) {
+			ret = ops->vidioc_g_parm(file, fh, p);
+		} else {
+			struct v4l2_standard s;
+
+			if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+				return -EINVAL;
+
+			v4l2_video_std_construct(&s, vfd->current_norm,
+						 v4l2_norm_to_name(vfd->current_norm));
+
+			p->parm.capture.timeperframe = s.frameperiod;
+			ret = 0;
+		}
+
+		dbgarg(cmd, "type=%d\n", p->type);
+		break;
+	}
+	case VIDIOC_S_PARM:
+	{
+		struct v4l2_streamparm *p = arg;
+
+		if (!ops->vidioc_s_parm)
+			break;
+		dbgarg(cmd, "type=%d\n", p->type);
+		ret = ops->vidioc_s_parm(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *p = arg;
+		__u32 index = p->index;
+
+		if (!ops->vidioc_g_tuner)
+			break;
+
+		memset(p, 0, sizeof(*p));
+		p->index = index;
+
+		ret = ops->vidioc_g_tuner(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "index=%d, name=%s, type=%d, "
+					"capability=0x%x, rangelow=%d, "
+					"rangehigh=%d, signal=%d, afc=%d, "
+					"rxsubchans=0x%x, audmode=%d\n",
+					p->index, p->name, p->type,
+					p->capability, p->rangelow,
+					p->rangehigh, p->signal, p->afc,
+					p->rxsubchans, p->audmode);
+		break;
+	}
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *p = arg;
+
+		if (!ops->vidioc_s_tuner)
+			break;
+		dbgarg(cmd, "index=%d, name=%s, type=%d, "
+				"capability=0x%x, rangelow=%d, "
+				"rangehigh=%d, signal=%d, afc=%d, "
+				"rxsubchans=0x%x, audmode=%d\n",
+				p->index, p->name, p->type,
+				p->capability, p->rangelow,
+				p->rangehigh, p->signal, p->afc,
+				p->rxsubchans, p->audmode);
+		ret = ops->vidioc_s_tuner(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_FREQUENCY:
+	{
+		struct v4l2_frequency *p = arg;
+
+		if (!ops->vidioc_g_frequency)
+			break;
+
+		memset(p->reserved, 0, sizeof(p->reserved));
+
+		ret = ops->vidioc_g_frequency(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+					p->tuner, p->type, p->frequency);
+		break;
+	}
+	case VIDIOC_S_FREQUENCY:
+	{
+		struct v4l2_frequency *p = arg;
+
+		if (!ops->vidioc_s_frequency)
+			break;
+		dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+				p->tuner, p->type, p->frequency);
+		ret = ops->vidioc_s_frequency(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_SLICED_VBI_CAP:
+	{
+		struct v4l2_sliced_vbi_cap *p = arg;
+		__u32 type = p->type;
+
+		if (!ops->vidioc_g_sliced_vbi_cap)
+			break;
+		memset(p, 0, sizeof(*p));
+		p->type = type;
+		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+		ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
+		if (!ret)
+			dbgarg2("service_set=%d\n", p->service_set);
+		break;
+	}
+	case VIDIOC_LOG_STATUS:
+	{
+		if (!ops->vidioc_log_status)
+			break;
+		ret = ops->vidioc_log_status(file, fh);
+		break;
+	}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	case VIDIOC_DBG_G_REGISTER:
+	{
+		struct v4l2_register *p = arg;
+
+		if (!capable(CAP_SYS_ADMIN))
+			ret = -EPERM;
+		else if (ops->vidioc_g_register)
+			ret = ops->vidioc_g_register(file, fh, p);
+		break;
+	}
+	case VIDIOC_DBG_S_REGISTER:
+	{
+		struct v4l2_register *p = arg;
+
+		if (!capable(CAP_SYS_ADMIN))
+			ret = -EPERM;
+		else if (ops->vidioc_s_register)
+			ret = ops->vidioc_s_register(file, fh, p);
+		break;
+	}
+#endif
+	case VIDIOC_G_CHIP_IDENT:
+	{
+		struct v4l2_chip_ident *p = arg;
+
+		if (!ops->vidioc_g_chip_ident)
+			break;
+		ret = ops->vidioc_g_chip_ident(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
+		break;
+	}
+	case VIDIOC_S_HW_FREQ_SEEK:
+	{
+		struct v4l2_hw_freq_seek *p = arg;
+
+		if (!ops->vidioc_s_hw_freq_seek)
+			break;
+		dbgarg(cmd,
+			"tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
+			p->tuner, p->type, p->seek_upward, p->wrap_around);
+		ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
+		break;
+	}
+	default:
+	{
+		if (!ops->vidioc_default)
+			break;
+		ret = ops->vidioc_default(file, fh, cmd, arg);
+		break;
+	}
+	} /* switch */
+
+	if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
+		if (ret < 0) {
+			v4l_print_ioctl(vfd->name, cmd);
+			printk(KERN_CONT " error %d\n", ret);
+		}
+	}
+
+	return ret;
+}
+
+int video_ioctl2(struct inode *inode, struct file *file,
+	       unsigned int cmd, unsigned long arg)
+{
+	char	sbuf[128];
+	void    *mbuf = NULL;
+	void	*parg = NULL;
+	int	err  = -EINVAL;
+	int     is_ext_ctrl;
+	size_t  ctrls_size = 0;
+	void __user *user_ptr = NULL;
+
+#ifdef __OLD_VIDIOC_
+	cmd = video_fix_command(cmd);
+#endif
+	is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
+		       cmd == VIDIOC_TRY_EXT_CTRLS);
+
+	/*  Copy arguments into temp kernel buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:
+		parg = NULL;
+		break;
+	case _IOC_READ:
+	case _IOC_WRITE:
+	case (_IOC_WRITE | _IOC_READ):
+		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+			parg = sbuf;
+		} else {
+			/* too big to allocate from stack */
+			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+			if (NULL == mbuf)
+				return -ENOMEM;
+			parg = mbuf;
+		}
+
+		err = -EFAULT;
+		if (_IOC_DIR(cmd) & _IOC_WRITE)
+			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+				goto out;
+		break;
+	}
+
+	if (is_ext_ctrl) {
+		struct v4l2_ext_controls *p = parg;
+
+		/* In case of an error, tell the caller that it wasn't
+		   a specific control that caused it. */
+		p->error_idx = p->count;
+		user_ptr = (void __user *)p->controls;
+		if (p->count) {
+			ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
+			/* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
+			mbuf = kmalloc(ctrls_size, GFP_KERNEL);
+			err = -ENOMEM;
+			if (NULL == mbuf)
+				goto out_ext_ctrl;
+			err = -EFAULT;
+			if (copy_from_user(mbuf, user_ptr, ctrls_size))
+				goto out_ext_ctrl;
+			p->controls = mbuf;
+		}
+	}
+
+	/* Handles IOCTL */
+	err = __video_do_ioctl(inode, file, cmd, parg);
+	if (err == -ENOIOCTLCMD)
+		err = -EINVAL;
+	if (is_ext_ctrl) {
+		struct v4l2_ext_controls *p = parg;
+
+		p->controls = (void *)user_ptr;
+		if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
+			err = -EFAULT;
+		goto out_ext_ctrl;
+	}
+	if (err < 0)
+		goto out;
+
+out_ext_ctrl:
+	/*  Copy results into user buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_READ:
+	case (_IOC_WRITE | _IOC_READ):
+		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+			err = -EFAULT;
+		break;
+	}
+
+out:
+	kfree(mbuf);
+	return err;
+}
+EXPORT_SYMBOL(video_ioctl2);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 03f20ac..31944b1 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -28,10 +28,10 @@
 };
 
 #define MAGIC_DC_MEM 0x0733ac61
-#define MAGIC_CHECK(is, should)						\
-	if (unlikely((is) != (should)))	{				\
-		pr_err("magic mismatch: %x expected %x\n", is, should); \
-		BUG();							\
+#define MAGIC_CHECK(is, should)						    \
+	if (unlikely((is) != (should)))	{				    \
+		pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
+		BUG();							    \
 	}
 
 static void
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index a868b7e..be65a2f 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -203,7 +203,7 @@
 			return 0;
 
 		/* FIXME: to properly support USERPTR, remap should occur.
-		   The code bellow won't work, since mem->vma = NULL
+		   The code below won't work, since mem->vma = NULL
 		 */
 		/* Try to remap memory */
 		rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 6616e65..e69de29 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1,2262 +0,0 @@
-/*
- * Video capture interface for Linux version 2
- *
- *	A generic video device interface for the LINUX operating system
- *	using a set of device structures/vectors for low level operations.
- *
- *	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.
- *
- * Authors:	Alan Cox, <alan@redhat.com> (version 1)
- *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
- *
- * Fixes:	20000516  Claudio Matsuoka <claudio@conectiva.com>
- *		- Added procfs support
- */
-
-#define dbgarg(cmd, fmt, arg...) \
-		do {							\
-		    if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {		\
-			printk(KERN_DEBUG "%s: ",  vfd->name);		\
-			v4l_printk_ioctl(cmd);				\
-			printk(" " fmt,  ## arg);			\
-		    }							\
-		} while (0)
-
-#define dbgarg2(fmt, arg...) \
-		do {							\
-		    if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)		\
-			printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
-		} while (0)
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#define __OLD_VIDIOC_ /* To allow fixing old calls*/
-#include <linux/videodev2.h>
-
-#ifdef CONFIG_VIDEO_V4L1
-#include <linux/videodev.h>
-#endif
-#include <media/v4l2-common.h>
-#include <linux/video_decoder.h>
-
-#define VIDEO_NUM_DEVICES	256
-#define VIDEO_NAME              "video4linux"
-
-struct std_descr {
-	v4l2_std_id std;
-	const char *descr;
-};
-
-static const struct std_descr standards[] = {
-	{ V4L2_STD_NTSC, 	"NTSC"      },
-	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
-	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
-	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
-	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
-	{ V4L2_STD_PAL, 	"PAL"       },
-	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
-	{ V4L2_STD_PAL_B, 	"PAL-B"     },
-	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
-	{ V4L2_STD_PAL_G, 	"PAL-G"     },
-	{ V4L2_STD_PAL_H, 	"PAL-H"     },
-	{ V4L2_STD_PAL_I, 	"PAL-I"     },
-	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
-	{ V4L2_STD_PAL_D, 	"PAL-D"     },
-	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
-	{ V4L2_STD_PAL_K, 	"PAL-K"     },
-	{ V4L2_STD_PAL_M, 	"PAL-M"     },
-	{ V4L2_STD_PAL_N, 	"PAL-N"     },
-	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
-	{ V4L2_STD_PAL_60, 	"PAL-60"    },
-	{ V4L2_STD_SECAM, 	"SECAM"     },
-	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
-	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
-	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
-	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
-	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
-	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
-	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
-	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
-	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
-	{ 0, 			"Unknown"   }
-};
-
-/* video4linux standard ID conversion to standard name
- */
-const char *v4l2_norm_to_name(v4l2_std_id id)
-{
-	u32 myid = id;
-	int i;
-
-	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
-	   64 bit comparations. So, on that architecture, with some gcc
-	   variants, compilation fails. Currently, the max value is 30bit wide.
-	 */
-	BUG_ON(myid != id);
-
-	for (i = 0; standards[i].std; i++)
-		if (myid == standards[i].std)
-			break;
-	return standards[i].descr;
-}
-EXPORT_SYMBOL(v4l2_norm_to_name);
-
-/* Fill in the fields of a v4l2_standard structure according to the
-   'id' and 'transmission' parameters.  Returns negative on error.  */
-int v4l2_video_std_construct(struct v4l2_standard *vs,
-			     int id, const char *name)
-{
-	u32 index = vs->index;
-
-	memset(vs, 0, sizeof(struct v4l2_standard));
-	vs->index = index;
-	vs->id    = id;
-	if (id & V4L2_STD_525_60) {
-		vs->frameperiod.numerator = 1001;
-		vs->frameperiod.denominator = 30000;
-		vs->framelines = 525;
-	} else {
-		vs->frameperiod.numerator = 1;
-		vs->frameperiod.denominator = 25;
-		vs->framelines = 625;
-	}
-	strlcpy(vs->name, name, sizeof(vs->name));
-	return 0;
-}
-EXPORT_SYMBOL(v4l2_video_std_construct);
-
-/* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages of enum types      */
-
-const char *v4l2_field_names[] = {
-	[V4L2_FIELD_ANY]        = "any",
-	[V4L2_FIELD_NONE]       = "none",
-	[V4L2_FIELD_TOP]        = "top",
-	[V4L2_FIELD_BOTTOM]     = "bottom",
-	[V4L2_FIELD_INTERLACED] = "interlaced",
-	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
-	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
-	[V4L2_FIELD_ALTERNATE]  = "alternate",
-	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
-	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-EXPORT_SYMBOL(v4l2_field_names);
-
-const char *v4l2_type_names[] = {
-	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "vid-cap",
-	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "vid-overlay",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "vid-out",
-	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
-	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
-	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
-	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
-	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
-};
-EXPORT_SYMBOL(v4l2_type_names);
-
-static const char *v4l2_memory_names[] = {
-	[V4L2_MEMORY_MMAP]    = "mmap",
-	[V4L2_MEMORY_USERPTR] = "userptr",
-	[V4L2_MEMORY_OVERLAY] = "overlay",
-};
-
-#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
-			   arr[a] : "unknown")
-
-/* ------------------------------------------------------------------ */
-/* debug help functions                                               */
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static const char *v4l1_ioctls[] = {
-	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
-	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
-	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
-	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
-	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
-	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
-	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
-	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
-	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
-	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
-	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
-	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
-	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
-	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
-	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
-	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
-	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
-	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
-	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
-	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
-	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
-	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
-	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
-	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
-	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
-	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
-	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
-	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
-	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
-};
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-#endif
-
-static const char *v4l2_ioctls[] = {
-	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
-	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
-	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
-	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
-	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
-	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
-	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
-	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
-	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
-	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
-	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
-	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
-	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
-	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
-	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
-	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
-	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
-	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
-	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
-	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
-	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
-	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
-	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
-	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
-	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
-	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
-	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
-	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
-	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
-	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
-	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
-	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
-	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
-	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
-	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
-	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
-	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
-	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
-	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
-	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
-	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
-	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
-	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
-	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
-	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
-	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
-	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
-	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
-	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
-	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
-	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
-	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
-	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
-	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
-	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
-#if 1
-	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
-	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
-	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
-	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
-	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
-
-	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
-	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
-
-	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
-	[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)]   = "VIDIOC_S_HW_FREQ_SEEK",
-#endif
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
-	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
-	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
-	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
-	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
-	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
-	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
-	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
-	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
-	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
-	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
-#endif
-	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
-
-	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
-	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
-	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
-
-	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
-	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
-	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
-	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
-	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
-	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
-	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
-	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
-/* Common ioctl debug function. This function can be used by
-   external ioctl messages as well as internal V4L ioctl */
-void v4l_printk_ioctl(unsigned int cmd)
-{
-	char *dir, *type;
-
-	switch (_IOC_TYPE(cmd)) {
-	case 'd':
-		if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
-			type = "v4l2_int";
-			break;
-		}
-		printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
-		return;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	case 'v':
-		if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
-			type = "v4l1";
-			break;
-		}
-		printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
-		return;
-#endif
-	case 'V':
-		if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
-			type = "v4l2";
-			break;
-		}
-		printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
-		return;
-	default:
-		type = "unknown";
-	}
-
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:              dir = "--"; break;
-	case _IOC_READ:              dir = "r-"; break;
-	case _IOC_WRITE:             dir = "-w"; break;
-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
-	default:                     dir = "*ERR*"; break;
-	}
-	printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
-		type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
-}
-EXPORT_SYMBOL(v4l_printk_ioctl);
-
-/*
- *	sysfs stuff
- */
-
-static ssize_t show_index(struct device *cd,
-			 struct device_attribute *attr, char *buf)
-{
-	struct video_device *vfd = container_of(cd, struct video_device,
-						class_dev);
-	return sprintf(buf, "%i\n", vfd->index);
-}
-
-static ssize_t show_name(struct device *cd,
-			 struct device_attribute *attr, char *buf)
-{
-	struct video_device *vfd = container_of(cd, struct video_device,
-						class_dev);
-	return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
-}
-
-static struct device_attribute video_device_attrs[] = {
-	__ATTR(name, S_IRUGO, show_name, NULL),
-	__ATTR(index, S_IRUGO, show_index, NULL),
-	__ATTR_NULL
-};
-
-struct video_device *video_device_alloc(void)
-{
-	struct video_device *vfd;
-
-	vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
-	return vfd;
-}
-EXPORT_SYMBOL(video_device_alloc);
-
-void video_device_release(struct video_device *vfd)
-{
-	kfree(vfd);
-}
-EXPORT_SYMBOL(video_device_release);
-
-static void video_release(struct device *cd)
-{
-	struct video_device *vfd = container_of(cd, struct video_device,
-								class_dev);
-
-#if 1
-	/* needed until all drivers are fixed */
-	if (!vfd->release)
-		return;
-#endif
-	vfd->release(vfd);
-}
-
-static struct class video_class = {
-	.name    = VIDEO_NAME,
-	.dev_attrs = video_device_attrs,
-	.dev_release = video_release,
-};
-
-/*
- *	Active devices
- */
-
-static struct video_device *video_device[VIDEO_NUM_DEVICES];
-static DEFINE_MUTEX(videodev_lock);
-
-struct video_device* video_devdata(struct file *file)
-{
-	return video_device[iminor(file->f_path.dentry->d_inode)];
-}
-EXPORT_SYMBOL(video_devdata);
-
-/*
- *	Open a video device - FIXME: Obsoleted
- */
-static int video_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	int err = 0;
-	struct video_device *vfl;
-	const struct file_operations *old_fops;
-
-	if(minor>=VIDEO_NUM_DEVICES)
-		return -ENODEV;
-	lock_kernel();
-	mutex_lock(&videodev_lock);
-	vfl=video_device[minor];
-	if(vfl==NULL) {
-		mutex_unlock(&videodev_lock);
-		request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
-		mutex_lock(&videodev_lock);
-		vfl=video_device[minor];
-		if (vfl==NULL) {
-			mutex_unlock(&videodev_lock);
-			unlock_kernel();
-			return -ENODEV;
-		}
-	}
-	old_fops = file->f_op;
-	file->f_op = fops_get(vfl->fops);
-	if(file->f_op->open)
-		err = file->f_op->open(inode,file);
-	if (err) {
-		fops_put(file->f_op);
-		file->f_op = fops_get(old_fops);
-	}
-	fops_put(old_fops);
-	mutex_unlock(&videodev_lock);
-	unlock_kernel();
-	return err;
-}
-
-/*
- * helper function -- handles userspace copying for ioctl arguments
- */
-
-#ifdef __OLD_VIDIOC_
-static unsigned int
-video_fix_command(unsigned int cmd)
-{
-	switch (cmd) {
-	case VIDIOC_OVERLAY_OLD:
-		cmd = VIDIOC_OVERLAY;
-		break;
-	case VIDIOC_S_PARM_OLD:
-		cmd = VIDIOC_S_PARM;
-		break;
-	case VIDIOC_S_CTRL_OLD:
-		cmd = VIDIOC_S_CTRL;
-		break;
-	case VIDIOC_G_AUDIO_OLD:
-		cmd = VIDIOC_G_AUDIO;
-		break;
-	case VIDIOC_G_AUDOUT_OLD:
-		cmd = VIDIOC_G_AUDOUT;
-		break;
-	case VIDIOC_CROPCAP_OLD:
-		cmd = VIDIOC_CROPCAP;
-		break;
-	}
-	return cmd;
-}
-#endif
-
-/*
- * Obsolete usercopy function - Should be removed soon
- */
-int
-video_usercopy(struct inode *inode, struct file *file,
-	       unsigned int cmd, unsigned long arg,
-	       int (*func)(struct inode *inode, struct file *file,
-			   unsigned int cmd, void *arg))
-{
-	char	sbuf[128];
-	void    *mbuf = NULL;
-	void	*parg = NULL;
-	int	err  = -EINVAL;
-	int     is_ext_ctrl;
-	size_t  ctrls_size = 0;
-	void __user *user_ptr = NULL;
-
-#ifdef __OLD_VIDIOC_
-	cmd = video_fix_command(cmd);
-#endif
-	is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
-		       cmd == VIDIOC_TRY_EXT_CTRLS);
-
-	/*  Copy arguments into temp kernel buffer  */
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:
-		parg = NULL;
-		break;
-	case _IOC_READ:
-	case _IOC_WRITE:
-	case (_IOC_WRITE | _IOC_READ):
-		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
-			parg = sbuf;
-		} else {
-			/* too big to allocate from stack */
-			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
-			if (NULL == mbuf)
-				return -ENOMEM;
-			parg = mbuf;
-		}
-
-		err = -EFAULT;
-		if (_IOC_DIR(cmd) & _IOC_WRITE)
-			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
-				goto out;
-		break;
-	}
-	if (is_ext_ctrl) {
-		struct v4l2_ext_controls *p = parg;
-
-		/* In case of an error, tell the caller that it wasn't
-		   a specific control that caused it. */
-		p->error_idx = p->count;
-		user_ptr = (void __user *)p->controls;
-		if (p->count) {
-			ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
-			/* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
-			mbuf = kmalloc(ctrls_size, GFP_KERNEL);
-			err = -ENOMEM;
-			if (NULL == mbuf)
-				goto out_ext_ctrl;
-			err = -EFAULT;
-			if (copy_from_user(mbuf, user_ptr, ctrls_size))
-				goto out_ext_ctrl;
-			p->controls = mbuf;
-		}
-	}
-
-	/* call driver */
-	err = func(inode, file, cmd, parg);
-	if (err == -ENOIOCTLCMD)
-		err = -EINVAL;
-	if (is_ext_ctrl) {
-		struct v4l2_ext_controls *p = parg;
-
-		p->controls = (void *)user_ptr;
-		if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
-			err = -EFAULT;
-		goto out_ext_ctrl;
-	}
-	if (err < 0)
-		goto out;
-
-out_ext_ctrl:
-	/*  Copy results into user buffer  */
-	switch (_IOC_DIR(cmd))
-	{
-	case _IOC_READ:
-	case (_IOC_WRITE | _IOC_READ):
-		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
-			err = -EFAULT;
-		break;
-	}
-
-out:
-	kfree(mbuf);
-	return err;
-}
-EXPORT_SYMBOL(video_usercopy);
-
-/*
- * open/release helper functions -- handle exclusive opens
- * Should be removed soon
- */
-int video_exclusive_open(struct inode *inode, struct file *file)
-{
-	struct  video_device *vfl = video_devdata(file);
-	int retval = 0;
-
-	mutex_lock(&vfl->lock);
-	if (vfl->users) {
-		retval = -EBUSY;
-	} else {
-		vfl->users++;
-	}
-	mutex_unlock(&vfl->lock);
-	return retval;
-}
-EXPORT_SYMBOL(video_exclusive_open);
-
-int video_exclusive_release(struct inode *inode, struct file *file)
-{
-	struct  video_device *vfl = video_devdata(file);
-
-	vfl->users--;
-	return 0;
-}
-EXPORT_SYMBOL(video_exclusive_release);
-
-static void dbgbuf(unsigned int cmd, struct video_device *vfd,
-					struct v4l2_buffer *p)
-{
-	struct v4l2_timecode *tc=&p->timecode;
-
-	dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
-		"bytesused=%d, flags=0x%08d, "
-		"field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
-			(p->timestamp.tv_sec/3600),
-			(int)(p->timestamp.tv_sec/60)%60,
-			(int)(p->timestamp.tv_sec%60),
-			p->timestamp.tv_usec,
-			p->index,
-			prt_names(p->type, v4l2_type_names),
-			p->bytesused, p->flags,
-			p->field, p->sequence,
-			prt_names(p->memory, v4l2_memory_names),
-			p->m.userptr, p->length);
-	dbgarg2("timecode=%02d:%02d:%02d type=%d, "
-		"flags=0x%08d, frames=%d, userbits=0x%08x\n",
-			tc->hours,tc->minutes,tc->seconds,
-			tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
-}
-
-static inline void dbgrect(struct video_device *vfd, char *s,
-							struct v4l2_rect *r)
-{
-	dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
-						r->width, r->height);
-};
-
-static inline void v4l_print_pix_fmt (struct video_device *vfd,
-						struct v4l2_pix_format *fmt)
-{
-	dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
-		"bytesperline=%d sizeimage=%d, colorspace=%d\n",
-		fmt->width,fmt->height,
-		(fmt->pixelformat & 0xff),
-		(fmt->pixelformat >>  8) & 0xff,
-		(fmt->pixelformat >> 16) & 0xff,
-		(fmt->pixelformat >> 24) & 0xff,
-		prt_names(fmt->field, v4l2_field_names),
-		fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
-};
-
-static inline void v4l_print_ext_ctrls(unsigned int cmd,
-	struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
-{
-	__u32 i;
-
-	if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
-		return;
-	dbgarg(cmd, "");
-	printk(KERN_CONT "class=0x%x", c->ctrl_class);
-	for (i = 0; i < c->count; i++) {
-		if (show_vals)
-			printk(KERN_CONT " id/val=0x%x/0x%x",
-				c->controls[i].id, c->controls[i].value);
-		else
-			printk(KERN_CONT " id=0x%x", c->controls[i].id);
-	}
-	printk(KERN_CONT "\n");
-};
-
-static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
-{
-	__u32 i;
-
-	/* zero the reserved fields */
-	c->reserved[0] = c->reserved[1] = 0;
-	for (i = 0; i < c->count; i++) {
-		c->controls[i].reserved2[0] = 0;
-		c->controls[i].reserved2[1] = 0;
-	}
-	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
-	   when using extended controls.
-	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
-	   is it allowed for backwards compatibility.
-	 */
-	if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
-		return 0;
-	/* Check that all controls are from the same control class. */
-	for (i = 0; i < c->count; i++) {
-		if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
-			c->error_idx = i;
-			return 0;
-		}
-	}
-	return 1;
-}
-
-static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
-{
-	switch (type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (vfd->vidioc_try_fmt_vid_cap)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (vfd->vidioc_try_fmt_vid_overlay)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (vfd->vidioc_try_fmt_vid_out)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		if (vfd->vidioc_try_fmt_vid_out_overlay)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		if (vfd->vidioc_try_fmt_vbi_cap)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		if (vfd->vidioc_try_fmt_vbi_out)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		if (vfd->vidioc_try_fmt_sliced_vbi_cap)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		if (vfd->vidioc_try_fmt_sliced_vbi_out)
-			return (0);
-		break;
-	case V4L2_BUF_TYPE_PRIVATE:
-		if (vfd->vidioc_try_fmt_type_private)
-			return (0);
-		break;
-	}
-	return (-EINVAL);
-}
-
-static int __video_do_ioctl(struct inode *inode, struct file *file,
-		unsigned int cmd, void *arg)
-{
-	struct video_device *vfd = video_devdata(file);
-	void                 *fh = file->private_data;
-	int                  ret = -EINVAL;
-
-	if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
-				!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
-		v4l_print_ioctl(vfd->name, cmd);
-		printk("\n");
-	}
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	/***********************************************************
-	 Handles calls to the obsoleted V4L1 API
-	 Due to the nature of VIDIOCGMBUF, each driver that supports
-	 V4L1 should implement its own handler for this ioctl.
-	 ***********************************************************/
-
-	/* --- streaming capture ------------------------------------- */
-	if (cmd == VIDIOCGMBUF) {
-		struct video_mbuf *p=arg;
-
-		memset(p, 0, sizeof(*p));
-
-		if (!vfd->vidiocgmbuf)
-			return ret;
-		ret=vfd->vidiocgmbuf(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
-						p->size, p->frames,
-						(unsigned long)p->offsets);
-		return ret;
-	}
-
-	/********************************************************
-	 All other V4L1 calls are handled by v4l1_compat module.
-	 Those calls will be translated into V4L2 calls, and
-	 __video_do_ioctl will be called again, with one or more
-	 V4L2 ioctls.
-	 ********************************************************/
-	if (_IOC_TYPE(cmd)=='v')
-		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-						__video_do_ioctl);
-#endif
-
-	switch(cmd) {
-	/* --- capabilities ------------------------------------------ */
-	case VIDIOC_QUERYCAP:
-	{
-		struct v4l2_capability *cap = (struct v4l2_capability*)arg;
-		memset(cap, 0, sizeof(*cap));
-
-		if (!vfd->vidioc_querycap)
-			break;
-
-		ret=vfd->vidioc_querycap(file, fh, cap);
-		if (!ret)
-			dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
-					"version=0x%08x, "
-					"capabilities=0x%08x\n",
-					cap->driver,cap->card,cap->bus_info,
-					cap->version,
-					cap->capabilities);
-		break;
-	}
-
-	/* --- priority ------------------------------------------ */
-	case VIDIOC_G_PRIORITY:
-	{
-		enum v4l2_priority *p=arg;
-
-		if (!vfd->vidioc_g_priority)
-			break;
-		ret=vfd->vidioc_g_priority(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "priority is %d\n", *p);
-		break;
-	}
-	case VIDIOC_S_PRIORITY:
-	{
-		enum v4l2_priority *p=arg;
-
-		if (!vfd->vidioc_s_priority)
-			break;
-		dbgarg(cmd, "setting priority to %d\n", *p);
-		ret=vfd->vidioc_s_priority(file, fh, *p);
-		break;
-	}
-
-	/* --- capture ioctls ---------------------------------------- */
-	case VIDIOC_ENUM_FMT:
-	{
-		struct v4l2_fmtdesc *f = arg;
-		enum v4l2_buf_type type;
-		unsigned int index;
-
-		index = f->index;
-		type  = f->type;
-		memset(f,0,sizeof(*f));
-		f->index = index;
-		f->type  = type;
-
-		switch (type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-			if (vfd->vidioc_enum_fmt_vid_cap)
-				ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (vfd->vidioc_enum_fmt_vid_overlay)
-				ret = vfd->vidioc_enum_fmt_vid_overlay(file,
-					fh, f);
-			break;
-#if 1
-		/* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
-		 * according to the spec. The bttv and saa7134 drivers support
-		 * it though, so just warn that this is deprecated and will be
-		 * removed in the near future. */
-		case V4L2_BUF_TYPE_VBI_CAPTURE:
-			if (vfd->vidioc_enum_fmt_vbi_cap) {
-				printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
-				ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f);
-			}
-			break;
-#endif
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			if (vfd->vidioc_enum_fmt_vid_out)
-				ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_PRIVATE:
-			if (vfd->vidioc_enum_fmt_type_private)
-				ret = vfd->vidioc_enum_fmt_type_private(file,
-								fh, f);
-			break;
-		default:
-			break;
-		}
-		if (!ret)
-			dbgarg (cmd, "index=%d, type=%d, flags=%d, "
-					"pixelformat=%c%c%c%c, description='%s'\n",
-					f->index, f->type, f->flags,
-					(f->pixelformat & 0xff),
-					(f->pixelformat >>  8) & 0xff,
-					(f->pixelformat >> 16) & 0xff,
-					(f->pixelformat >> 24) & 0xff,
-					f->description);
-		break;
-	}
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format *f = (struct v4l2_format *)arg;
-
-		memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
-
-		/* FIXME: Should be one dump per type */
-		dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
-
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-			if (vfd->vidioc_g_fmt_vid_cap)
-				ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f);
-			if (!ret)
-				v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (vfd->vidioc_g_fmt_vid_overlay)
-				ret = vfd->vidioc_g_fmt_vid_overlay(file,
-								    fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			if (vfd->vidioc_g_fmt_vid_out)
-				ret = vfd->vidioc_g_fmt_vid_out(file, fh, f);
-			if (!ret)
-				v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-			if (vfd->vidioc_g_fmt_vid_out_overlay)
-				ret = vfd->vidioc_g_fmt_vid_out_overlay(file,
-				       fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_CAPTURE:
-			if (vfd->vidioc_g_fmt_vbi_cap)
-				ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_OUTPUT:
-			if (vfd->vidioc_g_fmt_vbi_out)
-				ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-			if (vfd->vidioc_g_fmt_sliced_vbi_cap)
-				ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file,
-									fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-			if (vfd->vidioc_g_fmt_sliced_vbi_out)
-				ret = vfd->vidioc_g_fmt_sliced_vbi_out(file,
-									fh, f);
-			break;
-		case V4L2_BUF_TYPE_PRIVATE:
-			if (vfd->vidioc_g_fmt_type_private)
-				ret = vfd->vidioc_g_fmt_type_private(file,
-								fh, f);
-			break;
-		}
-
-		break;
-	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *f = (struct v4l2_format *)arg;
-
-		/* FIXME: Should be one dump per type */
-		dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
-
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-			v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			if (vfd->vidioc_s_fmt_vid_cap)
-				ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (vfd->vidioc_s_fmt_vid_overlay)
-				ret = vfd->vidioc_s_fmt_vid_overlay(file,
-								    fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			if (vfd->vidioc_s_fmt_vid_out)
-				ret = vfd->vidioc_s_fmt_vid_out(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-			if (vfd->vidioc_s_fmt_vid_out_overlay)
-				ret = vfd->vidioc_s_fmt_vid_out_overlay(file,
-					fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_CAPTURE:
-			if (vfd->vidioc_s_fmt_vbi_cap)
-				ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_OUTPUT:
-			if (vfd->vidioc_s_fmt_vbi_out)
-				ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-			if (vfd->vidioc_s_fmt_sliced_vbi_cap)
-				ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file,
-									fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-			if (vfd->vidioc_s_fmt_sliced_vbi_out)
-				ret = vfd->vidioc_s_fmt_sliced_vbi_out(file,
-									fh, f);
-			break;
-		case V4L2_BUF_TYPE_PRIVATE:
-			if (vfd->vidioc_s_fmt_type_private)
-				ret = vfd->vidioc_s_fmt_type_private(file,
-								fh, f);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_TRY_FMT:
-	{
-		struct v4l2_format *f = (struct v4l2_format *)arg;
-
-		/* FIXME: Should be one dump per type */
-		dbgarg (cmd, "type=%s\n", prt_names(f->type,
-						v4l2_type_names));
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-			if (vfd->vidioc_try_fmt_vid_cap)
-				ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f);
-			if (!ret)
-				v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (vfd->vidioc_try_fmt_vid_overlay)
-				ret = vfd->vidioc_try_fmt_vid_overlay(file,
-					fh, f);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			if (vfd->vidioc_try_fmt_vid_out)
-				ret = vfd->vidioc_try_fmt_vid_out(file, fh, f);
-			if (!ret)
-				v4l_print_pix_fmt(vfd, &f->fmt.pix);
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-			if (vfd->vidioc_try_fmt_vid_out_overlay)
-				ret = vfd->vidioc_try_fmt_vid_out_overlay(file,
-				       fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_CAPTURE:
-			if (vfd->vidioc_try_fmt_vbi_cap)
-				ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_VBI_OUTPUT:
-			if (vfd->vidioc_try_fmt_vbi_out)
-				ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-			if (vfd->vidioc_try_fmt_sliced_vbi_cap)
-				ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file,
-								fh, f);
-			break;
-		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-			if (vfd->vidioc_try_fmt_sliced_vbi_out)
-				ret = vfd->vidioc_try_fmt_sliced_vbi_out(file,
-								fh, f);
-			break;
-		case V4L2_BUF_TYPE_PRIVATE:
-			if (vfd->vidioc_try_fmt_type_private)
-				ret = vfd->vidioc_try_fmt_type_private(file,
-								fh, f);
-			break;
-		}
-
-		break;
-	}
-	/* FIXME: Those buf reqs could be handled here,
-	   with some changes on videobuf to allow its header to be included at
-	   videodev2.h or being merged at videodev2.
-	 */
-	case VIDIOC_REQBUFS:
-	{
-		struct v4l2_requestbuffers *p=arg;
-
-		if (!vfd->vidioc_reqbufs)
-			break;
-		ret = check_fmt (vfd, p->type);
-		if (ret)
-			break;
-
-		ret=vfd->vidioc_reqbufs(file, fh, p);
-		dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
-				p->count,
-				prt_names(p->type, v4l2_type_names),
-				prt_names(p->memory, v4l2_memory_names));
-		break;
-	}
-	case VIDIOC_QUERYBUF:
-	{
-		struct v4l2_buffer *p=arg;
-
-		if (!vfd->vidioc_querybuf)
-			break;
-		ret = check_fmt (vfd, p->type);
-		if (ret)
-			break;
-
-		ret=vfd->vidioc_querybuf(file, fh, p);
-		if (!ret)
-			dbgbuf(cmd,vfd,p);
-		break;
-	}
-	case VIDIOC_QBUF:
-	{
-		struct v4l2_buffer *p=arg;
-
-		if (!vfd->vidioc_qbuf)
-			break;
-		ret = check_fmt (vfd, p->type);
-		if (ret)
-			break;
-
-		ret=vfd->vidioc_qbuf(file, fh, p);
-		if (!ret)
-			dbgbuf(cmd,vfd,p);
-		break;
-	}
-	case VIDIOC_DQBUF:
-	{
-		struct v4l2_buffer *p=arg;
-		if (!vfd->vidioc_dqbuf)
-			break;
-		ret = check_fmt (vfd, p->type);
-		if (ret)
-			break;
-
-		ret=vfd->vidioc_dqbuf(file, fh, p);
-		if (!ret)
-			dbgbuf(cmd,vfd,p);
-		break;
-	}
-	case VIDIOC_OVERLAY:
-	{
-		int *i = arg;
-
-		if (!vfd->vidioc_overlay)
-			break;
-		dbgarg (cmd, "value=%d\n",*i);
-		ret=vfd->vidioc_overlay(file, fh, *i);
-		break;
-	}
-	case VIDIOC_G_FBUF:
-	{
-		struct v4l2_framebuffer *p = arg;
-
-		if (!vfd->vidioc_g_fbuf)
-			break;
-		ret = vfd->vidioc_g_fbuf(file, fh, arg);
-		if (!ret) {
-			dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
-					p->capability, p->flags,
-					(unsigned long)p->base);
-			v4l_print_pix_fmt(vfd, &p->fmt);
-		}
-		break;
-	}
-	case VIDIOC_S_FBUF:
-	{
-		struct v4l2_framebuffer *p = arg;
-
-		if (!vfd->vidioc_s_fbuf)
-			break;
-		dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
-			p->capability, p->flags, (unsigned long)p->base);
-		v4l_print_pix_fmt(vfd, &p->fmt);
-		ret = vfd->vidioc_s_fbuf(file, fh, arg);
-		break;
-	}
-	case VIDIOC_STREAMON:
-	{
-		enum v4l2_buf_type i = *(int *)arg;
-		if (!vfd->vidioc_streamon)
-			break;
-		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
-		ret=vfd->vidioc_streamon(file, fh,i);
-		break;
-	}
-	case VIDIOC_STREAMOFF:
-	{
-		enum v4l2_buf_type i = *(int *)arg;
-
-		if (!vfd->vidioc_streamoff)
-			break;
-		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
-		ret=vfd->vidioc_streamoff(file, fh, i);
-		break;
-	}
-	/* ---------- tv norms ---------- */
-	case VIDIOC_ENUMSTD:
-	{
-		struct v4l2_standard *p = arg;
-		v4l2_std_id id = vfd->tvnorms, curr_id = 0;
-		unsigned int index = p->index, i, j = 0;
-		const char *descr = "";
-
-		/* Return norm array in a canonical way */
-		for (i = 0; i <= index && id; i++) {
-			/* last std value in the standards array is 0, so this
-			   while always ends there since (id & 0) == 0. */
-			while ((id & standards[j].std) != standards[j].std)
-				j++;
-			curr_id = standards[j].std;
-			descr = standards[j].descr;
-			j++;
-			if (curr_id == 0)
-				break;
-			if (curr_id != V4L2_STD_PAL &&
-			    curr_id != V4L2_STD_SECAM &&
-			    curr_id != V4L2_STD_NTSC)
-				id &= ~curr_id;
-		}
-		if (i <= index)
-			return -EINVAL;
-
-		v4l2_video_std_construct(p, curr_id, descr);
-		p->index = index;
-
-		dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
-				"framelines=%d\n", p->index,
-				(unsigned long long)p->id, p->name,
-				p->frameperiod.numerator,
-				p->frameperiod.denominator,
-				p->framelines);
-
-		ret = 0;
-		break;
-	}
-	case VIDIOC_G_STD:
-	{
-		v4l2_std_id *id = arg;
-
-		ret = 0;
-		/* Calls the specific handler */
-		if (vfd->vidioc_g_std)
-			ret = vfd->vidioc_g_std(file, fh, id);
-		else
-			*id = vfd->current_norm;
-
-		if (!ret)
-			dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
-		break;
-	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *id = arg,norm;
-
-		dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
-
-		norm = (*id) & vfd->tvnorms;
-		if ( vfd->tvnorms && !norm)	/* Check if std is supported */
-			break;
-
-		/* Calls the specific handler */
-		if (vfd->vidioc_s_std)
-			ret=vfd->vidioc_s_std(file, fh, &norm);
-		else
-			ret=-EINVAL;
-
-		/* Updates standard information */
-		if (ret>=0)
-			vfd->current_norm=norm;
-
-		break;
-	}
-	case VIDIOC_QUERYSTD:
-	{
-		v4l2_std_id *p=arg;
-
-		if (!vfd->vidioc_querystd)
-			break;
-		ret=vfd->vidioc_querystd(file, fh, arg);
-		if (!ret)
-			dbgarg (cmd, "detected std=%08Lx\n",
-						(unsigned long long)*p);
-		break;
-	}
-	/* ------ input switching ---------- */
-	/* FIXME: Inputs can be handled inside videodev2 */
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input *p=arg;
-		int i=p->index;
-
-		if (!vfd->vidioc_enum_input)
-			break;
-		memset(p, 0, sizeof(*p));
-		p->index=i;
-
-		ret=vfd->vidioc_enum_input(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "index=%d, name=%s, type=%d, "
-					"audioset=%d, "
-					"tuner=%d, std=%08Lx, status=%d\n",
-					p->index,p->name,p->type,p->audioset,
-					p->tuner,
-					(unsigned long long)p->std,
-					p->status);
-		break;
-	}
-	case VIDIOC_G_INPUT:
-	{
-		unsigned int *i = arg;
-
-		if (!vfd->vidioc_g_input)
-			break;
-		ret=vfd->vidioc_g_input(file, fh, i);
-		if (!ret)
-			dbgarg (cmd, "value=%d\n",*i);
-		break;
-	}
-	case VIDIOC_S_INPUT:
-	{
-		unsigned int *i = arg;
-
-		if (!vfd->vidioc_s_input)
-			break;
-		dbgarg (cmd, "value=%d\n",*i);
-		ret=vfd->vidioc_s_input(file, fh, *i);
-		break;
-	}
-
-	/* ------ output switching ---------- */
-	case VIDIOC_ENUMOUTPUT:
-	{
-		struct v4l2_output *p = arg;
-		int i = p->index;
-
-		if (!vfd->vidioc_enum_output)
-			break;
-		memset(p, 0, sizeof(*p));
-		p->index = i;
-
-		ret = vfd->vidioc_enum_output(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "index=%d, name=%s, type=%d, "
-				"audioset=0x%x, "
-				"modulator=%d, std=0x%08Lx\n",
-				p->index, p->name, p->type, p->audioset,
-				p->modulator, (unsigned long long)p->std);
-		break;
-	}
-	case VIDIOC_G_OUTPUT:
-	{
-		unsigned int *i = arg;
-
-		if (!vfd->vidioc_g_output)
-			break;
-		ret=vfd->vidioc_g_output(file, fh, i);
-		if (!ret)
-			dbgarg (cmd, "value=%d\n",*i);
-		break;
-	}
-	case VIDIOC_S_OUTPUT:
-	{
-		unsigned int *i = arg;
-
-		if (!vfd->vidioc_s_output)
-			break;
-		dbgarg (cmd, "value=%d\n",*i);
-		ret=vfd->vidioc_s_output(file, fh, *i);
-		break;
-	}
-
-	/* --- controls ---------------------------------------------- */
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *p = arg;
-
-		if (!vfd->vidioc_queryctrl)
-			break;
-		ret = vfd->vidioc_queryctrl(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
-					"step=%d, default=%d, flags=0x%08x\n",
-					p->id, p->type, p->name,
-					p->minimum, p->maximum,
-					p->step, p->default_value, p->flags);
-		else
-			dbgarg(cmd, "id=0x%x\n", p->id);
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *p = arg;
-
-		if (vfd->vidioc_g_ctrl)
-			ret = vfd->vidioc_g_ctrl(file, fh, p);
-		else if (vfd->vidioc_g_ext_ctrls) {
-			struct v4l2_ext_controls ctrls;
-			struct v4l2_ext_control ctrl;
-
-			ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
-			ctrls.count = 1;
-			ctrls.controls = &ctrl;
-			ctrl.id = p->id;
-			ctrl.value = p->value;
-			if (check_ext_ctrls(&ctrls, 1)) {
-				ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
-				if (ret == 0)
-					p->value = ctrl.value;
-			}
-		} else
-			break;
-		if (!ret)
-			dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
-		else
-			dbgarg(cmd, "id=0x%x\n", p->id);
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *p = arg;
-		struct v4l2_ext_controls ctrls;
-		struct v4l2_ext_control ctrl;
-
-		if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls)
-			break;
-
-		dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
-
-		if (vfd->vidioc_s_ctrl) {
-			ret = vfd->vidioc_s_ctrl(file, fh, p);
-			break;
-		}
-		if (!vfd->vidioc_s_ext_ctrls)
-			break;
-
-		ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
-		ctrls.count = 1;
-		ctrls.controls = &ctrl;
-		ctrl.id = p->id;
-		ctrl.value = p->value;
-		if (check_ext_ctrls(&ctrls, 1))
-			ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
-		break;
-	}
-	case VIDIOC_G_EXT_CTRLS:
-	{
-		struct v4l2_ext_controls *p = arg;
-
-		p->error_idx = p->count;
-		if (!vfd->vidioc_g_ext_ctrls)
-			break;
-		if (check_ext_ctrls(p, 0))
-			ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
-		v4l_print_ext_ctrls(cmd, vfd, p, !ret);
-		break;
-	}
-	case VIDIOC_S_EXT_CTRLS:
-	{
-		struct v4l2_ext_controls *p = arg;
-
-		p->error_idx = p->count;
-		if (!vfd->vidioc_s_ext_ctrls)
-			break;
-		v4l_print_ext_ctrls(cmd, vfd, p, 1);
-		if (check_ext_ctrls(p, 0))
-			ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
-		break;
-	}
-	case VIDIOC_TRY_EXT_CTRLS:
-	{
-		struct v4l2_ext_controls *p = arg;
-
-		p->error_idx = p->count;
-		if (!vfd->vidioc_try_ext_ctrls)
-			break;
-		v4l_print_ext_ctrls(cmd, vfd, p, 1);
-		if (check_ext_ctrls(p, 0))
-			ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
-		break;
-	}
-	case VIDIOC_QUERYMENU:
-	{
-		struct v4l2_querymenu *p = arg;
-
-		if (!vfd->vidioc_querymenu)
-			break;
-		ret = vfd->vidioc_querymenu(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
-				p->id, p->index, p->name);
-		else
-			dbgarg(cmd, "id=0x%x, index=%d\n",
-				p->id, p->index);
-		break;
-	}
-	/* --- audio ---------------------------------------------- */
-	case VIDIOC_ENUMAUDIO:
-	{
-		struct v4l2_audio *p = arg;
-
-		if (!vfd->vidioc_enumaudio)
-			break;
-		ret = vfd->vidioc_enumaudio(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
-					"mode=0x%x\n", p->index, p->name,
-					p->capability, p->mode);
-		else
-			dbgarg(cmd, "index=%d\n", p->index);
-		break;
-	}
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *p = arg;
-		__u32 index = p->index;
-
-		if (!vfd->vidioc_g_audio)
-			break;
-
-		memset(p, 0, sizeof(*p));
-		p->index = index;
-		ret = vfd->vidioc_g_audio(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
-					"mode=0x%x\n", p->index,
-					p->name, p->capability, p->mode);
-		else
-			dbgarg(cmd, "index=%d\n", p->index);
-		break;
-	}
-	case VIDIOC_S_AUDIO:
-	{
-		struct v4l2_audio *p = arg;
-
-		if (!vfd->vidioc_s_audio)
-			break;
-		dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
-					"mode=0x%x\n", p->index, p->name,
-					p->capability, p->mode);
-		ret = vfd->vidioc_s_audio(file, fh, p);
-		break;
-	}
-	case VIDIOC_ENUMAUDOUT:
-	{
-		struct v4l2_audioout *p=arg;
-
-		if (!vfd->vidioc_enumaudout)
-			break;
-		dbgarg(cmd, "Enum for index=%d\n", p->index);
-		ret=vfd->vidioc_enumaudout(file, fh, p);
-		if (!ret)
-			dbgarg2("index=%d, name=%s, capability=%d, "
-					"mode=%d\n", p->index, p->name,
-					p->capability,p->mode);
-		break;
-	}
-	case VIDIOC_G_AUDOUT:
-	{
-		struct v4l2_audioout *p=arg;
-
-		if (!vfd->vidioc_g_audout)
-			break;
-		dbgarg(cmd, "Enum for index=%d\n", p->index);
-		ret=vfd->vidioc_g_audout(file, fh, p);
-		if (!ret)
-			dbgarg2("index=%d, name=%s, capability=%d, "
-					"mode=%d\n", p->index, p->name,
-					p->capability,p->mode);
-		break;
-	}
-	case VIDIOC_S_AUDOUT:
-	{
-		struct v4l2_audioout *p=arg;
-
-		if (!vfd->vidioc_s_audout)
-			break;
-		dbgarg(cmd, "index=%d, name=%s, capability=%d, "
-					"mode=%d\n", p->index, p->name,
-					p->capability,p->mode);
-
-		ret=vfd->vidioc_s_audout(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_MODULATOR:
-	{
-		struct v4l2_modulator *p=arg;
-		if (!vfd->vidioc_g_modulator)
-			break;
-		ret=vfd->vidioc_g_modulator(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "index=%d, name=%s, "
-					"capability=%d, rangelow=%d,"
-					" rangehigh=%d, txsubchans=%d\n",
-					p->index, p->name,p->capability,
-					p->rangelow, p->rangehigh,
-					p->txsubchans);
-		break;
-	}
-	case VIDIOC_S_MODULATOR:
-	{
-		struct v4l2_modulator *p=arg;
-		if (!vfd->vidioc_s_modulator)
-			break;
-		dbgarg(cmd, "index=%d, name=%s, capability=%d, "
-				"rangelow=%d, rangehigh=%d, txsubchans=%d\n",
-				p->index, p->name,p->capability,p->rangelow,
-				p->rangehigh,p->txsubchans);
-			ret=vfd->vidioc_s_modulator(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_CROP:
-	{
-		struct v4l2_crop *p=arg;
-		if (!vfd->vidioc_g_crop)
-			break;
-		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-		ret=vfd->vidioc_g_crop(file, fh, p);
-		if (!ret) {
-			dbgrect(vfd, "", &p->c);
-		}
-		break;
-	}
-	case VIDIOC_S_CROP:
-	{
-		struct v4l2_crop *p=arg;
-		if (!vfd->vidioc_s_crop)
-			break;
-		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-		dbgrect(vfd, "", &p->c);
-		ret=vfd->vidioc_s_crop(file, fh, p);
-		break;
-	}
-	case VIDIOC_CROPCAP:
-	{
-		struct v4l2_cropcap *p = arg;
-
-		/*FIXME: Should also show v4l2_fract pixelaspect */
-		if (!vfd->vidioc_cropcap)
-			break;
-		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-		ret = vfd->vidioc_cropcap(file, fh, p);
-		if (!ret) {
-			dbgrect(vfd, "bounds ", &p->bounds);
-			dbgrect(vfd, "defrect ", &p->defrect);
-		}
-		break;
-	}
-	case VIDIOC_G_JPEGCOMP:
-	{
-		struct v4l2_jpegcompression *p=arg;
-		if (!vfd->vidioc_g_jpegcomp)
-			break;
-		ret=vfd->vidioc_g_jpegcomp(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "quality=%d, APPn=%d, "
-						"APP_len=%d, COM_len=%d, "
-						"jpeg_markers=%d\n",
-						p->quality,p->APPn,p->APP_len,
-						p->COM_len,p->jpeg_markers);
-		break;
-	}
-	case VIDIOC_S_JPEGCOMP:
-	{
-		struct v4l2_jpegcompression *p=arg;
-		if (!vfd->vidioc_g_jpegcomp)
-			break;
-		dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
-					"COM_len=%d, jpeg_markers=%d\n",
-					p->quality,p->APPn,p->APP_len,
-					p->COM_len,p->jpeg_markers);
-			ret=vfd->vidioc_s_jpegcomp(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_ENC_INDEX:
-	{
-		struct v4l2_enc_idx *p=arg;
-
-		if (!vfd->vidioc_g_enc_index)
-			break;
-		ret=vfd->vidioc_g_enc_index(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "entries=%d, entries_cap=%d\n",
-					p->entries,p->entries_cap);
-		break;
-	}
-	case VIDIOC_ENCODER_CMD:
-	{
-		struct v4l2_encoder_cmd *p = arg;
-
-		if (!vfd->vidioc_encoder_cmd)
-			break;
-		memset(&p->raw, 0, sizeof(p->raw));
-		ret = vfd->vidioc_encoder_cmd(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
-		break;
-	}
-	case VIDIOC_TRY_ENCODER_CMD:
-	{
-		struct v4l2_encoder_cmd *p = arg;
-
-		if (!vfd->vidioc_try_encoder_cmd)
-			break;
-		memset(&p->raw, 0, sizeof(p->raw));
-		ret = vfd->vidioc_try_encoder_cmd(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
-		break;
-	}
-	case VIDIOC_G_PARM:
-	{
-		struct v4l2_streamparm *p=arg;
-		__u32 type=p->type;
-
-		memset(p,0,sizeof(*p));
-		p->type=type;
-
-		if (vfd->vidioc_g_parm) {
-			ret=vfd->vidioc_g_parm(file, fh, p);
-		} else {
-			struct v4l2_standard s;
-
-			if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-				return -EINVAL;
-
-			v4l2_video_std_construct(&s, vfd->current_norm,
-						 v4l2_norm_to_name(vfd->current_norm));
-
-			p->parm.capture.timeperframe = s.frameperiod;
-			ret=0;
-		}
-
-		dbgarg (cmd, "type=%d\n", p->type);
-		break;
-	}
-	case VIDIOC_S_PARM:
-	{
-		struct v4l2_streamparm *p=arg;
-		if (!vfd->vidioc_s_parm)
-			break;
-		dbgarg (cmd, "type=%d\n", p->type);
-		ret=vfd->vidioc_s_parm(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *p = arg;
-		__u32 index = p->index;
-
-		if (!vfd->vidioc_g_tuner)
-			break;
-
-		memset(p, 0, sizeof(*p));
-		p->index = index;
-
-		ret = vfd->vidioc_g_tuner(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "index=%d, name=%s, type=%d, "
-					"capability=0x%x, rangelow=%d, "
-					"rangehigh=%d, signal=%d, afc=%d, "
-					"rxsubchans=0x%x, audmode=%d\n",
-					p->index, p->name, p->type,
-					p->capability, p->rangelow,
-					p->rangehigh, p->signal, p->afc,
-					p->rxsubchans, p->audmode);
-		break;
-	}
-	case VIDIOC_S_TUNER:
-	{
-		struct v4l2_tuner *p = arg;
-
-		if (!vfd->vidioc_s_tuner)
-			break;
-		dbgarg(cmd, "index=%d, name=%s, type=%d, "
-				"capability=0x%x, rangelow=%d, "
-				"rangehigh=%d, signal=%d, afc=%d, "
-				"rxsubchans=0x%x, audmode=%d\n",
-				p->index, p->name, p->type,
-				p->capability, p->rangelow,
-				p->rangehigh, p->signal, p->afc,
-				p->rxsubchans, p->audmode);
-		ret = vfd->vidioc_s_tuner(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_FREQUENCY:
-	{
-		struct v4l2_frequency *p = arg;
-
-		if (!vfd->vidioc_g_frequency)
-			break;
-
-		memset(p->reserved, 0, sizeof(p->reserved));
-
-		ret = vfd->vidioc_g_frequency(file, fh, p);
-		if (!ret)
-			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
-					p->tuner, p->type, p->frequency);
-		break;
-	}
-	case VIDIOC_S_FREQUENCY:
-	{
-		struct v4l2_frequency *p=arg;
-		if (!vfd->vidioc_s_frequency)
-			break;
-		dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
-				p->tuner,p->type,p->frequency);
-		ret=vfd->vidioc_s_frequency(file, fh, p);
-		break;
-	}
-	case VIDIOC_G_SLICED_VBI_CAP:
-	{
-		struct v4l2_sliced_vbi_cap *p = arg;
-		__u32 type = p->type;
-
-		if (!vfd->vidioc_g_sliced_vbi_cap)
-			break;
-		memset(p, 0, sizeof(*p));
-		p->type = type;
-		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-		ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
-		if (!ret)
-			dbgarg2("service_set=%d\n", p->service_set);
-		break;
-	}
-	case VIDIOC_LOG_STATUS:
-	{
-		if (!vfd->vidioc_log_status)
-			break;
-		ret=vfd->vidioc_log_status(file, fh);
-		break;
-	}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	case VIDIOC_DBG_G_REGISTER:
-	{
-		struct v4l2_register *p=arg;
-		if (!capable(CAP_SYS_ADMIN))
-			ret=-EPERM;
-		else if (vfd->vidioc_g_register)
-			ret=vfd->vidioc_g_register(file, fh, p);
-		break;
-	}
-	case VIDIOC_DBG_S_REGISTER:
-	{
-		struct v4l2_register *p=arg;
-		if (!capable(CAP_SYS_ADMIN))
-			ret=-EPERM;
-		else if (vfd->vidioc_s_register)
-			ret=vfd->vidioc_s_register(file, fh, p);
-		break;
-	}
-#endif
-	case VIDIOC_G_CHIP_IDENT:
-	{
-		struct v4l2_chip_ident *p=arg;
-		if (!vfd->vidioc_g_chip_ident)
-			break;
-		ret=vfd->vidioc_g_chip_ident(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
-		break;
-	}
-	default:
-	{
-		if (!vfd->vidioc_default)
-			break;
-		ret = vfd->vidioc_default(file, fh, cmd, arg);
-		break;
-	}
-	case VIDIOC_S_HW_FREQ_SEEK:
-	{
-		struct v4l2_hw_freq_seek *p = arg;
-		if (!vfd->vidioc_s_hw_freq_seek)
-			break;
-		dbgarg(cmd,
-			"tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
-			p->tuner, p->type, p->seek_upward, p->wrap_around);
-		ret = vfd->vidioc_s_hw_freq_seek(file, fh, p);
-		break;
-	}
-	} /* switch */
-
-	if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
-		if (ret < 0) {
-			v4l_print_ioctl(vfd->name, cmd);
-			printk(KERN_CONT " error %d\n", ret);
-		}
-	}
-
-	return ret;
-}
-
-int video_ioctl2 (struct inode *inode, struct file *file,
-	       unsigned int cmd, unsigned long arg)
-{
-	char	sbuf[128];
-	void    *mbuf = NULL;
-	void	*parg = NULL;
-	int	err  = -EINVAL;
-	int     is_ext_ctrl;
-	size_t  ctrls_size = 0;
-	void __user *user_ptr = NULL;
-
-#ifdef __OLD_VIDIOC_
-	cmd = video_fix_command(cmd);
-#endif
-	is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
-		       cmd == VIDIOC_TRY_EXT_CTRLS);
-
-	/*  Copy arguments into temp kernel buffer  */
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:
-		parg = NULL;
-		break;
-	case _IOC_READ:
-	case _IOC_WRITE:
-	case (_IOC_WRITE | _IOC_READ):
-		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
-			parg = sbuf;
-		} else {
-			/* too big to allocate from stack */
-			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
-			if (NULL == mbuf)
-				return -ENOMEM;
-			parg = mbuf;
-		}
-
-		err = -EFAULT;
-		if (_IOC_DIR(cmd) & _IOC_WRITE)
-			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
-				goto out;
-		break;
-	}
-
-	if (is_ext_ctrl) {
-		struct v4l2_ext_controls *p = parg;
-
-		/* In case of an error, tell the caller that it wasn't
-		   a specific control that caused it. */
-		p->error_idx = p->count;
-		user_ptr = (void __user *)p->controls;
-		if (p->count) {
-			ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
-			/* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
-			mbuf = kmalloc(ctrls_size, GFP_KERNEL);
-			err = -ENOMEM;
-			if (NULL == mbuf)
-				goto out_ext_ctrl;
-			err = -EFAULT;
-			if (copy_from_user(mbuf, user_ptr, ctrls_size))
-				goto out_ext_ctrl;
-			p->controls = mbuf;
-		}
-	}
-
-	/* Handles IOCTL */
-	err = __video_do_ioctl(inode, file, cmd, parg);
-	if (err == -ENOIOCTLCMD)
-		err = -EINVAL;
-	if (is_ext_ctrl) {
-		struct v4l2_ext_controls *p = parg;
-
-		p->controls = (void *)user_ptr;
-		if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
-			err = -EFAULT;
-		goto out_ext_ctrl;
-	}
-	if (err < 0)
-		goto out;
-
-out_ext_ctrl:
-	/*  Copy results into user buffer  */
-	switch (_IOC_DIR(cmd))
-	{
-	case _IOC_READ:
-	case (_IOC_WRITE | _IOC_READ):
-		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
-			err = -EFAULT;
-		break;
-	}
-
-out:
-	kfree(mbuf);
-	return err;
-}
-EXPORT_SYMBOL(video_ioctl2);
-
-/**
- * get_index - assign stream number based on parent device
- * @vdev: video_device to assign index number to, vdev->dev should be assigned
- * @num: -1 if auto assign, requested number otherwise
- *
- *
- * returns -ENFILE if num is already in use, a free index number if
- * successful.
- */
-static int get_index(struct video_device *vdev, int num)
-{
-	u32 used = 0;
-	const int max_index = sizeof(used) * 8 - 1;
-	int i;
-
-	/* Currently a single v4l driver instance cannot create more than
-	   32 devices.
-	   Increase to u64 or an array of u32 if more are needed. */
-	if (num > max_index) {
-		printk(KERN_ERR "videodev: %s num is too large\n", __func__);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
-		if (video_device[i] != NULL &&
-		    video_device[i] != vdev &&
-		    video_device[i]->dev == vdev->dev) {
-			used |= 1 << video_device[i]->index;
-		}
-	}
-
-	if (num >= 0) {
-		if (used & (1 << num))
-			return -ENFILE;
-		return num;
-	}
-
-	i = ffz(used);
-	return i > max_index ? -ENFILE : i;
-}
-
-static const struct file_operations video_fops;
-
-int video_register_device(struct video_device *vfd, int type, int nr)
-{
-	return video_register_device_index(vfd, type, nr, -1);
-}
-EXPORT_SYMBOL(video_register_device);
-
-/**
- *	video_register_device - register video4linux devices
- *	@vfd:  video device structure we want to register
- *	@type: type of device to register
- *	@nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
- *             -1 == first free)
- *
- *	The registration code assigns minor numbers based on the type
- *	requested. -ENFILE is returned in all the device slots for this
- *	category are full. If not then the minor field is set and the
- *	driver initialize function is called (if non %NULL).
- *
- *	Zero is returned on success.
- *
- *	Valid types are
- *
- *	%VFL_TYPE_GRABBER - A frame grabber
- *
- *	%VFL_TYPE_VTX - A teletext device
- *
- *	%VFL_TYPE_VBI - Vertical blank data (undecoded)
- *
- *	%VFL_TYPE_RADIO - A radio card
- */
-
-int video_register_device_index(struct video_device *vfd, int type, int nr,
-					int index)
-{
-	int i=0;
-	int base;
-	int end;
-	int ret;
-	char *name_base;
-
-	switch(type)
-	{
-		case VFL_TYPE_GRABBER:
-			base=MINOR_VFL_TYPE_GRABBER_MIN;
-			end=MINOR_VFL_TYPE_GRABBER_MAX+1;
-			name_base = "video";
-			break;
-		case VFL_TYPE_VTX:
-			base=MINOR_VFL_TYPE_VTX_MIN;
-			end=MINOR_VFL_TYPE_VTX_MAX+1;
-			name_base = "vtx";
-			break;
-		case VFL_TYPE_VBI:
-			base=MINOR_VFL_TYPE_VBI_MIN;
-			end=MINOR_VFL_TYPE_VBI_MAX+1;
-			name_base = "vbi";
-			break;
-		case VFL_TYPE_RADIO:
-			base=MINOR_VFL_TYPE_RADIO_MIN;
-			end=MINOR_VFL_TYPE_RADIO_MAX+1;
-			name_base = "radio";
-			break;
-		default:
-			printk(KERN_ERR "%s called with unknown type: %d\n",
-			       __func__, type);
-			return -1;
-	}
-
-	/* pick a minor number */
-	mutex_lock(&videodev_lock);
-	if (nr >= 0  &&  nr < end-base) {
-		/* use the one the driver asked for */
-		i = base+nr;
-		if (NULL != video_device[i]) {
-			mutex_unlock(&videodev_lock);
-			return -ENFILE;
-		}
-	} else {
-		/* use first free */
-		for(i=base;i<end;i++)
-			if (NULL == video_device[i])
-				break;
-		if (i == end) {
-			mutex_unlock(&videodev_lock);
-			return -ENFILE;
-		}
-	}
-	video_device[i]=vfd;
-	vfd->minor=i;
-
-	ret = get_index(vfd, index);
-	vfd->index = ret;
-
-	mutex_unlock(&videodev_lock);
-
-	if (ret < 0) {
-		printk(KERN_ERR "%s: get_index failed\n", __func__);
-		goto fail_minor;
-	}
-
-	mutex_init(&vfd->lock);
-
-	/* sysfs class */
-	memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
-	vfd->class_dev.class       = &video_class;
-	vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
-	if (vfd->dev)
-		vfd->class_dev.parent = vfd->dev;
-	sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
-	ret = device_register(&vfd->class_dev);
-	if (ret < 0) {
-		printk(KERN_ERR "%s: device_register failed\n", __func__);
-		goto fail_minor;
-	}
-
-#if 1
-	/* needed until all drivers are fixed */
-	if (!vfd->release)
-		printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
-		       "Please fix your driver for proper sysfs support, see "
-		       "http://lwn.net/Articles/36850/\n", vfd->name);
-#endif
-	return 0;
-
-fail_minor:
-	mutex_lock(&videodev_lock);
-	video_device[vfd->minor] = NULL;
-	vfd->minor = -1;
-	mutex_unlock(&videodev_lock);
-	return ret;
-}
-EXPORT_SYMBOL(video_register_device_index);
-
-/**
- *	video_unregister_device - unregister a video4linux device
- *	@vfd: the device to unregister
- *
- *	This unregisters the passed device and deassigns the minor
- *	number. Future open calls will be met with errors.
- */
-
-void video_unregister_device(struct video_device *vfd)
-{
-	mutex_lock(&videodev_lock);
-	if(video_device[vfd->minor]!=vfd)
-		panic("videodev: bad unregister");
-
-	video_device[vfd->minor]=NULL;
-	device_unregister(&vfd->class_dev);
-	mutex_unlock(&videodev_lock);
-}
-EXPORT_SYMBOL(video_unregister_device);
-
-/*
- * Video fs operations
- */
-static const struct file_operations video_fops=
-{
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.open		= video_open,
-};
-
-/*
- *	Initialise video for linux
- */
-
-static int __init videodev_init(void)
-{
-	int ret;
-
-	printk(KERN_INFO "Linux video capture interface: v2.00\n");
-	if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
-		printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
-		return -EIO;
-	}
-
-	ret = class_register(&video_class);
-	if (ret < 0) {
-		unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
-		printk(KERN_WARNING "video_dev: class_register failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void __exit videodev_exit(void)
-{
-	class_unregister(&video_class);
-	unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
-}
-
-module_init(videodev_init)
-module_exit(videodev_exit)
-
-MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
-MODULE_LICENSE("GPL");
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 01ea99c..3989b0e 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -38,7 +38,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-sgi.h>
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/video_decoder.h>
 #include <linux/mutex.h>
@@ -4385,8 +4385,6 @@
 
 static struct video_device v4l_device_template = {
 	.name		= "NOT SET",
-	/*.type		= VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | */
-	/*	VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY */
 	.fops		= &vino_fops,
 	.minor		= -1,
 };
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 059b01c..3518af0 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/freezer.h>
@@ -1065,13 +1066,7 @@
 	.llseek         = no_llseek,
 };
 
-static struct video_device vivi_template = {
-	.name		= "vivi",
-	.type		= VID_TYPE_CAPTURE,
-	.fops           = &vivi_fops,
-	.minor		= -1,
-	.release	= video_device_release,
-
+static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
 	.vidioc_querycap      = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
@@ -1093,6 +1088,15 @@
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	.vidiocgmbuf          = vidiocgmbuf,
 #endif
+};
+
+static struct video_device vivi_template = {
+	.name		= "vivi",
+	.fops           = &vivi_fops,
+	.ioctl_ops 	= &vivi_ioctl_ops,
+	.minor		= -1,
+	.release	= video_device_release,
+
 	.tvnorms              = V4L2_STD_525_60,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index cbecb3c..577956c 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -27,7 +27,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 33f7026..9402f40 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -57,8 +57,9 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/parport.h>
 
 /*#define DEBUG*/				/* Undef me for production */
@@ -195,9 +196,7 @@
 	.llseek         = no_llseek,
 };
 static struct video_device w9966_template = {
-	.owner		= THIS_MODULE,
 	.name           = W9966_DRIVERNAME,
-	.type           = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
 	.fops           = &w9966_fops,
 };
 
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 8405224..168baab 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -42,6 +42,7 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <linux/page-flags.h>
+#include <media/v4l2-ioctl.h>
 
 #include "w9968cf.h"
 #include "w9968cf_decoder.h"
@@ -3549,13 +3550,11 @@
 	}
 
 	strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
-	cam->v4ldev->owner = THIS_MODULE;
-	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
 	cam->v4ldev->fops = &w9968cf_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	video_set_drvdata(cam->v4ldev, cam);
-	cam->v4ldev->dev = &cam->dev;
+	cam->v4ldev->parent = &cam->dev;
 
 	err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
 				    video_nr[dev_nr]);
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
index 3c95316..30032e1 100644
--- a/drivers/media/video/w9968cf.h
+++ b/drivers/media/video/w9968cf.h
@@ -21,7 +21,7 @@
 #ifndef _W9968CF_H_
 #define _W9968CF_H_
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 7be47a2..95c79ad 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -27,7 +27,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index c2ab70a..48df661 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -31,7 +31,7 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv-legacy.h>
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h
index 7bbab54..b1b5cce 100644
--- a/drivers/media/video/zc0301/zc0301.h
+++ b/drivers/media/video/zc0301/zc0301.h
@@ -25,6 +25,7 @@
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index e5c4e9f..550ce7b 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1985,8 +1985,6 @@
 	}
 
 	strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
-	cam->v4ldev->owner = THIS_MODULE;
-	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
 	cam->v4ldev->fops = &zc0301_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 0929edb..d842a7c 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -161,7 +161,7 @@
 MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
 
 int zoran_num;			/* number of Buzs in use */
-struct zoran zoran[BUZ_MAX];
+struct zoran *zoran[BUZ_MAX];
 
 /* videocodec bus functions ZR36060 */
 static u32
@@ -355,9 +355,15 @@
 	case I2C_DRIVERID_BT856:
 		name = "bt856";
 		break;
+	case I2C_DRIVERID_BT866:
+		name = "bt866";
+		break;
 	case I2C_DRIVERID_VPX3220:
 		name = "vpx3220";
 		break;
+	case I2C_DRIVERID_KS0127:
+		name = "ks0127";
+		break;
 	}
 
 	return name;
@@ -1164,7 +1170,7 @@
 zoran_release (struct zoran *zr)
 {
 	if (!zr->initialized)
-		return;
+		goto exit_free;
 	/* unregister videocodec bus */
 	if (zr->codec) {
 		struct videocodec_master *master = zr->codec->master_data;
@@ -1192,6 +1198,8 @@
 	iounmap(zr->zr36057_mem);
 	pci_disable_device(zr->pci_dev);
 	video_unregister_device(zr->video_dev);
+exit_free:
+	kfree(zr);
 }
 
 void
@@ -1269,8 +1277,14 @@
 	while (zoran_num < BUZ_MAX &&
 	       (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
 		card_num = card[zoran_num];
-		zr = &zoran[zoran_num];
-		memset(zr, 0, sizeof(struct zoran));	// Just in case if previous cycle failed
+		zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+		if (!zr) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - kzalloc failed\n",
+				ZORAN_NAME);
+			continue;
+		}
 		zr->pci_dev = dev;
 		//zr->zr36057_mem = NULL;
 		zr->id = zoran_num;
@@ -1278,7 +1292,7 @@
 		spin_lock_init(&zr->spinlock);
 		mutex_init(&zr->resource_lock);
 		if (pci_enable_device(dev))
-			continue;
+			goto zr_free_mem;
 		zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
 		pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
 				     &zr->revision);
@@ -1294,7 +1308,7 @@
 					KERN_ERR
 					"%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
 					ZR_DEVNAME(zr));
-				continue;
+				goto zr_free_mem;
 			}
 		} else {
 			int i;
@@ -1333,7 +1347,7 @@
 						KERN_ERR
 						"%s: find_zr36057() - unknown card\n",
 						ZR_DEVNAME(zr));
-					continue;
+					goto zr_free_mem;
 				}
 			}
 		}
@@ -1343,7 +1357,7 @@
 				KERN_ERR
 				"%s: find_zr36057() - invalid cardnum %d\n",
 				ZR_DEVNAME(zr), card_num);
-			continue;
+			goto zr_free_mem;
 		}
 
 		/* even though we make this a non pointer and thus
@@ -1361,7 +1375,7 @@
 				KERN_ERR
 				"%s: find_zr36057() - ioremap failed\n",
 				ZR_DEVNAME(zr));
-			continue;
+			goto zr_free_mem;
 		}
 
 		result = request_irq(zr->pci_dev->irq,
@@ -1530,7 +1544,7 @@
 		}
 		/* Success so keep the pci_dev referenced */
 		pci_dev_get(zr->pci_dev);
-		zoran_num++;
+		zoran[zoran_num++] = zr;
 		continue;
 
 		// Init errors
@@ -1549,6 +1563,8 @@
 		free_irq(zr->pci_dev->irq, zr);
 	      zr_unmap:
 		iounmap(zr->zr36057_mem);
+	      zr_free_mem:
+		kfree(zr);
 		continue;
 	}
 	if (dev)	/* Clean up ref count on early exit */
@@ -1620,7 +1636,7 @@
 
 	/* take care of Natoma chipset and a revision 1 zr36057 */
 	for (i = 0; i < zoran_num; i++) {
-		struct zoran *zr = &zoran[i];
+		struct zoran *zr = zoran[i];
 
 		if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
 			zr->jpg_buffers.need_contiguous = 1;
@@ -1632,7 +1648,7 @@
 
 		if (zr36057_init(zr) < 0) {
 			for (i = 0; i < zoran_num; i++)
-				zoran_release(&zoran[i]);
+				zoran_release(zoran[i]);
 			return -EIO;
 		}
 		zoran_proc_init(zr);
@@ -1647,7 +1663,7 @@
 	int i;
 
 	for (i = 0; i < zoran_num; i++)
-		zoran_release(&zoran[i]);
+		zoran_release(zoran[i]);
 }
 
 module_init(init_dc10_cards);
diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h
index 1b5c417..e4dc9d2 100644
--- a/drivers/media/video/zoran_card.h
+++ b/drivers/media/video/zoran_card.h
@@ -41,7 +41,7 @@
 /* Anybody who uses more than four? */
 #define BUZ_MAX 4
 extern int zoran_num;
-extern struct zoran zoran[BUZ_MAX];
+extern struct zoran *zoran[BUZ_MAX];
 
 extern struct video_device zoran_template;
 
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index c067592..ec6f596 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -71,6 +71,7 @@
 
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include "videocodec.h"
 
 #include <asm/byteorder.h>
@@ -1212,8 +1213,8 @@
 
 	/* find the device */
 	for (i = 0; i < zoran_num; i++) {
-		if (zoran[i].video_dev->minor == minor) {
-			zr = &zoran[i];
+		if (zoran[i]->video_dev->minor == minor) {
+			zr = zoran[i];
 			break;
 		}
 	}
@@ -4643,8 +4644,6 @@
 
 struct video_device zoran_template __devinitdata = {
 	.name = ZORAN_NAME,
-	.type = ZORAN_VID_TYPE,
-	.type2 = ZORAN_V4L2_VID_FLAGS,
 	.fops = &zoran_fops,
 	.release = &zoran_vdev_release,
 	.minor = -1
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 485df2e..18d1c4b 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -35,6 +35,7 @@
 #include <linux/proc_fs.h>
 #include <linux/highmem.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 
 /* Version Information */
@@ -761,14 +762,7 @@
 	.llseek = no_llseek,
 };
 
-static struct video_device zr364xx_template = {
-	.owner = THIS_MODULE,
-	.name = DRIVER_DESC,
-	.type = VID_TYPE_CAPTURE,
-	.fops = &zr364xx_fops,
-	.release = video_device_release,
-	.minor = -1,
-
+static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
 	.vidioc_querycap	= zr364xx_vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	= zr364xx_vidioc_try_fmt_vid_cap,
@@ -784,6 +778,14 @@
 	.vidioc_s_ctrl		= zr364xx_vidioc_s_ctrl,
 };
 
+static struct video_device zr364xx_template = {
+	.name = DRIVER_DESC,
+	.fops = &zr364xx_fops,
+	.ioctl_ops = &zr364xx_ioctl_ops,
+	.release = video_device_release,
+	.minor = -1,
+};
+
 
 
 /*******************/
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 9385a56..15a653d 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -17,6 +17,21 @@
 
 #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
 
+#define VID_TYPE_CAPTURE	1	/* Can capture */
+#define VID_TYPE_TUNER		2	/* Can tune */
+#define VID_TYPE_TELETEXT	4	/* Does teletext */
+#define VID_TYPE_OVERLAY	8	/* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY	16	/* Overlay by chromakey */
+#define VID_TYPE_CLIPPING	32	/* Can clip */
+#define VID_TYPE_FRAMERAM	64	/* Uses the frame buffer memory */
+#define VID_TYPE_SCALES		128	/* Scalable */
+#define VID_TYPE_MONOCHROME	256	/* Monochrome only */
+#define VID_TYPE_SUBCAPTURE	512	/* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER	1024	/* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER	2048	/* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER	4096	/* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER	8192	/* Can encode MJPEG streams */
+
 struct video_capability
 {
 	char name[32];
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 2e66a95..e466bd5 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -71,6 +71,11 @@
  */
 #define VIDEO_MAX_FRAME               32
 
+#ifndef __KERNEL__
+
+/* These defines are V4L1 specific and should not be used with the V4L2 API!
+   They will be removed from this header in the future. */
+
 #define VID_TYPE_CAPTURE	1	/* Can capture */
 #define VID_TYPE_TUNER		2	/* Can tune */
 #define VID_TYPE_TELETEXT	4	/* Does teletext */
@@ -85,14 +90,15 @@
 #define VID_TYPE_MPEG_ENCODER	2048	/* Can encode MPEG streams */
 #define VID_TYPE_MJPEG_DECODER	4096	/* Can decode MJPEG streams */
 #define VID_TYPE_MJPEG_ENCODER	8192	/* Can encode MJPEG streams */
+#endif
 
 /*
  *	M I S C E L L A N E O U S
  */
 
 /*  Four-character-code (FOURCC) */
-#define v4l2_fourcc(a,b,c,d)\
-	(((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+#define v4l2_fourcc(a, b, c, d)\
+	((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))
 
 /*
  *	E N U M S
@@ -226,8 +232,7 @@
 /*
  *	D R I V E R   C A P A B I L I T I E S
  */
-struct v4l2_capability
-{
+struct v4l2_capability {
 	__u8	driver[16];	/* i.e. "bttv" */
 	__u8	card[32];	/* i.e. "Hauppauge WinTV" */
 	__u8	bus_info[32];	/* "PCI:" + pci_name(pci_dev) */
@@ -259,8 +264,7 @@
 /*
  *	V I D E O   I M A G E   F O R M A T
  */
-struct v4l2_pix_format
-{
+struct v4l2_pix_format {
 	__u32         		width;
 	__u32			height;
 	__u32			pixelformat;
@@ -272,68 +276,69 @@
 };
 
 /*      Pixel format         FOURCC                        depth  Description  */
-#define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R','G','B','1') /*  8  RGB-3-3-2     */
-#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R','4','4','4') /* 16  xxxxrrrr ggggbbbb */
-#define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R','G','B','O') /* 16  RGB-5-5-5     */
-#define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R','G','B','P') /* 16  RGB-5-6-5     */
-#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16  RGB-5-5-5 BE  */
-#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16  RGB-5-6-5 BE  */
-#define V4L2_PIX_FMT_BGR24   v4l2_fourcc('B','G','R','3') /* 24  BGR-8-8-8     */
-#define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R','G','B','3') /* 24  RGB-8-8-8     */
-#define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B','G','R','4') /* 32  BGR-8-8-8-8   */
-#define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R','G','B','4') /* 32  RGB-8-8-8-8   */
-#define V4L2_PIX_FMT_GREY    v4l2_fourcc('G','R','E','Y') /*  8  Greyscale     */
-#define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y','1','6',' ') /* 16  Greyscale     */
-#define V4L2_PIX_FMT_PAL8    v4l2_fourcc('P','A','L','8') /*  8  8-bit palette */
-#define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y','V','U','9') /*  9  YVU 4:1:0     */
-#define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y','V','1','2') /* 12  YVU 4:2:0     */
-#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y','U','Y','V') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U','Y','V','Y') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16  YVU422 planar */
-#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16  YVU411 planar */
-#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y','4','1','P') /* 12  YUV 4:1:1     */
-#define V4L2_PIX_FMT_YUV444  v4l2_fourcc('Y','4','4','4') /* 16  xxxxyyyy uuuuvvvv */
-#define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y','U','V','O') /* 16  YUV-5-5-5     */
-#define V4L2_PIX_FMT_YUV565  v4l2_fourcc('Y','U','V','P') /* 16  YUV-5-6-5     */
-#define V4L2_PIX_FMT_YUV32   v4l2_fourcc('Y','U','V','4') /* 32  YUV-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R', 'G', 'B', '1') /*  8  RGB-3-3-2     */
+#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R', '4', '4', '4') /* 16  xxxxrrrr ggggbbbb */
+#define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R', 'G', 'B', 'O') /* 16  RGB-5-5-5     */
+#define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R', 'G', 'B', 'P') /* 16  RGB-5-6-5     */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16  RGB-5-5-5 BE  */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16  RGB-5-6-5 BE  */
+#define V4L2_PIX_FMT_BGR24   v4l2_fourcc('B', 'G', 'R', '3') /* 24  BGR-8-8-8     */
+#define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R', 'G', 'B', '3') /* 24  RGB-8-8-8     */
+#define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B', 'G', 'R', '4') /* 32  BGR-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R', 'G', 'B', '4') /* 32  RGB-8-8-8-8   */
+#define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /*  8  Greyscale     */
+#define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale     */
+#define V4L2_PIX_FMT_PAL8    v4l2_fourcc('P', 'A', 'L', '8') /*  8  8-bit palette */
+#define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y', 'V', 'U', '9') /*  9  YVU 4:1:0     */
+#define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
+#define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16  YVU411 planar */
+#define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y', '4', '1', 'P') /* 12  YUV 4:1:1     */
+#define V4L2_PIX_FMT_YUV444  v4l2_fourcc('Y', '4', '4', '4') /* 16  xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y', 'U', 'V', 'O') /* 16  YUV-5-5-5     */
+#define V4L2_PIX_FMT_YUV565  v4l2_fourcc('Y', 'U', 'V', 'P') /* 16  YUV-5-6-5     */
+#define V4L2_PIX_FMT_YUV32   v4l2_fourcc('Y', 'U', 'V', '4') /* 32  YUV-8-8-8-8   */
 
 /* two planes -- one Y, one Cr + Cb interleaved  */
-#define V4L2_PIX_FMT_NV12    v4l2_fourcc('N','V','1','2') /* 12  Y/CbCr 4:2:0  */
-#define V4L2_PIX_FMT_NV21    v4l2_fourcc('N','V','2','1') /* 12  Y/CrCb 4:2:0  */
+#define V4L2_PIX_FMT_NV12    v4l2_fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
+#define V4L2_PIX_FMT_NV21    v4l2_fourcc('N', 'V', '2', '1') /* 12  Y/CrCb 4:2:0  */
 
 /*  The following formats are not defined in the V4L2 specification */
-#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y','U','V','9') /*  9  YUV 4:1:0     */
-#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
-#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
-#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:2:0 16x16 macroblocks */
+#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y', 'U', 'V', '9') /*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H', 'I', '2', '4') /*  8  8-bit color   */
+#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H', 'M', '1', '2') /*  8  YUV 4:2:0 16x16 macroblocks */
 
 /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
-#define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /*  8  BGBG.. GRGR.. */
-#define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G','B','R','G') /*  8  GBGB.. RGRG.. */
-#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B','Y','R','2') /* 16  BGBG.. GRGR.. */
+#define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
+#define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
+#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16  BGBG.. GRGR.. */
 
 /* compressed formats */
-#define V4L2_PIX_FMT_MJPEG    v4l2_fourcc('M','J','P','G') /* Motion-JPEG   */
-#define V4L2_PIX_FMT_JPEG     v4l2_fourcc('J','P','E','G') /* JFIF JPEG     */
-#define V4L2_PIX_FMT_DV       v4l2_fourcc('d','v','s','d') /* 1394          */
-#define V4L2_PIX_FMT_MPEG     v4l2_fourcc('M','P','E','G') /* MPEG-1/2/4    */
+#define V4L2_PIX_FMT_MJPEG    v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG   */
+#define V4L2_PIX_FMT_JPEG     v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG     */
+#define V4L2_PIX_FMT_DV       v4l2_fourcc('d', 'v', 's', 'd') /* 1394          */
+#define V4L2_PIX_FMT_MPEG     v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4    */
 
 /*  Vendor-specific formats   */
-#define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
-#define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
-#define V4L2_PIX_FMT_PWC1     v4l2_fourcc('P','W','C','1') /* pwc older webcam */
-#define V4L2_PIX_FMT_PWC2     v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
-#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */
-#define V4L2_PIX_FMT_SPCA501  v4l2_fourcc('S','5','0','1') /* YUYV per line */
-#define V4L2_PIX_FMT_SPCA561  v4l2_fourcc('S','5','6','1') /* compressed GBRG bayer */
-#define V4L2_PIX_FMT_PAC207   v4l2_fourcc('P','2','0','7') /* compressed BGGR bayer */
+#define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
+#define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
+#define V4L2_PIX_FMT_PWC1     v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
+#define V4L2_PIX_FMT_PWC2     v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
+#define V4L2_PIX_FMT_SPCA501  v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */
+#define V4L2_PIX_FMT_SPCA505  v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */
+#define V4L2_PIX_FMT_SPCA508  v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
+#define V4L2_PIX_FMT_SPCA561  v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
+#define V4L2_PIX_FMT_PAC207   v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
  */
-struct v4l2_fmtdesc
-{
+struct v4l2_fmtdesc {
 	__u32		    index;             /* Format number      */
 	enum v4l2_buf_type  type;              /* buffer type        */
 	__u32               flags;
@@ -349,21 +354,18 @@
 /*
  *	F R A M E   S I Z E   E N U M E R A T I O N
  */
-enum v4l2_frmsizetypes
-{
+enum v4l2_frmsizetypes {
 	V4L2_FRMSIZE_TYPE_DISCRETE	= 1,
 	V4L2_FRMSIZE_TYPE_CONTINUOUS	= 2,
 	V4L2_FRMSIZE_TYPE_STEPWISE	= 3,
 };
 
-struct v4l2_frmsize_discrete
-{
+struct v4l2_frmsize_discrete {
 	__u32			width;		/* Frame width [pixel] */
 	__u32			height;		/* Frame height [pixel] */
 };
 
-struct v4l2_frmsize_stepwise
-{
+struct v4l2_frmsize_stepwise {
 	__u32			min_width;	/* Minimum frame width [pixel] */
 	__u32			max_width;	/* Maximum frame width [pixel] */
 	__u32			step_width;	/* Frame width step size [pixel] */
@@ -372,8 +374,7 @@
 	__u32			step_height;	/* Frame height step size [pixel] */
 };
 
-struct v4l2_frmsizeenum
-{
+struct v4l2_frmsizeenum {
 	__u32			index;		/* Frame size number */
 	__u32			pixel_format;	/* Pixel format */
 	__u32			type;		/* Frame size type the device supports. */
@@ -389,22 +390,19 @@
 /*
  *	F R A M E   R A T E   E N U M E R A T I O N
  */
-enum v4l2_frmivaltypes
-{
+enum v4l2_frmivaltypes {
 	V4L2_FRMIVAL_TYPE_DISCRETE	= 1,
 	V4L2_FRMIVAL_TYPE_CONTINUOUS	= 2,
 	V4L2_FRMIVAL_TYPE_STEPWISE	= 3,
 };
 
-struct v4l2_frmival_stepwise
-{
+struct v4l2_frmival_stepwise {
 	struct v4l2_fract	min;		/* Minimum frame interval [s] */
 	struct v4l2_fract	max;		/* Maximum frame interval [s] */
 	struct v4l2_fract	step;		/* Frame interval step size [s] */
 };
 
-struct v4l2_frmivalenum
-{
+struct v4l2_frmivalenum {
 	__u32			index;		/* Frame format index */
 	__u32			pixel_format;	/* Pixel format */
 	__u32			width;		/* Frame width */
@@ -423,8 +421,7 @@
 /*
  *	T I M E C O D E
  */
-struct v4l2_timecode
-{
+struct v4l2_timecode {
 	__u32	type;
 	__u32	flags;
 	__u8	frames;
@@ -449,8 +446,7 @@
 #define V4L2_TC_USERBITS_8BITCHARS	0x0008
 /* The above is based on SMPTE timecodes */
 
-struct v4l2_jpegcompression
-{
+struct v4l2_jpegcompression {
 	int quality;
 
 	int  APPn;              /* Number of APP segment to be written,
@@ -482,16 +478,14 @@
 /*
  *	M E M O R Y - M A P P I N G   B U F F E R S
  */
-struct v4l2_requestbuffers
-{
+struct v4l2_requestbuffers {
 	__u32			count;
 	enum v4l2_buf_type      type;
 	enum v4l2_memory        memory;
 	__u32			reserved[2];
 };
 
-struct v4l2_buffer
-{
+struct v4l2_buffer {
 	__u32			index;
 	enum v4l2_buf_type      type;
 	__u32			bytesused;
@@ -525,13 +519,12 @@
 /*
  *	O V E R L A Y   P R E V I E W
  */
-struct v4l2_framebuffer
-{
+struct v4l2_framebuffer {
 	__u32			capability;
 	__u32			flags;
 /* FIXME: in theory we should pass something like PCI device + memory
  * region + offset instead of some physical address */
-	void*                   base;
+	void                    *base;
 	struct v4l2_pix_format	fmt;
 };
 /*  Flags for the 'capability' field. Read only */
@@ -550,14 +543,12 @@
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA	0x0010
 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA	0x0020
 
-struct v4l2_clip
-{
+struct v4l2_clip {
 	struct v4l2_rect        c;
 	struct v4l2_clip	__user *next;
 };
 
-struct v4l2_window
-{
+struct v4l2_window {
 	struct v4l2_rect        w;
 	enum v4l2_field  	field;
 	__u32			chromakey;
@@ -570,8 +561,7 @@
 /*
  *	C A P T U R E   P A R A M E T E R S
  */
-struct v4l2_captureparm
-{
+struct v4l2_captureparm {
 	__u32		   capability;	  /*  Supported modes */
 	__u32		   capturemode;	  /*  Current mode */
 	struct v4l2_fract  timeperframe;  /*  Time per frame in .1us units */
@@ -584,8 +574,7 @@
 #define V4L2_MODE_HIGHQUALITY	0x0001	/*  High quality imaging mode */
 #define V4L2_CAP_TIMEPERFRAME	0x1000	/*  timeperframe field is supported */
 
-struct v4l2_outputparm
-{
+struct v4l2_outputparm {
 	__u32		   capability;	 /*  Supported modes */
 	__u32		   outputmode;	 /*  Current mode */
 	struct v4l2_fract  timeperframe; /*  Time per frame in seconds */
@@ -702,8 +691,7 @@
 #define V4L2_STD_ALL            (V4L2_STD_525_60	|\
 				 V4L2_STD_625_50)
 
-struct v4l2_standard
-{
+struct v4l2_standard {
 	__u32		     index;
 	v4l2_std_id          id;
 	__u8		     name[24];
@@ -715,8 +703,7 @@
 /*
  *	V I D E O   I N P U T S
  */
-struct v4l2_input
-{
+struct v4l2_input {
 	__u32	     index;		/*  Which input */
 	__u8	     name[32];		/*  Label */
 	__u32	     type;		/*  Type of input */
@@ -753,8 +740,7 @@
 /*
  *	V I D E O   O U T P U T S
  */
-struct v4l2_output
-{
+struct v4l2_output {
 	__u32	     index;		/*  Which output */
 	__u8	     name[32];		/*  Label */
 	__u32	     type;		/*  Type of output */
@@ -771,14 +757,12 @@
 /*
  *	C O N T R O L S
  */
-struct v4l2_control
-{
+struct v4l2_control {
 	__u32		     id;
 	__s32		     value;
 };
 
-struct v4l2_ext_control
-{
+struct v4l2_ext_control {
 	__u32 id;
 	__u32 reserved2[2];
 	union {
@@ -788,8 +772,7 @@
 	};
 } __attribute__ ((packed));
 
-struct v4l2_ext_controls
-{
+struct v4l2_ext_controls {
 	__u32 ctrl_class;
 	__u32 count;
 	__u32 error_idx;
@@ -807,8 +790,7 @@
 #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
 
 /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
-struct v4l2_queryctrl
-{
+struct v4l2_queryctrl {
 	__u32		     id;
 	enum v4l2_ctrl_type  type;
 	__u8		     name[32];	/* Whatever */
@@ -821,8 +803,7 @@
 };
 
 /*  Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
-struct v4l2_querymenu
-{
+struct v4l2_querymenu {
 	__u32		id;
 	__u32		index;
 	__u8		name[32];	/* Whatever */
@@ -1104,8 +1085,7 @@
 /*
  *	T U N I N G
  */
-struct v4l2_tuner
-{
+struct v4l2_tuner {
 	__u32                   index;
 	__u8			name[32];
 	enum v4l2_tuner_type    type;
@@ -1119,8 +1099,7 @@
 	__u32			reserved[4];
 };
 
-struct v4l2_modulator
-{
+struct v4l2_modulator {
 	__u32			index;
 	__u8			name[32];
 	__u32			capability;
@@ -1153,8 +1132,7 @@
 #define V4L2_TUNER_MODE_LANG1		0x0003
 #define V4L2_TUNER_MODE_LANG1_LANG2	0x0004
 
-struct v4l2_frequency
-{
+struct v4l2_frequency {
 	__u32		      tuner;
 	enum v4l2_tuner_type  type;
 	__u32		      frequency;
@@ -1172,8 +1150,7 @@
 /*
  *	A U D I O
  */
-struct v4l2_audio
-{
+struct v4l2_audio {
 	__u32	index;
 	__u8	name[32];
 	__u32	capability;
@@ -1188,8 +1165,7 @@
 /*  Flags for the 'mode' field */
 #define V4L2_AUDMODE_AVL		0x00001
 
-struct v4l2_audioout
-{
+struct v4l2_audioout {
 	__u32	index;
 	__u8	name[32];
 	__u32	capability;
@@ -1253,8 +1229,7 @@
  */
 
 /* Raw VBI */
-struct v4l2_vbi_format
-{
+struct v4l2_vbi_format {
 	__u32	sampling_rate;		/* in 1 Hz */
 	__u32	offset;
 	__u32	samples_per_line;
@@ -1266,8 +1241,8 @@
 };
 
 /*  VBI flags  */
-#define V4L2_VBI_UNSYNC		(1<< 0)
-#define V4L2_VBI_INTERLACED	(1<< 1)
+#define V4L2_VBI_UNSYNC		(1 << 0)
+#define V4L2_VBI_INTERLACED	(1 << 1)
 
 /* Sliced VBI
  *
@@ -1276,8 +1251,7 @@
  * notice in the definitive implementation.
  */
 
-struct v4l2_sliced_vbi_format
-{
+struct v4l2_sliced_vbi_format {
 	__u16   service_set;
 	/* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
 	   service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
@@ -1301,8 +1275,7 @@
 #define V4L2_SLICED_VBI_525             (V4L2_SLICED_CAPTION_525)
 #define V4L2_SLICED_VBI_625             (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
 
-struct v4l2_sliced_vbi_cap
-{
+struct v4l2_sliced_vbi_cap {
 	__u16   service_set;
 	/* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
 	   service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
@@ -1313,8 +1286,7 @@
 	__u32   reserved[3];    /* must be 0 */
 };
 
-struct v4l2_sliced_vbi_data
-{
+struct v4l2_sliced_vbi_data {
 	__u32   id;
 	__u32   field;          /* 0: first field, 1: second field */
 	__u32   line;           /* 1-23 */
@@ -1328,27 +1300,23 @@
 
 /*	Stream data format
  */
-struct v4l2_format
-{
+struct v4l2_format {
 	enum v4l2_buf_type type;
-	union
-	{
-		struct v4l2_pix_format		pix;     // V4L2_BUF_TYPE_VIDEO_CAPTURE
-		struct v4l2_window		win;     // V4L2_BUF_TYPE_VIDEO_OVERLAY
-		struct v4l2_vbi_format		vbi;     // V4L2_BUF_TYPE_VBI_CAPTURE
-		struct v4l2_sliced_vbi_format	sliced;  // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
-		__u8	raw_data[200];                   // user-defined
+	union {
+		struct v4l2_pix_format		pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
+		struct v4l2_window		win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
+		struct v4l2_vbi_format		vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
+		struct v4l2_sliced_vbi_format	sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
+		__u8	raw_data[200];                   /* user-defined */
 	} fmt;
 };
 
 
 /*	Stream type-dependent parameters
  */
-struct v4l2_streamparm
-{
+struct v4l2_streamparm {
 	enum v4l2_buf_type type;
-	union
-	{
+	union {
 		struct v4l2_captureparm	capture;
 		struct v4l2_outputparm	output;
 		__u8	raw_data[200];  /* user-defined */
@@ -1386,92 +1354,86 @@
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
  */
-#define VIDIOC_QUERYCAP		_IOR  ('V',  0, struct v4l2_capability)
-#define VIDIOC_RESERVED		_IO   ('V',  1)
-#define VIDIOC_ENUM_FMT         _IOWR ('V',  2, struct v4l2_fmtdesc)
-#define VIDIOC_G_FMT		_IOWR ('V',  4, struct v4l2_format)
-#define VIDIOC_S_FMT		_IOWR ('V',  5, struct v4l2_format)
-#define VIDIOC_REQBUFS		_IOWR ('V',  8, struct v4l2_requestbuffers)
-#define VIDIOC_QUERYBUF		_IOWR ('V',  9, struct v4l2_buffer)
-#define VIDIOC_G_FBUF		_IOR  ('V', 10, struct v4l2_framebuffer)
-#define VIDIOC_S_FBUF		_IOW  ('V', 11, struct v4l2_framebuffer)
-#define VIDIOC_OVERLAY		_IOW  ('V', 14, int)
-#define VIDIOC_QBUF		_IOWR ('V', 15, struct v4l2_buffer)
-#define VIDIOC_DQBUF		_IOWR ('V', 17, struct v4l2_buffer)
-#define VIDIOC_STREAMON		_IOW  ('V', 18, int)
-#define VIDIOC_STREAMOFF	_IOW  ('V', 19, int)
-#define VIDIOC_G_PARM		_IOWR ('V', 21, struct v4l2_streamparm)
-#define VIDIOC_S_PARM		_IOWR ('V', 22, struct v4l2_streamparm)
-#define VIDIOC_G_STD		_IOR  ('V', 23, v4l2_std_id)
-#define VIDIOC_S_STD		_IOW  ('V', 24, v4l2_std_id)
-#define VIDIOC_ENUMSTD		_IOWR ('V', 25, struct v4l2_standard)
-#define VIDIOC_ENUMINPUT	_IOWR ('V', 26, struct v4l2_input)
-#define VIDIOC_G_CTRL		_IOWR ('V', 27, struct v4l2_control)
-#define VIDIOC_S_CTRL		_IOWR ('V', 28, struct v4l2_control)
-#define VIDIOC_G_TUNER		_IOWR ('V', 29, struct v4l2_tuner)
-#define VIDIOC_S_TUNER		_IOW  ('V', 30, struct v4l2_tuner)
-#define VIDIOC_G_AUDIO		_IOR  ('V', 33, struct v4l2_audio)
-#define VIDIOC_S_AUDIO		_IOW  ('V', 34, struct v4l2_audio)
-#define VIDIOC_QUERYCTRL	_IOWR ('V', 36, struct v4l2_queryctrl)
-#define VIDIOC_QUERYMENU	_IOWR ('V', 37, struct v4l2_querymenu)
-#define VIDIOC_G_INPUT		_IOR  ('V', 38, int)
-#define VIDIOC_S_INPUT		_IOWR ('V', 39, int)
-#define VIDIOC_G_OUTPUT		_IOR  ('V', 46, int)
-#define VIDIOC_S_OUTPUT		_IOWR ('V', 47, int)
-#define VIDIOC_ENUMOUTPUT	_IOWR ('V', 48, struct v4l2_output)
-#define VIDIOC_G_AUDOUT		_IOR  ('V', 49, struct v4l2_audioout)
-#define VIDIOC_S_AUDOUT		_IOW  ('V', 50, struct v4l2_audioout)
-#define VIDIOC_G_MODULATOR	_IOWR ('V', 54, struct v4l2_modulator)
-#define VIDIOC_S_MODULATOR	_IOW  ('V', 55, struct v4l2_modulator)
-#define VIDIOC_G_FREQUENCY	_IOWR ('V', 56, struct v4l2_frequency)
-#define VIDIOC_S_FREQUENCY	_IOW  ('V', 57, struct v4l2_frequency)
-#define VIDIOC_CROPCAP		_IOWR ('V', 58, struct v4l2_cropcap)
-#define VIDIOC_G_CROP		_IOWR ('V', 59, struct v4l2_crop)
-#define VIDIOC_S_CROP		_IOW  ('V', 60, struct v4l2_crop)
-#define VIDIOC_G_JPEGCOMP	_IOR  ('V', 61, struct v4l2_jpegcompression)
-#define VIDIOC_S_JPEGCOMP	_IOW  ('V', 62, struct v4l2_jpegcompression)
-#define VIDIOC_QUERYSTD      	_IOR  ('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT      	_IOWR ('V', 64, struct v4l2_format)
-#define VIDIOC_ENUMAUDIO	_IOWR ('V', 65, struct v4l2_audio)
-#define VIDIOC_ENUMAUDOUT	_IOWR ('V', 66, struct v4l2_audioout)
-#define VIDIOC_G_PRIORITY       _IOR  ('V', 67, enum v4l2_priority)
-#define VIDIOC_S_PRIORITY       _IOW  ('V', 68, enum v4l2_priority)
-#define VIDIOC_G_SLICED_VBI_CAP _IOWR ('V', 69, struct v4l2_sliced_vbi_cap)
-#define VIDIOC_LOG_STATUS       _IO   ('V', 70)
-#define VIDIOC_G_EXT_CTRLS	_IOWR ('V', 71, struct v4l2_ext_controls)
-#define VIDIOC_S_EXT_CTRLS	_IOWR ('V', 72, struct v4l2_ext_controls)
-#define VIDIOC_TRY_EXT_CTRLS	_IOWR ('V', 73, struct v4l2_ext_controls)
+#define VIDIOC_QUERYCAP		 _IOR('V',  0, struct v4l2_capability)
+#define VIDIOC_RESERVED		  _IO('V',  1)
+#define VIDIOC_ENUM_FMT         _IOWR('V',  2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT		_IOWR('V',  4, struct v4l2_format)
+#define VIDIOC_S_FMT		_IOWR('V',  5, struct v4l2_format)
+#define VIDIOC_REQBUFS		_IOWR('V',  8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF		_IOWR('V',  9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF		 _IOR('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF		 _IOW('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY		 _IOW('V', 14, int)
+#define VIDIOC_QBUF		_IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF		_IOWR('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON		 _IOW('V', 18, int)
+#define VIDIOC_STREAMOFF	 _IOW('V', 19, int)
+#define VIDIOC_G_PARM		_IOWR('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM		_IOWR('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD		 _IOR('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD		 _IOW('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD		_IOWR('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT	_IOWR('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL		_IOWR('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL		_IOWR('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER		_IOWR('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER		 _IOW('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO		 _IOR('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO		 _IOW('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL	_IOWR('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU	_IOWR('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT		 _IOR('V', 38, int)
+#define VIDIOC_S_INPUT		_IOWR('V', 39, int)
+#define VIDIOC_G_OUTPUT		 _IOR('V', 46, int)
+#define VIDIOC_S_OUTPUT		_IOWR('V', 47, int)
+#define VIDIOC_ENUMOUTPUT	_IOWR('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT		 _IOR('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT		 _IOW('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR	_IOWR('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR	 _IOW('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY	_IOWR('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY	 _IOW('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP		_IOWR('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP		_IOWR('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP		 _IOW('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP	 _IOR('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP	 _IOW('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD      	 _IOR('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT      	_IOWR('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO	_IOWR('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT	_IOWR('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY        _IOR('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY        _IOW('V', 68, enum v4l2_priority)
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_LOG_STATUS         _IO('V', 70)
+#define VIDIOC_G_EXT_CTRLS	_IOWR('V', 71, struct v4l2_ext_controls)
+#define VIDIOC_S_EXT_CTRLS	_IOWR('V', 72, struct v4l2_ext_controls)
+#define VIDIOC_TRY_EXT_CTRLS	_IOWR('V', 73, struct v4l2_ext_controls)
 #if 1
-#define VIDIOC_ENUM_FRAMESIZES	_IOWR ('V', 74, struct v4l2_frmsizeenum)
-#define VIDIOC_ENUM_FRAMEINTERVALS	_IOWR ('V', 75, struct v4l2_frmivalenum)
-#define VIDIOC_G_ENC_INDEX      _IOR  ('V', 76, struct v4l2_enc_idx)
-#define VIDIOC_ENCODER_CMD      _IOWR ('V', 77, struct v4l2_encoder_cmd)
-#define VIDIOC_TRY_ENCODER_CMD  _IOWR ('V', 78, struct v4l2_encoder_cmd)
+#define VIDIOC_ENUM_FRAMESIZES	_IOWR('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX       _IOR('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD      _IOWR('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD  _IOWR('V', 78, struct v4l2_encoder_cmd)
 
 /* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
-#define	VIDIOC_DBG_S_REGISTER 	_IOW  ('V', 79, struct v4l2_register)
-#define	VIDIOC_DBG_G_REGISTER 	_IOWR ('V', 80, struct v4l2_register)
+#define	VIDIOC_DBG_S_REGISTER 	 _IOW('V', 79, struct v4l2_register)
+#define	VIDIOC_DBG_G_REGISTER 	_IOWR('V', 80, struct v4l2_register)
 
-#define VIDIOC_G_CHIP_IDENT     _IOWR ('V', 81, struct v4l2_chip_ident)
+#define VIDIOC_G_CHIP_IDENT     _IOWR('V', 81, struct v4l2_chip_ident)
 #endif
-#define VIDIOC_S_HW_FREQ_SEEK	_IOW  ('V', 82, struct v4l2_hw_freq_seek)
+#define VIDIOC_S_HW_FREQ_SEEK	 _IOW('V', 82, struct v4l2_hw_freq_seek)
 
 #ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
-#define VIDIOC_OVERLAY_OLD     	_IOWR ('V', 14, int)
-#define VIDIOC_S_PARM_OLD      	_IOW  ('V', 22, struct v4l2_streamparm)
-#define VIDIOC_S_CTRL_OLD      	_IOW  ('V', 28, struct v4l2_control)
-#define VIDIOC_G_AUDIO_OLD     	_IOWR ('V', 33, struct v4l2_audio)
-#define VIDIOC_G_AUDOUT_OLD    	_IOWR ('V', 49, struct v4l2_audioout)
-#define VIDIOC_CROPCAP_OLD     	_IOR  ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_OVERLAY_OLD     	_IOWR('V', 14, int)
+#define VIDIOC_S_PARM_OLD      	 _IOW('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD      	 _IOW('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD     	_IOWR('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD    	_IOWR('V', 49, struct v4l2_audioout)
+#define VIDIOC_CROPCAP_OLD     	 _IOR('V', 58, struct v4l2_cropcap)
 #endif
 
 #define BASE_VIDIOC_PRIVATE	192		/* 192-255 are private */
 
 #endif /* __LINUX_VIDEODEV2_H */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/include/linux/videotext.h b/include/linux/videotext.h
index 018f920..3e68c8d 100644
--- a/include/linux/videotext.h
+++ b/include/linux/videotext.h
@@ -45,10 +45,10 @@
 #define VTXIOCCLRCACHE_OLD 0x710b  /* clear cache on VTX-interface (if avail.) */
 #define VTXIOCSETVIRT_OLD  0x710c  /* turn on virtual mode (this disables TV-display) */
 
-/* 
+/*
  *	Definitions for VTXIOCGETINFO
  */
- 
+
 #define SAA5243 0
 #define SAA5246 1
 #define SAA5249 2
@@ -57,10 +57,10 @@
 
 typedef struct {
 	int version_major, version_minor;	/* version of driver; if version_major changes, driver */
-						/* is not backward compatible!!! CHECK THIS!!! */  
+						/* is not backward compatible!!! CHECK THIS!!! */
 	int numpages;				/* number of page-buffers of vtx-chipset */
 	int cct_type;				/* type of vtx-chipset (SAA5243, SAA5246, SAA5248 or
-  						 * SAA5249) */
+						 * SAA5249) */
 }
 vtx_info_t;
 
@@ -81,7 +81,7 @@
 #define PGMASK_HOUR (HR_TEN | HR_UNIT)
 #define PGMASK_MINUTE (MIN_TEN | MIN_UNIT)
 
-typedef struct 
+typedef struct
 {
 	int page;	/* number of requested page (hexadecimal) */
 	int hour;	/* requested hour (hexadecimal) */
@@ -98,11 +98,11 @@
 /*
  *	Definitions for VTXIOC{GETSTAT,PUTSTAT}
  */
- 
+
 #define VTX_PAGESIZE (40 * 24)
 #define VTX_VIRTUALSIZE (40 * 49)
 
-typedef struct 
+typedef struct
 {
 	int pagenum;			/* number of page (hexadecimal) */
 	int hour;			/* hour (hexadecimal) */
@@ -121,5 +121,5 @@
 	unsigned hamming : 1;		/* hamming-error occurred */
 }
 vtx_pageinfo_t;
- 
+
 #endif /* _VTX_H */
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index db8823d..e69de29 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,26 +0,0 @@
-/*
- */
-
-#ifndef AUDIOCHIP_H
-#define AUDIOCHIP_H
-
-enum audiochip {
-	AUDIO_CHIP_NONE,
-	AUDIO_CHIP_UNKNOWN,
-	/* Provided by video chip */
-	AUDIO_CHIP_INTERNAL,
-	/* Provided by tvaudio.c */
-	AUDIO_CHIP_TDA8425,
-	AUDIO_CHIP_TEA6300,
-	AUDIO_CHIP_TEA6420,
-	AUDIO_CHIP_TDA9840,
-	AUDIO_CHIP_TDA985X,
-	AUDIO_CHIP_TDA9874,
-	AUDIO_CHIP_PIC16C54,
-	/* Provided by msp3400.c */
-	AUDIO_CHIP_MSP34XX,
-	/* Provided by wm8775.c */
-	AUDIO_CHIP_WM8775
-};
-
-#endif /* AUDIOCHIP_H */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 89c442e..1d10409 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -2,6 +2,7 @@
 #define __SAA7146_VV__
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 #include <media/saa7146.h>
 #include <media/videobuf-dma-sg.h>
 
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index 5660ea2..a8ad75a 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -3,7 +3,12 @@
 
 struct tveeprom {
 	u32 has_radio;
-	u32 has_ir;     /* bit 0: IR receiver present, bit 1: IR transmitter (blaster) present. -1 == unknown */
+	/* If has_ir == 0, then it is unknown what the IR capabilities are,
+	   otherwise:
+	   bit 0: 1 (= IR capabilities are known)
+	   bit 1: IR receiver present
+	   bit 2: IR transmitter (blaster) present */
+	u32 has_ir;
 	u32 has_MAC_address; /* 0: no MAC, 1: MAC present, 2: unknown */
 
 	u32 tuner_type;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 2a52774..41b509b 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -90,7 +90,10 @@
 	/* module m52790: just ident 52790 */
 	V4L2_IDENT_M52790 = 52790,
 
-	/* module msp34xx: reserved range 34000-34999 */
+	/* module msp3400: reserved range 34000-34999 and 44000-44999 */
+	V4L2_IDENT_MSPX4XX  = 34000, /* generic MSPX4XX identifier, only
+					use internally (tveeprom.c). */
+
 	V4L2_IDENT_MSP3400B = 34002,
 	V4L2_IDENT_MSP3410B = 34102,
 
@@ -142,7 +145,7 @@
 	V4L2_IDENT_MSP3457G = 34577,
 	V4L2_IDENT_MSP3467G = 34677,
 
-	/* module msp44xx: reserved range 44000-44999 */
+	/* module msp3400: reserved range 34000-34999 and 44000-44999 */
 	V4L2_IDENT_MSP4400G = 44007,
 	V4L2_IDENT_MSP4410G = 44107,
 	V4L2_IDENT_MSP4420G = 44207,
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 020d057..07d3a9a 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -28,12 +28,6 @@
 
 #include <media/v4l2-dev.h>
 
-/* v4l debugging and diagnostics */
-
-/* Debug bitmask flags to be used on V4L2 */
-#define V4L2_DEBUG_IOCTL     0x01
-#define V4L2_DEBUG_IOCTL_ARG 0x02
-
 /* Common printk constucts for v4l-i2c drivers. These macros create a unique
    prefix consisting of the driver name, the adapter number and the i2c
    address. */
@@ -61,21 +55,20 @@
 			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
 	} while (0)
 
+/* ------------------------------------------------------------------------- */
 
-/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
-#define v4l_print_ioctl(name, cmd)  		 \
-	do {  					 \
-		printk(KERN_DEBUG "%s: ", name); \
-		v4l_printk_ioctl(cmd);		 \
-	} while (0)
+/* Priority helper functions */
 
-/* Use this macro in I2C drivers where 'client' is the struct i2c_client
-   pointer */
-#define v4l_i2c_print_ioctl(client, cmd) 		   \
-	do {      					   \
-		v4l_client_printk(KERN_DEBUG, client, ""); \
-		v4l_printk_ioctl(cmd);			   \
-	} while (0)
+struct v4l2_prio_state {
+	atomic_t prios[4];
+};
+int v4l2_prio_init(struct v4l2_prio_state *global);
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+		     enum v4l2_priority new);
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
 
 /* ------------------------------------------------------------------------- */
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 33f379b..2745e1a 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -9,7 +9,6 @@
 #ifndef _V4L2_DEV_H
 #define _V4L2_DEV_H
 
-#define OBSOLETE_OWNER   1 /* to be removed soon */
 #define OBSOLETE_DEVDATA 1 /* to be removed soon */
 
 #include <linux/poll.h>
@@ -17,11 +16,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/compiler.h> /* need __user */
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-#include <linux/videodev.h>
-#else
 #include <linux/videodev2.h>
-#endif
 
 #define VIDEO_MAJOR	81
 /* Minor device allocation */
@@ -39,42 +34,7 @@
 #define VFL_TYPE_RADIO		2
 #define VFL_TYPE_VTX		3
 
-/*  Video standard functions  */
-extern const char *v4l2_norm_to_name(v4l2_std_id id);
-extern int v4l2_video_std_construct(struct v4l2_standard *vs,
-				    int id, const char *name);
-/* Prints the ioctl in a human-readable format */
-extern void v4l_printk_ioctl(unsigned int cmd);
-
-/* prority handling */
-struct v4l2_prio_state {
-	atomic_t prios[4];
-};
-int v4l2_prio_init(struct v4l2_prio_state *global);
-int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
-		     enum v4l2_priority new);
-int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
-int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
-enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
-int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
-
-/* names for fancy debug output */
-extern const char *v4l2_field_names[];
-extern const char *v4l2_type_names[];
-
-/*  Compatibility layer interface  --  v4l1-compat module */
-typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
-			   unsigned int cmd, void *arg);
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
-			       int cmd, void *arg, v4l2_kioctl driver_ioctl);
-#else
-#define v4l_compat_translate_ioctl(inode,file,cmd,arg,ioctl) -EINVAL
-#endif
-
-/* 32 Bits compatibility layer for 64 bits processors */
-extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
-				unsigned long arg);
+struct v4l2_ioctl_callbacks;
 
 /*
  * Newer version of video_device, handled by videodev2.c
@@ -88,18 +48,17 @@
 	const struct file_operations *fops;
 
 	/* sysfs */
-	struct device class_dev;	/* v4l device */
-	struct device *dev;		/* device parent */
+	struct device dev;		/* v4l device */
+	struct device *parent;		/* device parent */
 
 	/* device info */
 	char name[32];
-	int type;       /* v4l1 */
-	int type2;      /* v4l2 */
+	int vfl_type;
 	int minor;
-	/* attribute to diferentiate multiple indexs on one physical device */
+	/* attribute to differentiate multiple indices on one physical device */
 	int index;
 
-	int debug;	/* Activates debug level*/
+	int debug;			/* Activates debug level*/
 
 	/* Video standard vars */
 	v4l2_std_id tvnorms;		/* Supported tv norms */
@@ -109,285 +68,36 @@
 	void (*release)(struct video_device *vfd);
 
 	/* ioctl callbacks */
+	const struct v4l2_ioctl_ops *ioctl_ops;
 
-	/* VIDIOC_QUERYCAP handler */
-	int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap);
-
-	/* Priority handling */
-	int (*vidioc_g_priority)   (struct file *file, void *fh,
-				    enum v4l2_priority *p);
-	int (*vidioc_s_priority)   (struct file *file, void *fh,
-				    enum v4l2_priority p);
-
-	/* VIDIOC_ENUM_FMT handlers */
-	int (*vidioc_enum_fmt_vid_cap)     (struct file *file, void *fh,
-					    struct v4l2_fmtdesc *f);
-	int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh,
-					    struct v4l2_fmtdesc *f);
-	int (*vidioc_enum_fmt_vid_out)     (struct file *file, void *fh,
-					    struct v4l2_fmtdesc *f);
-#if 1
-	/* deprecated, will be removed in 2.6.28 */
-	int (*vidioc_enum_fmt_vbi_cap)     (struct file *file, void *fh,
-					    struct v4l2_fmtdesc *f);
-#endif
-	int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
-					    struct v4l2_fmtdesc *f);
-
-	/* VIDIOC_G_FMT handlers */
-	int (*vidioc_g_fmt_vid_cap)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_vid_out)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_vbi_cap)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_vbi_out)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
-					struct v4l2_format *f);
-
-	/* VIDIOC_S_FMT handlers */
-	int (*vidioc_s_fmt_vid_cap)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_vid_out)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_vbi_cap)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_vbi_out)    (struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh,
-					struct v4l2_format *f);
-	int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
-					struct v4l2_format *f);
-
-	/* VIDIOC_TRY_FMT handlers */
-	int (*vidioc_try_fmt_vid_cap)    (struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_vid_out)    (struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_vbi_cap)    (struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_vbi_out)    (struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh,
-					  struct v4l2_format *f);
-	int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
-					  struct v4l2_format *f);
-
-	/* Buffer handlers */
-	int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
-	int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b);
-	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
-	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
-
-
-	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-			/* buffer type is struct vidio_mbuf * */
-	int (*vidiocgmbuf)  (struct file *file, void *fh, struct video_mbuf *p);
-#endif
-	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
-				struct v4l2_framebuffer *a);
-	int (*vidioc_s_fbuf)   (struct file *file, void *fh,
-				struct v4l2_framebuffer *a);
-
-		/* Stream on/off */
-	int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i);
-	int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i);
-
-		/* Standard handling
-			ENUMSTD is handled by videodev.c
-		 */
-	int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm);
-	int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm);
-	int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a);
-
-		/* Input handling */
-	int (*vidioc_enum_input)(struct file *file, void *fh,
-				 struct v4l2_input *inp);
-	int (*vidioc_g_input)   (struct file *file, void *fh, unsigned int *i);
-	int (*vidioc_s_input)   (struct file *file, void *fh, unsigned int i);
-
-		/* Output handling */
-	int (*vidioc_enum_output) (struct file *file, void *fh,
-				  struct v4l2_output *a);
-	int (*vidioc_g_output)   (struct file *file, void *fh, unsigned int *i);
-	int (*vidioc_s_output)   (struct file *file, void *fh, unsigned int i);
-
-		/* Control handling */
-	int (*vidioc_queryctrl)        (struct file *file, void *fh,
-					struct v4l2_queryctrl *a);
-	int (*vidioc_g_ctrl)           (struct file *file, void *fh,
-					struct v4l2_control *a);
-	int (*vidioc_s_ctrl)           (struct file *file, void *fh,
-					struct v4l2_control *a);
-	int (*vidioc_g_ext_ctrls)      (struct file *file, void *fh,
-					struct v4l2_ext_controls *a);
-	int (*vidioc_s_ext_ctrls)      (struct file *file, void *fh,
-					struct v4l2_ext_controls *a);
-	int (*vidioc_try_ext_ctrls)    (struct file *file, void *fh,
-					struct v4l2_ext_controls *a);
-	int (*vidioc_querymenu)        (struct file *file, void *fh,
-					struct v4l2_querymenu *a);
-
-	/* Audio ioctls */
-	int (*vidioc_enumaudio)        (struct file *file, void *fh,
-					struct v4l2_audio *a);
-	int (*vidioc_g_audio)          (struct file *file, void *fh,
-					struct v4l2_audio *a);
-	int (*vidioc_s_audio)          (struct file *file, void *fh,
-					struct v4l2_audio *a);
-
-	/* Audio out ioctls */
-	int (*vidioc_enumaudout)       (struct file *file, void *fh,
-					struct v4l2_audioout *a);
-	int (*vidioc_g_audout)         (struct file *file, void *fh,
-					struct v4l2_audioout *a);
-	int (*vidioc_s_audout)         (struct file *file, void *fh,
-					struct v4l2_audioout *a);
-	int (*vidioc_g_modulator)      (struct file *file, void *fh,
-					struct v4l2_modulator *a);
-	int (*vidioc_s_modulator)      (struct file *file, void *fh,
-					struct v4l2_modulator *a);
-	/* Crop ioctls */
-	int (*vidioc_cropcap)          (struct file *file, void *fh,
-					struct v4l2_cropcap *a);
-	int (*vidioc_g_crop)           (struct file *file, void *fh,
-					struct v4l2_crop *a);
-	int (*vidioc_s_crop)           (struct file *file, void *fh,
-					struct v4l2_crop *a);
-	/* Compression ioctls */
-	int (*vidioc_g_jpegcomp)       (struct file *file, void *fh,
-					struct v4l2_jpegcompression *a);
-	int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
-					struct v4l2_jpegcompression *a);
-	int (*vidioc_g_enc_index)      (struct file *file, void *fh,
-					struct v4l2_enc_idx *a);
-	int (*vidioc_encoder_cmd)      (struct file *file, void *fh,
-					struct v4l2_encoder_cmd *a);
-	int (*vidioc_try_encoder_cmd)  (struct file *file, void *fh,
-					struct v4l2_encoder_cmd *a);
-
-	/* Stream type-dependent parameter ioctls */
-	int (*vidioc_g_parm)           (struct file *file, void *fh,
-					struct v4l2_streamparm *a);
-	int (*vidioc_s_parm)           (struct file *file, void *fh,
-					struct v4l2_streamparm *a);
-
-	/* Tuner ioctls */
-	int (*vidioc_g_tuner)          (struct file *file, void *fh,
-					struct v4l2_tuner *a);
-	int (*vidioc_s_tuner)          (struct file *file, void *fh,
-					struct v4l2_tuner *a);
-	int (*vidioc_g_frequency)      (struct file *file, void *fh,
-					struct v4l2_frequency *a);
-	int (*vidioc_s_frequency)      (struct file *file, void *fh,
-					struct v4l2_frequency *a);
-
-	/* Sliced VBI cap */
-	int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh,
-					struct v4l2_sliced_vbi_cap *a);
-
-	/* Log status ioctl */
-	int (*vidioc_log_status)       (struct file *file, void *fh);
-
-	int (*vidioc_s_hw_freq_seek)   (struct file *file, void *fh,
-					struct v4l2_hw_freq_seek *a);
-
-	/* Debugging ioctls */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	int (*vidioc_g_register)       (struct file *file, void *fh,
-					struct v4l2_register *reg);
-	int (*vidioc_s_register)       (struct file *file, void *fh,
-					struct v4l2_register *reg);
-#endif
-	int (*vidioc_g_chip_ident)     (struct file *file, void *fh,
-					struct v4l2_chip_ident *chip);
-
-	/* For other private ioctls */
-	int (*vidioc_default)	       (struct file *file, void *fh,
-					int cmd, void *arg);
-
-
-#ifdef OBSOLETE_OWNER /* to be removed soon */
-/* obsolete -- fops->owner is used instead */
-struct module *owner;
-/* dev->driver_data will be used instead some day.
-	* Use the video_{get|set}_drvdata() helper functions,
-	* so the switch over will be transparent for you.
-	* Or use {pci|usb}_{get|set}_drvdata() directly. */
-void *priv;
+#ifdef OBSOLETE_DEVDATA /* to be removed soon */
+	/* dev->driver_data will be used instead some day.
+	 * Use the video_{get|set}_drvdata() helper functions,
+	 * so the switch over will be transparent for you.
+	 * Or use {pci|usb}_{get|set}_drvdata() directly. */
+	void *priv;
 #endif
 
-	/* for videodev.c intenal usage -- please don't touch */
+	/* for videodev.c internal usage -- please don't touch */
 	int users;                     /* video_exclusive_{open|close} ... */
 	struct mutex lock;             /* ... helper function uses these   */
 };
 
 /* Class-dev to video-device */
-#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
+#define to_video_device(cd) container_of(cd, struct video_device, dev)
 
 /* Version 2 functions */
 extern int video_register_device(struct video_device *vfd, int type, int nr);
 int video_register_device_index(struct video_device *vfd, int type, int nr,
 					int index);
 void video_unregister_device(struct video_device *);
-extern int video_ioctl2(struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg);
 
 /* helper functions to alloc / release struct video_device, the
    later can be used for video_device->release() */
 struct video_device *video_device_alloc(void);
 void video_device_release(struct video_device *vfd);
 
-/* Include support for obsoleted stuff */
-extern int video_usercopy(struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg,
-			  int (*func)(struct inode *inode, struct file *file,
-				      unsigned int cmd, void *arg));
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-#include <linux/mm.h>
-
-static inline int __must_check
-video_device_create_file(struct video_device *vfd,
-			 struct device_attribute *attr)
-{
-	int ret = device_create_file(&vfd->class_dev, attr);
-	if (ret < 0)
-		printk(KERN_WARNING "%s error: %d\n", __func__, ret);
-	return ret;
-}
-static inline void
-video_device_remove_file(struct video_device *vfd,
-			 struct device_attribute *attr)
-{
-	device_remove_file(&vfd->class_dev, attr);
-}
-
-#endif /* CONFIG_VIDEO_V4L1_COMPAT */
-
-#ifdef OBSOLETE_OWNER /* to be removed soon */
+#ifdef OBSOLETE_DEVDATA /* to be removed soon */
 /* helper functions to access driver private data. */
 static inline void *video_get_drvdata(struct video_device *dev)
 {
@@ -399,9 +109,6 @@
 	dev->priv = data;
 }
 
-#endif
-
-#ifdef OBSOLETE_DEVDATA /* to be removed soon */
 /* Obsolete stuff - Still needed for radio devices and obsolete drivers */
 extern struct video_device* video_devdata(struct file*);
 extern int video_exclusive_open(struct inode *inode, struct file *file);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
new file mode 100644
index 0000000..dc64046
--- /dev/null
+++ b/include/media/v4l2-ioctl.h
@@ -0,0 +1,301 @@
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ * Moved from videodev2.h
+ *
+ *	Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#ifndef _V4L2_IOCTL_H
+#define _V4L2_IOCTL_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/compiler.h> /* need __user */
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#include <linux/videodev.h>
+#else
+#include <linux/videodev2.h>
+#endif
+
+struct v4l2_ioctl_ops {
+	/* ioctl callbacks */
+
+	/* VIDIOC_QUERYCAP handler */
+	int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap);
+
+	/* Priority handling */
+	int (*vidioc_g_priority)   (struct file *file, void *fh,
+				    enum v4l2_priority *p);
+	int (*vidioc_s_priority)   (struct file *file, void *fh,
+				    enum v4l2_priority p);
+
+	/* VIDIOC_ENUM_FMT handlers */
+	int (*vidioc_enum_fmt_vid_cap)     (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_out)     (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+#if 1
+	/* deprecated, will be removed in 2.6.28 */
+	int (*vidioc_enum_fmt_vbi_cap)     (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+#endif
+	int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+
+	/* VIDIOC_G_FMT handlers */
+	int (*vidioc_g_fmt_vid_cap)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_out)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_cap)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_out)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
+					struct v4l2_format *f);
+
+	/* VIDIOC_S_FMT handlers */
+	int (*vidioc_s_fmt_vid_cap)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_out)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_cap)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_out)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
+					struct v4l2_format *f);
+
+	/* VIDIOC_TRY_FMT handlers */
+	int (*vidioc_try_fmt_vid_cap)    (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_out)    (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_cap)    (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_out)    (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+
+	/* Buffer handlers */
+	int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
+	int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b);
+	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
+	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
+
+
+	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+			/* buffer type is struct vidio_mbuf * */
+	int (*vidiocgmbuf)  (struct file *file, void *fh, struct video_mbuf *p);
+#endif
+	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
+				struct v4l2_framebuffer *a);
+	int (*vidioc_s_fbuf)   (struct file *file, void *fh,
+				struct v4l2_framebuffer *a);
+
+		/* Stream on/off */
+	int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i);
+	int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i);
+
+		/* Standard handling
+			ENUMSTD is handled by videodev.c
+		 */
+	int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm);
+	int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm);
+	int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a);
+
+		/* Input handling */
+	int (*vidioc_enum_input)(struct file *file, void *fh,
+				 struct v4l2_input *inp);
+	int (*vidioc_g_input)   (struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_input)   (struct file *file, void *fh, unsigned int i);
+
+		/* Output handling */
+	int (*vidioc_enum_output) (struct file *file, void *fh,
+				  struct v4l2_output *a);
+	int (*vidioc_g_output)   (struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_output)   (struct file *file, void *fh, unsigned int i);
+
+		/* Control handling */
+	int (*vidioc_queryctrl)        (struct file *file, void *fh,
+					struct v4l2_queryctrl *a);
+	int (*vidioc_g_ctrl)           (struct file *file, void *fh,
+					struct v4l2_control *a);
+	int (*vidioc_s_ctrl)           (struct file *file, void *fh,
+					struct v4l2_control *a);
+	int (*vidioc_g_ext_ctrls)      (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_s_ext_ctrls)      (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_try_ext_ctrls)    (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_querymenu)        (struct file *file, void *fh,
+					struct v4l2_querymenu *a);
+
+	/* Audio ioctls */
+	int (*vidioc_enumaudio)        (struct file *file, void *fh,
+					struct v4l2_audio *a);
+	int (*vidioc_g_audio)          (struct file *file, void *fh,
+					struct v4l2_audio *a);
+	int (*vidioc_s_audio)          (struct file *file, void *fh,
+					struct v4l2_audio *a);
+
+	/* Audio out ioctls */
+	int (*vidioc_enumaudout)       (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_g_audout)         (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_s_audout)         (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_g_modulator)      (struct file *file, void *fh,
+					struct v4l2_modulator *a);
+	int (*vidioc_s_modulator)      (struct file *file, void *fh,
+					struct v4l2_modulator *a);
+	/* Crop ioctls */
+	int (*vidioc_cropcap)          (struct file *file, void *fh,
+					struct v4l2_cropcap *a);
+	int (*vidioc_g_crop)           (struct file *file, void *fh,
+					struct v4l2_crop *a);
+	int (*vidioc_s_crop)           (struct file *file, void *fh,
+					struct v4l2_crop *a);
+	/* Compression ioctls */
+	int (*vidioc_g_jpegcomp)       (struct file *file, void *fh,
+					struct v4l2_jpegcompression *a);
+	int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
+					struct v4l2_jpegcompression *a);
+	int (*vidioc_g_enc_index)      (struct file *file, void *fh,
+					struct v4l2_enc_idx *a);
+	int (*vidioc_encoder_cmd)      (struct file *file, void *fh,
+					struct v4l2_encoder_cmd *a);
+	int (*vidioc_try_encoder_cmd)  (struct file *file, void *fh,
+					struct v4l2_encoder_cmd *a);
+
+	/* Stream type-dependent parameter ioctls */
+	int (*vidioc_g_parm)           (struct file *file, void *fh,
+					struct v4l2_streamparm *a);
+	int (*vidioc_s_parm)           (struct file *file, void *fh,
+					struct v4l2_streamparm *a);
+
+	/* Tuner ioctls */
+	int (*vidioc_g_tuner)          (struct file *file, void *fh,
+					struct v4l2_tuner *a);
+	int (*vidioc_s_tuner)          (struct file *file, void *fh,
+					struct v4l2_tuner *a);
+	int (*vidioc_g_frequency)      (struct file *file, void *fh,
+					struct v4l2_frequency *a);
+	int (*vidioc_s_frequency)      (struct file *file, void *fh,
+					struct v4l2_frequency *a);
+
+	/* Sliced VBI cap */
+	int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh,
+					struct v4l2_sliced_vbi_cap *a);
+
+	/* Log status ioctl */
+	int (*vidioc_log_status)       (struct file *file, void *fh);
+
+	int (*vidioc_s_hw_freq_seek)   (struct file *file, void *fh,
+					struct v4l2_hw_freq_seek *a);
+
+	/* Debugging ioctls */
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	int (*vidioc_g_register)       (struct file *file, void *fh,
+					struct v4l2_register *reg);
+	int (*vidioc_s_register)       (struct file *file, void *fh,
+					struct v4l2_register *reg);
+#endif
+	int (*vidioc_g_chip_ident)     (struct file *file, void *fh,
+					struct v4l2_chip_ident *chip);
+
+	/* For other private ioctls */
+	int (*vidioc_default)	       (struct file *file, void *fh,
+					int cmd, void *arg);
+};
+
+
+/* v4l debugging and diagnostics */
+
+/* Debug bitmask flags to be used on V4L2 */
+#define V4L2_DEBUG_IOCTL     0x01
+#define V4L2_DEBUG_IOCTL_ARG 0x02
+
+/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
+#define v4l_print_ioctl(name, cmd)  		 \
+	do {  					 \
+		printk(KERN_DEBUG "%s: ", name); \
+		v4l_printk_ioctl(cmd);		 \
+	} while (0)
+
+/* Use this macro in I2C drivers where 'client' is the struct i2c_client
+   pointer */
+#define v4l_i2c_print_ioctl(client, cmd) 		   \
+	do {      					   \
+		v4l_client_printk(KERN_DEBUG, client, ""); \
+		v4l_printk_ioctl(cmd);			   \
+	} while (0)
+
+/*  Video standard functions  */
+extern const char *v4l2_norm_to_name(v4l2_std_id id);
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+				    int id, const char *name);
+/* Prints the ioctl in a human-readable format */
+extern void v4l_printk_ioctl(unsigned int cmd);
+
+/* names for fancy debug output */
+extern const char *v4l2_field_names[];
+extern const char *v4l2_type_names[];
+
+/*  Compatibility layer interface  --  v4l1-compat module */
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg);
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+			       int cmd, void *arg, v4l2_kioctl driver_ioctl);
+#else
+#define v4l_compat_translate_ioctl(inode, file, cmd, arg, ioctl) (-EINVAL)
+#endif
+
+/* 32 Bits compatibility layer for 64 bits processors */
+extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
+				unsigned long arg);
+
+extern int video_ioctl2(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg);
+
+/* Include support for obsoleted stuff */
+extern int video_usercopy(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg,
+			  int (*func)(struct inode *inode, struct file *file,
+				      unsigned int cmd, void *arg));
+
+#endif /* _V4L2_IOCTL_H */
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 87e3aef..83e9005 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -189,9 +189,7 @@
 	}
 
 	memset(&tea->vd, 0, sizeof(tea->vd));
-	tea->vd.owner = tea->card->module;
 	strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
-	tea->vd.type = VID_TYPE_TUNER;
 	tea->vd.release = snd_tea575x_release;
 	video_set_drvdata(&tea->vd, tea);
 	tea->vd.fops = &tea->fops;