From c2e5307b902426247afa48d3f1ed4fa5409dcb49 Mon Sep 17 00:00:00 2001
From: Valentin Longchamp <valentin.longchamp@epfl.ch>
Date: Wed, 6 May 2009 11:54:48 +0200
Subject: mx31: changed CONSISTENT_DMA_SIZE to 8M for mx31 video

Signed-off-by: Valentin Longchamp <valentin.longchamp@epfl.ch>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/media/video/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9d48da2fb01..57835f5715f 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -758,10 +758,14 @@ config VIDEO_MX1
 	---help---
 	  This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
 
+config MX3_VIDEO
+	bool
+
 config VIDEO_MX3
 	tristate "i.MX3x Camera Sensor Interface driver"
 	depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
 	select VIDEOBUF_DMA_CONTIG
+	select MX3_VIDEO
 	---help---
 	  This is a v4l2 driver for the i.MX3x Camera Sensor Interface
 
-- 
cgit v1.2.3-70-g09d2


From 4b512d26f425be1c779c8319249b42ce3c3424d2 Mon Sep 17 00:00:00 2001
From: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Date: Tue, 14 Apr 2009 23:14:10 -0300
Subject: trivial: typo (en|dis|avail|remove)bale -> (en|dis|avail|remove)able

Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---
 drivers/char/amiserial.c                | 2 +-
 drivers/media/video/hdpvr/hdpvr-video.c | 2 +-
 drivers/net/b44.h                       | 2 +-
 drivers/net/e100.c                      | 2 +-
 drivers/net/niu.h                       | 4 ++--
 drivers/scsi/megaraid.h                 | 2 +-
 drivers/scsi/megaraid/mbox_defs.h       | 2 +-
 drivers/staging/rt2860/common/mlme.c    | 2 +-
 drivers/staging/rt2870/common/mlme.c    | 2 +-
 drivers/staging/rt3070/common/mlme.c    | 2 +-
 drivers/watchdog/iop_wdt.c              | 2 +-
 sound/pci/aw2/aw2-saa7146.c             | 2 +-
 12 files changed, 13 insertions(+), 13 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index fd3ebd1be57..72429b6b2fa 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -779,7 +779,7 @@ static void change_speed(struct async_struct *info,
 		info->IER |= UART_IER_MSI;
 	}
 	/* TBD:
-	 * Does clearing IER_MSI imply that we should disbale the VBL interrupt ?
+	 * Does clearing IER_MSI imply that we should disable the VBL interrupt ?
 	 */
 
 	/*
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 3e6ffee8dfe..ccd47f57f42 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -181,7 +181,7 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
 				 buff_list);
 		if (buf->status != BUFSTAT_AVAILABLE) {
 			v4l2_err(&dev->v4l2_dev,
-				 "buffer not marked as availbale\n");
+				 "buffer not marked as available\n");
 			ret = -EFAULT;
 			goto err;
 		}
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index e678498de6d..d24158e7f30 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -97,7 +97,7 @@
 #define B44_DMARX_STAT	0x021CUL /* DMA RX Current Active Desc. + Status */
 #define  DMARX_STAT_CDMASK	0x00000fff /* Current Descriptor Mask */
 #define  DMARX_STAT_SMASK	0x0000f000 /* State Mask */
-#define  DMARX_STAT_SDISABLED	0x00000000 /* State Disbaled */
+#define  DMARX_STAT_SDISABLED	0x00000000 /* State Disabled */
 #define  DMARX_STAT_SACTIVE	0x00001000 /* State Active */
 #define  DMARX_STAT_SIDLE	0x00002000 /* State Idle Wait */
 #define  DMARX_STAT_SSTOPPED	0x00003000 /* State Stopped */
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 0f9ee134855..af5364f4955 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2785,7 +2785,7 @@ static int e100_resume(struct pci_dev *pdev)
 	/* ack any pending wake events, disable PME */
 	pci_enable_wake(pdev, 0, 0);
 
-	/* disbale reverse auto-negotiation */
+	/* disable reverse auto-negotiation */
 	if (nic->phy == phy_82552_v) {
 		u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
 		                           E100_82552_SMARTSPEED);
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 8754e44cada..3bd0b5933d5 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3242,8 +3242,8 @@ struct niu {
 	struct niu_parent		*parent;
 
 	u32				flags;
-#define NIU_FLAGS_HOTPLUG_PHY_PRESENT	0x02000000 /* Removebale PHY detected*/
-#define NIU_FLAGS_HOTPLUG_PHY		0x01000000 /* Removebale PHY */
+#define NIU_FLAGS_HOTPLUG_PHY_PRESENT	0x02000000 /* Removeable PHY detected*/
+#define NIU_FLAGS_HOTPLUG_PHY		0x01000000 /* Removeable PHY */
 #define NIU_FLAGS_VPD_VALID		0x00800000 /* VPD has valid version */
 #define NIU_FLAGS_MSIX			0x00400000 /* MSI-X in use */
 #define NIU_FLAGS_MCAST			0x00200000 /* multicast filter enabled */
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 795201fa0b4..512c2cc1a33 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -469,7 +469,7 @@ typedef struct {
 	u8	type;		/* Type of the device */
 	u8	cur_status;	/* current status of the device */
 	u8	tag_depth;	/* Level of tagging */
-	u8	sync_neg;	/* sync negotiation - ENABLE or DISBALE */
+	u8	sync_neg;	/* sync negotiation - ENABLE or DISABLE */
 	u32	size;		/* configurable size in terms of 512 byte
 				   blocks */
 }__attribute__ ((packed)) phys_drv;
diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h
index 170399ef06f..b25b74764ec 100644
--- a/drivers/scsi/megaraid/mbox_defs.h
+++ b/drivers/scsi/megaraid/mbox_defs.h
@@ -686,7 +686,7 @@ typedef struct {
  * @type	: Type of the device
  * @cur_status	: current status of the device
  * @tag_depth	: Level of tagging
- * @sync_neg	: sync negotiation - ENABLE or DISBALE
+ * @sync_neg	: sync negotiation - ENABLE or DISABLE
  * @size	: configurable size in terms of 512 byte
  */
 typedef struct {
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index c00f9ab9c46..2edf2999f5c 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -5664,7 +5664,7 @@ VOID 	AsicUpdateProtect(
 #if 0
 	MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
 #else
-	// If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+	// If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
         if ((
 #ifdef DOT11_N_SUPPORT
 			(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
diff --git a/drivers/staging/rt2870/common/mlme.c b/drivers/staging/rt2870/common/mlme.c
index 8a82cee8bf2..a26bc033337 100644
--- a/drivers/staging/rt2870/common/mlme.c
+++ b/drivers/staging/rt2870/common/mlme.c
@@ -5561,7 +5561,7 @@ VOID 	AsicUpdateProtect(
 #if 0
 	MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
 #else
-	// If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+	// If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
         if ((
 #ifdef DOT11_N_SUPPORT
 			(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
index 0ffbfa36699..0189bab013c 100644
--- a/drivers/staging/rt3070/common/mlme.c
+++ b/drivers/staging/rt3070/common/mlme.c
@@ -5575,7 +5575,7 @@ VOID 	AsicUpdateProtect(
 	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
 	MacReg &= 0xFF0000FF;
 
-	// If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+	// If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
     if ((
 #ifdef DOT11_N_SUPPORT
 		(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index 96eb2cbe587..0c905967669 100644
--- a/drivers/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
@@ -192,7 +192,7 @@ static int iop_wdt_release(struct inode *inode, struct file *file)
 		if (test_bit(WDT_ENABLED, &wdt_status))
 			state = wdt_disable();
 
-	/* if the timer is not disbaled reload and notify that we are still
+	/* if the timer is not disabled reload and notify that we are still
 	 * going down
 	 */
 	if (state != 0) {
diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c
index 6a3891ab69d..296123ab74f 100644
--- a/sound/pci/aw2/aw2-saa7146.c
+++ b/sound/pci/aw2/aw2-saa7146.c
@@ -108,7 +108,7 @@ void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
 #endif
 	/* WS0_CTRL, WS0_SYNC: input TSL1, I2S */
 
-	/* At initialization WS1 and WS2 are disbaled (configured as input */
+	/* At initialization WS1 and WS2 are disabled (configured as input) */
 	acon1 |= 0 * WS1_CTRL;
 	acon1 |= 0 * WS2_CTRL;
 
-- 
cgit v1.2.3-70-g09d2


From f7a386c5b8ff34cd84ae922603d1c6f9d234edee Mon Sep 17 00:00:00 2001
From: Kay Sievers <kay.sievers@vrfy.org>
Date: Thu, 30 Apr 2009 15:23:42 +0200
Subject: Driver Core: usb: add nodename support for usb drivers.

This adds support for USB drivers to report their requested nodename to
userspace.  It also updates a number of USB drivers to provide the
needed subdirectory and device name to be used for them.

Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/hid/usbhid/hiddev.c     |  7 ++++++-
 drivers/media/video/dabusb.c    |  6 ++++++
 drivers/usb/class/usblp.c       |  6 ++++++
 drivers/usb/core/file.c         | 13 ++++++++++++-
 drivers/usb/core/usb.c          | 11 +++++++++++
 drivers/usb/misc/iowarrior.c    |  6 ++++++
 drivers/usb/misc/legousbtower.c |  6 ++++++
 include/linux/usb.h             |  3 +++
 8 files changed, 56 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index e9b436d2d94..9e9421525fb 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -850,8 +850,14 @@ static const struct file_operations hiddev_fops = {
 #endif
 };
 
+static char *hiddev_nodename(struct device *dev)
+{
+	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
+}
+
 static struct usb_class_driver hiddev_class = {
 	.name =		"hiddev%d",
+	.nodename =	hiddev_nodename,
 	.fops =		&hiddev_fops,
 	.minor_base =	HIDDEV_MINOR_BASE,
 };
@@ -955,7 +961,6 @@ static int hiddev_usbd_probe(struct usb_interface *intf,
 	return -ENODEV;
 }
 
-
 static /* const */ struct usb_driver hiddev_driver = {
 	.name =		"hiddev",
 	.probe =	hiddev_usbd_probe,
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ba3709bec3f..ec2f45dde16 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -747,8 +747,14 @@ static const struct file_operations dabusb_fops =
 	.release =	dabusb_release,
 };
 
+static char *dabusb_nodename(struct device *dev)
+{
+	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
+}
+
 static struct usb_class_driver dabusb_class = {
 	.name =		"dabusb%d",
+	.nodename =	dabusb_nodename,
 	.fops =		&dabusb_fops,
 	.minor_base =	DABUSB_MINOR,
 };
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index d2747a49b97..26c09f0257d 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1057,8 +1057,14 @@ static const struct file_operations usblp_fops = {
 	.release =	usblp_release,
 };
 
+static char *usblp_nodename(struct device *dev)
+{
+	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
+}
+
 static struct usb_class_driver usblp_class = {
 	.name =		"lp%d",
+	.nodename =	usblp_nodename,
 	.fops =		&usblp_fops,
 	.minor_base =	USBLP_MINOR_BASE,
 };
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 997e659ff69..5cef88929b3 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -67,6 +67,16 @@ static struct usb_class {
 	struct class *class;
 } *usb_class;
 
+static char *usb_nodename(struct device *dev)
+{
+	struct usb_class_driver *drv;
+
+	drv = dev_get_drvdata(dev);
+	if (!drv || !drv->nodename)
+		return NULL;
+	return drv->nodename(dev);
+}
+
 static int init_usb_class(void)
 {
 	int result = 0;
@@ -90,6 +100,7 @@ static int init_usb_class(void)
 		kfree(usb_class);
 		usb_class = NULL;
 	}
+	usb_class->class->nodename = usb_nodename;
 
 exit:
 	return result;
@@ -198,7 +209,7 @@ int usb_register_dev(struct usb_interface *intf,
 	else
 		temp = name;
 	intf->usb_dev = device_create(usb_class->class, &intf->dev,
-				      MKDEV(USB_MAJOR, minor), NULL,
+				      MKDEV(USB_MAJOR, minor), class_driver,
 				      "%s", temp);
 	if (IS_ERR(intf->usb_dev)) {
 		down_write(&minor_rwsem);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7eee400d3e3..927a27dd2f8 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -305,10 +305,21 @@ static struct dev_pm_ops usb_device_pm_ops = {
 
 #endif	/* CONFIG_PM */
 
+
+static char *usb_nodename(struct device *dev)
+{
+	struct usb_device *usb_dev;
+
+	usb_dev = to_usb_device(dev);
+	return kasprintf(GFP_KERNEL, "bus/usb/%03d/%03d",
+			 usb_dev->bus->busnum, usb_dev->devnum);
+}
+
 struct device_type usb_device_type = {
 	.name =		"usb_device",
 	.release =	usb_release_dev,
 	.uevent =	usb_dev_uevent,
+	.nodename = 	usb_nodename,
 	.pm =		&usb_device_pm_ops,
 };
 
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index a4ef77ef917..3c5fe5cee05 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -726,12 +726,18 @@ static const struct file_operations iowarrior_fops = {
 	.poll = iowarrior_poll,
 };
 
+static char *iowarrior_nodename(struct device *dev)
+{
+	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
+}
+
 /*
  * usb class driver info in order to get a minor number from the usb core,
  * and to have the device registered with devfs and the driver core
  */
 static struct usb_class_driver iowarrior_class = {
 	.name = "iowarrior%d",
+	.nodename = iowarrior_nodename,
 	.fops = &iowarrior_fops,
 	.minor_base = IOWARRIOR_MINOR_BASE,
 };
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index ab0f3226158..c1e2433f640 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -266,12 +266,18 @@ static const struct file_operations tower_fops = {
 	.llseek =	tower_llseek,
 };
 
+static char *legousbtower_nodename(struct device *dev)
+{
+	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
+}
+
 /*
  * usb class driver info in order to get a minor number from the usb core,
  * and to have the device registered with the driver core
  */
 static struct usb_class_driver tower_class = {
 	.name =		"legousbtower%d",
+	.nodename = 	legousbtower_nodename,
 	.fops =		&tower_fops,
 	.minor_base =	LEGO_USB_TOWER_MINOR_BASE,
 };
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 3aa2cd1f8d0..34cdfcac455 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -869,6 +869,8 @@ struct usb_driver {
  * struct usb_device_driver - identifies USB device driver to usbcore
  * @name: The driver name should be unique among USB drivers,
  *	and should normally be the same as the module name.
+ * @nodename: Callback to provide a naming hint for a possible
+ *	device node to create.
  * @probe: Called to see if the driver is willing to manage a particular
  *	device.  If it is, probe returns zero and uses dev_set_drvdata()
  *	to associate driver-specific data with the device.  If unwilling
@@ -912,6 +914,7 @@ extern struct bus_type usb_bus_type;
  */
 struct usb_class_driver {
 	char *name;
+	char *(*nodename)(struct device *dev);
 	const struct file_operations *fops;
 	int minor_base;
 };
-- 
cgit v1.2.3-70-g09d2


From 79510cdbc76265426c6d75326436624393694ea7 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@suse.de>
Date: Thu, 30 Apr 2009 14:43:31 -0700
Subject: media: remove driver_data direct access of struct device

In the near future, the driver core is going to not allow direct access
to the driver_data pointer in struct device.  Instead, the functions
dev_get_drvdata() and dev_set_drvdata() should be used.  These functions
have been around since the beginning, so are backwards compatible with
all older kernel versions.


Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Acked-by: Mike Isely <isely@pobox.com>
Cc: linux-media@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/media/dvb/firewire/firedtv-1394.c   |  4 ++--
 drivers/media/dvb/firewire/firedtv-dvb.c    |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 22 +++++++++++-----------
 3 files changed, 14 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 4e207658c5d..2b6eeeab5b2 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -225,7 +225,7 @@ fail_free:
 
 static int node_remove(struct device *dev)
 {
-	struct firedtv *fdtv = dev->driver_data;
+	struct firedtv *fdtv = dev_get_drvdata(dev);
 
 	fdtv_dvb_unregister(fdtv);
 
@@ -242,7 +242,7 @@ static int node_remove(struct device *dev)
 
 static int node_update(struct unit_directory *ud)
 {
-	struct firedtv *fdtv = ud->device.driver_data;
+	struct firedtv *fdtv = dev_get_drvdata(&ud->device);
 
 	if (fdtv->isochannel >= 0)
 		cmp_establish_pp_connection(fdtv, fdtv->subunit,
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 9d308dd32a5..5742fde79d9 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -268,7 +268,7 @@ struct firedtv *fdtv_alloc(struct device *dev,
 	if (!fdtv)
 		return NULL;
 
-	dev->driver_data	= fdtv;
+	dev_set_drvdata(dev, fdtv);
 	fdtv->device		= dev;
 	fdtv->isochannel	= -1;
 	fdtv->voltage		= 0xff;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 299c1cbc383..6c23456e0bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -539,7 +539,7 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
 					 &sfp->attr_unit_number);
 	}
 	pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
-	sfp->class_dev->driver_data = NULL;
+	dev_set_drvdata(sfp->class_dev, NULL);
 	device_unregister(sfp->class_dev);
 	sfp->class_dev = NULL;
 }
@@ -549,7 +549,7 @@ static ssize_t v4l_minor_number_show(struct device *class_dev,
 				     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -561,7 +561,7 @@ static ssize_t bus_info_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_bus_info(sfp->channel.hdw));
@@ -572,7 +572,7 @@ static ssize_t hdw_name_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_type(sfp->channel.hdw));
@@ -583,7 +583,7 @@ static ssize_t hdw_desc_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_desc(sfp->channel.hdw));
@@ -595,7 +595,7 @@ static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
 					   char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -607,7 +607,7 @@ static ssize_t unit_number_show(struct device *class_dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_get_unit_number(sfp->channel.hdw));
@@ -635,7 +635,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
 	class_dev->parent = &usb_dev->dev;
 
 	sfp->class_dev = class_dev;
-	class_dev->driver_data = sfp;
+	dev_set_drvdata(class_dev, sfp);
 	ret = device_register(class_dev);
 	if (ret) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -792,7 +792,7 @@ static ssize_t debuginfo_show(struct device *class_dev,
 			      struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	pvr2_hdw_trigger_module_log(sfp->channel.hdw);
 	return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
@@ -803,7 +803,7 @@ static ssize_t debugcmd_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
 }
@@ -816,7 +816,7 @@ static ssize_t debugcmd_store(struct device *class_dev,
 	struct pvr2_sysfs *sfp;
 	int ret;
 
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 
 	ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
-- 
cgit v1.2.3-70-g09d2


From dd72cb3eda68067f27e928a44aa40d82f972669a Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Thu, 12 Mar 2009 04:40:19 -0300
Subject: V4L/DVB (11446): gspca - t613: Do sensor reset only for sensor
 om6802.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/t613.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index f63e37e2e4f..404214b8cd2 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		return -EINVAL;
 	}
 
-	if (sd->sensor != SENSOR_OTHER) {
+	if (sd->sensor == SENSOR_OM6802) {
 		reg_w_buf(gspca_dev, n1, sizeof n1);
 		i = 5;
 		while (--i >= 0) {
-- 
cgit v1.2.3-70-g09d2


From 5d3fa30ddcc93bb5e0078f67cfe8d277f6334c57 Mon Sep 17 00:00:00 2001
From: Alexey Klimov <klimov.linux@gmail.com>
Date: Fri, 27 Mar 2009 15:57:46 -0300
Subject: V4L/DVB (11447): gspca - mr97310a: Return good error code in
 mod_init.

Signed-off-by: Alexey Klimov <klimov.linux@gmail.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/mr97310a.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 2a901a4a6f0..f9da55b20fa 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -347,8 +347,11 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2


From 2444163122c42f0f25db9b49a5e55c28eaf0b0f2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 27 Mar 2009 16:08:20 -0300
Subject: V4L/DVB (11448): gspca - main: Use usb interface as parent.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a2741d7dccf..93902e828e7 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1943,7 +1943,7 @@ int gspca_dev_probe(struct usb_interface *intf,
 
 	/* init video stuff */
 	memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
-	gspca_dev->vdev.parent = &dev->dev;
+	gspca_dev->vdev.parent = &intf->dev;
 	gspca_dev->module = module;
 	gspca_dev->present = 1;
 	ret = video_register_device(&gspca_dev->vdev,
-- 
cgit v1.2.3-70-g09d2


From 881cd41882fa5762e3f831dd997368fef5257274 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Sun, 5 Apr 2009 04:01:13 -0300
Subject: V4L/DVB (11449): gspca - zc3xx: Bad probe of many webcams since
 adcm2700 addition.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/zc3xx.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 4fe01d8b6c8..c4684b9a412 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
 	{0x8400, 0x15},		/* TAS5130K */
-	{0x4001, 0x16},		/* ADCM2700 */
 };
 
 static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	retword |= reg_r(gspca_dev, 0x000a);
 	PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
 	reg_r(gspca_dev, 0x0010);
-	/* this is tested only once anyway */
-	for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
-		if (chipset_revision_sensor[i].revision == retword) {
-			sd->chip_revision = retword;
-			send_unknown(dev, SENSOR_PB0330);
-			return chipset_revision_sensor[i].internal_sensor_id;
+	/* value 0x4001 is meaningless */
+	if (retword != 0x4001) {
+		for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
+			if (chipset_revision_sensor[i].revision == retword) {
+				sd->chip_revision = retword;
+				send_unknown(dev, SENSOR_PB0330);
+				return chipset_revision_sensor[i]
+							.internal_sensor_id;
+			}
 		}
 	}
 
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(dev, 0x01, 0x0001);
 	reg_w(dev, 0x03, 0x0012);
 	reg_w(dev, 0x01, 0x0012);
-	reg_w(dev, 0x05, 0x0001);
+	reg_w(dev, 0x05, 0x0012);
 	reg_w(dev, 0xd3, 0x008b);
 	retword = i2c_read(gspca_dev, 0x01);
 	if (retword != 0) {
 		PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
-		return retword;
+		return 0x16;			/* adcm2700 (6100/6200) */
 	}
 	return -1;
 }
-- 
cgit v1.2.3-70-g09d2


From 04f15655f6cd99ba7d7c9ef8f969a71061a1fbac Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 4 Jan 2009 16:52:48 -0300
Subject: V4L/DVB (11450): gspca - m5602-mt9m111: Convert the mt9m111 to use a
 v4l2 ctrl cache

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 65 +++++++++++++++----------
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  4 +-
 2 files changed, 43 insertions(+), 26 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7d3f9e348ef..43791a6b8d2 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -32,6 +32,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
 };
 
 const static struct ctrl mt9m111_ctrls[] = {
+#define VFLIP_IDX 0
 	{
 		{
 			.id		= V4L2_CID_VFLIP,
@@ -44,7 +45,9 @@ const static struct ctrl mt9m111_ctrls[] = {
 		},
 		.set = mt9m111_set_vflip,
 		.get = mt9m111_get_vflip
-	}, {
+	},
+#define HFLIP_IDX 1
+	{
 		{
 			.id             = V4L2_CID_HFLIP,
 			.type           = V4L2_CTRL_TYPE_BOOLEAN,
@@ -56,7 +59,9 @@ const static struct ctrl mt9m111_ctrls[] = {
 		},
 		.set = mt9m111_set_hflip,
 		.get = mt9m111_get_hflip
-	}, {
+	},
+#define GAIN_IDX 2
+	{
 		{
 			.id             = V4L2_CID_GAIN,
 			.type           = V4L2_CTRL_TYPE_INTEGER,
@@ -79,6 +84,7 @@ int mt9m111_probe(struct sd *sd)
 {
 	u8 data[2] = {0x00, 0x00};
 	int i;
+	s32 *sensor_settings;
 
 	if (force_sensor) {
 		if (force_sensor == MT9M111_SENSOR) {
@@ -117,10 +123,19 @@ int mt9m111_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
+	sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
 	sd->gspca_dev.cam.cam_mode = mt9m111_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
 	sd->desc->ctrls = mt9m111_ctrls;
 	sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
+
+	for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
+		sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
+	sd->sensor_priv = sensor_settings;
+
 	return 0;
 }
 
@@ -155,18 +170,21 @@ int mt9m111_power_down(struct sd *sd)
 	return 0;
 }
 
+void mt9m111_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
 int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
-				  data, 2);
-	*val = data[0] & MT9M111_RMB_MIRROR_ROWS;
+	*val = sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,9 +192,12 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 
+	sensor_settings[VFLIP_IDX] = val;
+
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
@@ -194,16 +215,13 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 
 int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
-				  data, 2);
-	*val = data[0] & MT9M111_RMB_MIRROR_COLS;
+	*val = sensor_settings[HFLIP_IDX];
 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -211,9 +229,11 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 
+	sensor_settings[HFLIP_IDX] = val;
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
@@ -231,21 +251,13 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 
 int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err, tmp;
-	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
-	tmp = ((data[1] << 8) | data[0]);
-
-	*val = ((tmp & (1 << 10)) * 2) |
-	      ((tmp & (1 <<  9)) * 2) |
-	      ((tmp & (1 <<  8)) * 2) |
-	       (tmp & 0x7f);
-
+	*val = sensor_settings[GAIN_IDX];
 	PDEBUG(D_V4L2, "Read gain %d", *val);
 
-	return err;
+	return 0;
 }
 
 int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -253,6 +265,9 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	int err, tmp;
 	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[GAIN_IDX] = val;
 
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 00c6db02bdb..03769fc0442 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -86,6 +86,7 @@ extern int dump_sensor;
 int mt9m111_probe(struct sd *sd);
 int mt9m111_init(struct sd *sd);
 int mt9m111_power_down(struct sd *sd);
+void mt9m111_disconnect(struct sd *sd);
 
 int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -102,7 +103,8 @@ const static struct m5602_sensor mt9m111 = {
 
 	.probe = mt9m111_probe,
 	.init = mt9m111_init,
-	.power_down = mt9m111_power_down
+	.power_down = mt9m111_power_down,
+	.disconnect = mt9m111_disconnect,
 };
 
 static const unsigned char preinit_mt9m111[][4] =
-- 
cgit v1.2.3-70-g09d2


From ac3d5bfecc362a91f38ad864f5d34c639f894214 Mon Sep 17 00:00:00 2001
From: Luk?? Karas <lukas.karas@centrum.cz>
Date: Fri, 3 Apr 2009 02:45:56 -0300
Subject: V4L/DVB (11451): gspca - m5602-s5k83a: Add rotation, ctrl cache.
 Rename some ctrls.

s5k83a sensor mounted on many acer laptops have a swiwel allowing it to be rotated. When the camera is in its rotated state, the image needs to be flipped. The only way to check for if the camera has been flipped is to continously poll a register in the m5602. This patch creates a kernel thread which does this. This patch renames some v4l2 ctrls and finally implements a cache in order to prevent unnecessary sensor reads.

Signed-off-by: Luk?? Karas <lukas.karas@centrum.cz>
Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c   |  18 +-
 drivers/media/video/gspca/m5602/m5602_s5k83a.c | 389 +++++++++++++++----------
 drivers/media/video/gspca/m5602/m5602_s5k83a.h |  67 +++--
 3 files changed, 294 insertions(+), 180 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 1aac2985fee..93302f31aa6 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -80,6 +80,16 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
 	return (err < 0) ? err : 0;
 }
 
+int m5602_wait_for_i2c(struct sd *sd)
+{
+	int err;
+	u8 data;
+	do {
+		err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
+	} while ((data & I2C_BUSY) && !err);
+	return (err < 0) ? err : 0;
+}
+
 int m5602_read_sensor(struct sd *sd, const u8 address,
 		       u8 *i2c_data, const u8 len)
 {
@@ -88,9 +98,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
 	if (!len || len > sd->sensor->i2c_regW)
 		return -EINVAL;
 
-	do {
-		err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
-	} while ((*i2c_data & I2C_BUSY) && !err);
+	err = m5602_wait_for_i2c(sd);
 	if (err < 0)
 		return err;
 
@@ -118,6 +126,10 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
 	}
 
 	for (i = 0; (i < len) && !err; i++) {
+		err = m5602_wait_for_i2c(sd);
+		if (err < 0)
+			return err;
+
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
 		PDEBUG(D_CONF, "Reading sensor register "
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 42c86aa4dc8..c77afcab179 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -16,6 +16,7 @@
  *
  */
 
+#include <linux/kthread.h>
 #include "m5602_s5k83a.h"
 
 static struct v4l2_pix_format s5k83a_modes[] = {
@@ -33,47 +34,54 @@ static struct v4l2_pix_format s5k83a_modes[] = {
 };
 
 const static struct ctrl s5k83a_ctrls[] = {
+#define GAIN_IDX 0
 	{
 		{
-			.id = V4L2_CID_BRIGHTNESS,
+			.id = V4L2_CID_GAIN,
 			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "brightness",
+			.name = "gain",
 			.minimum = 0x00,
 			.maximum = 0xff,
 			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_BRIGHTNESS,
+			.default_value = S5K83A_DEFAULT_GAIN,
 			.flags = V4L2_CTRL_FLAG_SLIDER
 		},
-			.set = s5k83a_set_brightness,
-			.get = s5k83a_get_brightness
+			.set = s5k83a_set_gain,
+			.get = s5k83a_get_gain
 
-	}, {
+	},
+#define BRIGHTNESS_IDX 1
+	{
 		{
-			.id = V4L2_CID_WHITENESS,
+			.id = V4L2_CID_BRIGHTNESS,
 			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "whiteness",
+			.name = "brightness",
 			.minimum = 0x00,
 			.maximum = 0xff,
 			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_WHITENESS,
+			.default_value = S5K83A_DEFAULT_BRIGHTNESS,
 			.flags = V4L2_CTRL_FLAG_SLIDER
 		},
-			.set = s5k83a_set_whiteness,
-			.get = s5k83a_get_whiteness,
-	}, {
+			.set = s5k83a_set_brightness,
+			.get = s5k83a_get_brightness,
+	},
+#define EXPOSURE_IDX 2
+	{
 		{
-			.id = V4L2_CID_GAIN,
+			.id = V4L2_CID_EXPOSURE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "gain",
+			.name = "exposure",
 			.minimum = 0x00,
-			.maximum = S5K83A_MAXIMUM_GAIN,
+			.maximum = S5K83A_MAXIMUM_EXPOSURE,
 			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_GAIN,
+			.default_value = S5K83A_DEFAULT_EXPOSURE,
 			.flags = V4L2_CTRL_FLAG_SLIDER
 		},
-			.set = s5k83a_set_gain,
-			.get = s5k83a_get_gain
-	}, {
+			.set = s5k83a_set_exposure,
+			.get = s5k83a_get_exposure
+	},
+#define HFLIP_IDX 3
+	{
 		{
 			.id         = V4L2_CID_HFLIP,
 			.type       = V4L2_CTRL_TYPE_BOOLEAN,
@@ -85,7 +93,9 @@ const static struct ctrl s5k83a_ctrls[] = {
 		},
 			.set = s5k83a_set_hflip,
 			.get = s5k83a_get_hflip
-	}, {
+	},
+#define VFLIP_IDX 4
+	{
 		{
 		 .id         = V4L2_CID_VFLIP,
 		.type       = V4L2_CTRL_TYPE_BOOLEAN,
@@ -101,9 +111,13 @@ const static struct ctrl s5k83a_ctrls[] = {
 };
 
 static void s5k83a_dump_registers(struct sd *sd);
+static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
+static int s5k83a_set_led_indication(struct sd *sd, u8 val);
+int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip);
 
 int s5k83a_probe(struct sd *sd)
 {
+	struct s5k83a_priv *sens_priv;
 	u8 prod_id = 0, ver_id = 0;
 	int i, err = 0;
 
@@ -145,10 +159,28 @@ int s5k83a_probe(struct sd *sd)
 		info("Detected a s5k83a sensor");
 
 sensor_found:
+	sens_priv = kmalloc(
+		sizeof(struct s5k83a_priv), GFP_KERNEL);
+	if (!sens_priv)
+		return -ENOMEM;
+
+	sens_priv->settings =
+	kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
+	if (!sens_priv->settings)
+		return -ENOMEM;
+
 	sd->gspca_dev.cam.cam_mode = s5k83a_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
 	sd->desc->ctrls = s5k83a_ctrls;
 	sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
+
+	/* null the pointer! thread is't running now */
+	sens_priv->rotation_thread = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
+		sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
+
+	sd->sensor_priv = sens_priv;
 	return 0;
 }
 
@@ -190,84 +222,104 @@ int s5k83a_init(struct sd *sd)
 	return (err < 0) ? err : 0;
 }
 
+static int rotation_thread_function(void *data)
+{
+	struct sd *sd = (struct sd *) data;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
+	u8 reg, previous_rotation = 0;
+	__s32 vflip, hflip;
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (!schedule_timeout(100)) {
+		if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
+			break;
+
+		s5k83a_get_rotation(sd, &reg);
+		if (previous_rotation != reg) {
+			previous_rotation = reg;
+			info("Camera was flipped");
+
+			s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
+			s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
+
+			if (reg) {
+				vflip = !vflip;
+				hflip = !hflip;
+			}
+			s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
+		}
+
+		mutex_unlock(&sd->gspca_dev.usb_lock);
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+
+	/* return to "front" flip */
+	if (previous_rotation) {
+		s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
+		s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
+		s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
+	}
+
+	sens_priv->rotation_thread = NULL;
+	return 0;
+}
+
 int s5k83a_start(struct sd *sd)
 {
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+	/* Create another thread, polling the GPIO ports of the camera to check
+	   if it got rotated. This is how the windows driver does it so we have
+	   to assume that there is no better way of accomplishing this */
+	sens_priv->rotation_thread = kthread_create(rotation_thread_function, sd, "rotation thread");
+	wake_up_process(sens_priv->rotation_thread);
+
 	return s5k83a_set_led_indication(sd, 1);
 }
 
 int s5k83a_stop(struct sd *sd)
 {
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+	if (sens_priv->rotation_thread)
+		kthread_stop(sens_priv->rotation_thread);
+
 	return s5k83a_set_led_indication(sd, 0);
 }
 
-int s5k83a_power_down(struct sd *sd)
+void s5k83a_disconnect(struct sd *sd)
 {
-	return 0;
-}
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-static void s5k83a_dump_registers(struct sd *sd)
-{
-	int address;
-	u8 page, old_page;
-	m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+	s5k83a_stop(sd);
 
-	for (page = 0; page < 16; page++) {
-		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
-		info("Dumping the s5k83a register state for page 0x%x", page);
-		for (address = 0; address <= 0xff; address++) {
-			u8 val = 0;
-			m5602_read_sensor(sd, address, &val, 1);
-			info("register 0x%x contains 0x%x",
-			     address, val);
-		}
-	}
-	info("s5k83a register state dump complete");
-
-	for (page = 0; page < 16; page++) {
-		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
-		info("Probing for which registers that are read/write "
-		      "for page 0x%x", page);
-		for (address = 0; address <= 0xff; address++) {
-			u8 old_val, ctrl_val, test_val = 0xff;
-
-			m5602_read_sensor(sd, address, &old_val, 1);
-			m5602_write_sensor(sd, address, &test_val, 1);
-			m5602_read_sensor(sd, address, &ctrl_val, 1);
-
-			if (ctrl_val == test_val)
-				info("register 0x%x is writeable", address);
-			else
-				info("register 0x%x is read only", address);
+	sd->sensor = NULL;
+	kfree(sens_priv->settings);
+	kfree(sens_priv);
+}
 
-			/* Restore original val */
-			m5602_write_sensor(sd, address, &old_val, 1);
-		}
-	}
-	info("Read/write register probing complete");
-	m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+int s5k83a_power_down(struct sd *sd)
+{
+	return 0;
 }
 
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data[2];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
-	if (err < 0)
-		return err;
-
-	data[1] = data[1] << 1;
-	*val = data[1];
-
-	return err;
+	*val = sens_priv->settings[GAIN_IDX];
+	return 0;
 }
 
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+	sens_priv->settings[GAIN_IDX] = val;
 
 	data[0] = 0x00;
 	data[1] = 0x20;
@@ -283,89 +335,68 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 
 	/* FIXME: This is not sane, we need to figure out the composition
 		  of these registers */
-	data[0] = val >> 3; /* brightness, high 5 bits */
-	data[1] = val >> 1; /* brightness, high 7 bits */
-	err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
+	data[0] = val >> 3; /* gain, high 5 bits */
+	data[1] = val >> 1; /* gain, high 7 bits */
+	err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
 
 	return err;
 }
 
-int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
+int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
-	if (err < 0)
-		return err;
-
-	*val = data;
-
-	return err;
+	*val = sens_priv->settings[BRIGHTNESS_IDX];
+	return 0;
 }
 
-int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
+int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[1];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
+	sens_priv->settings[BRIGHTNESS_IDX] = val;
 	data[0] = val;
-	err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
-
+	err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
 	return err;
 }
 
-int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data[2];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
-	if (err < 0)
-		return err;
-
-	data[1] = data[1] & 0x3f;
-	if (data[1] > S5K83A_MAXIMUM_GAIN)
-		data[1] = S5K83A_MAXIMUM_GAIN;
-
-	*val = data[1];
-
-	return err;
+	*val = sens_priv->settings[EXPOSURE_IDX];
+	return 0;
 }
 
-int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
+	sens_priv->settings[EXPOSURE_IDX] = val;
 	data[0] = 0;
 	data[1] = val;
-	err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
+	err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
 	return err;
 }
 
 int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 data[1];
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	data[0] = 0x05;
-	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
-	if (err < 0)
-		return err;
-
-	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
-	*val = (data[0] | 0x40) ? 1 : 0;
-
-	return err;
+	*val = sens_priv->settings[VFLIP_IDX];
+	return 0;
 }
 
-int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip)
 {
 	int err;
 	u8 data[1];
@@ -376,69 +407,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
-	if (err < 0)
-		return err;
+	/* six bit is vflip, seven is hflip */
+	data[0] = S5K83A_FLIP_MASK;
+	data[0] = (vflip) ? data[0] | 0x40 : data[0];
+	data[0] = (hflip) ? data[0] | 0x80 : data[0];
 
-	/* set or zero six bit, seven is hflip */
-	data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
-			: (data[0] & 0x80) | S5K83A_FLIP_MASK;
 	err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
 	if (err < 0)
 		return err;
 
-	data[0] = (val) ? 0x0b : 0x0a;
+	data[0] = (vflip) ? 0x0b : 0x0a;
 	err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
+	if (err < 0)
+		return err;
 
+	data[0] = (hflip) ? 0x0a : 0x0b;
+	err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
 	return err;
 }
 
-int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
-	u8 data[1];
+	u8 reg;
+	__s32 hflip;
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	data[0] = 0x05;
-	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+	sens_priv->settings[VFLIP_IDX] = val;
+
+	s5k83a_get_hflip(gspca_dev, &hflip);
+
+	err = s5k83a_get_rotation(sd, &reg);
 	if (err < 0)
 		return err;
+	if (reg) {
+		val = !val;
+		hflip = !hflip;
+	}
 
-	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
-	*val = (data[0] | 0x80) ? 1 : 0;
-
+	err = s5k83a_set_flip_real(gspca_dev, val, hflip);
 	return err;
 }
 
+int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
+
+	*val = sens_priv->settings[HFLIP_IDX];
+	return 0;
+}
+
 int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
-	u8 data[1];
+	u8 reg;
+	__s32 vflip;
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
-	data[0] = 0x05;
-	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
-	if (err < 0)
-		return err;
+	sens_priv->settings[HFLIP_IDX] = val;
 
-	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
-	if (err < 0)
-		return err;
+	s5k83a_get_vflip(gspca_dev, &vflip);
 
-	/* set or zero seven bit, six is vflip */
-	data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
-			: (data[0] & 0x40) | S5K83A_FLIP_MASK;
-	err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
+	err = s5k83a_get_rotation(sd, &reg);
 	if (err < 0)
 		return err;
+	if (reg) {
+		val = !val;
+		vflip = !vflip;
+	}
 
-	data[0] = (val) ? 0x0a : 0x0b;
-	err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
-
+	err = s5k83a_set_flip_real(gspca_dev, vflip, val);
 	return err;
 }
 
-int s5k83a_set_led_indication(struct sd *sd, u8 val)
+static int s5k83a_set_led_indication(struct sd *sd, u8 val)
 {
 	int err = 0;
 	u8 data[1];
@@ -456,3 +501,53 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val)
 
 	return (err < 0) ? err : 0;
 }
+
+/* Get camera rotation on Acer notebooks */
+static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
+{
+	int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
+	*reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
+	return err;
+}
+
+static void s5k83a_dump_registers(struct sd *sd)
+{
+	int address;
+	u8 page, old_page;
+	m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+
+	for (page = 0; page < 16; page++) {
+		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
+		info("Dumping the s5k83a register state for page 0x%x", page);
+		for (address = 0; address <= 0xff; address++) {
+			u8 val = 0;
+			m5602_read_sensor(sd, address, &val, 1);
+			info("register 0x%x contains 0x%x",
+			     address, val);
+		}
+	}
+	info("s5k83a register state dump complete");
+
+	for (page = 0; page < 16; page++) {
+		m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
+		info("Probing for which registers that are read/write "
+				"for page 0x%x", page);
+		for (address = 0; address <= 0xff; address++) {
+			u8 old_val, ctrl_val, test_val = 0xff;
+
+			m5602_read_sensor(sd, address, &old_val, 1);
+			m5602_write_sensor(sd, address, &test_val, 1);
+			m5602_read_sensor(sd, address, &ctrl_val, 1);
+
+			if (ctrl_val == test_val)
+				info("register 0x%x is writeable", address);
+			else
+				info("register 0x%x is read only", address);
+
+			/* Restore original val */
+			m5602_write_sensor(sd, address, &old_val, 1);
+		}
+	}
+	info("Read/write register probing complete");
+	m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
+}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 819ab25272b..9ca3ca311c8 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -21,20 +21,21 @@
 
 #include "m5602_sensor.h"
 
-#define S5K83A_FLIP				0x01
-#define S5K83A_HFLIP_TUNE			0x03
-#define S5K83A_VFLIP_TUNE			0x05
-#define S5K83A_WHITENESS			0x0a
-#define S5K83A_GAIN				0x18
-#define S5K83A_BRIGHTNESS			0x1b
-#define S5K83A_PAGE_MAP				0xec
-
-#define S5K83A_DEFAULT_BRIGHTNESS		0x71
-#define S5K83A_DEFAULT_WHITENESS		0x7e
-#define S5K83A_DEFAULT_GAIN			0x00
-#define S5K83A_MAXIMUM_GAIN			0x3c
-#define S5K83A_FLIP_MASK			0x10
+#define S5K83A_FLIP			0x01
+#define S5K83A_HFLIP_TUNE		0x03
+#define S5K83A_VFLIP_TUNE		0x05
+#define S5K83A_BRIGHTNESS		0x0a
+#define S5K83A_EXPOSURE			0x18
+#define S5K83A_GAIN			0x1b
+#define S5K83A_PAGE_MAP			0xec
+
+#define S5K83A_DEFAULT_GAIN		0x71
+#define S5K83A_DEFAULT_BRIGHTNESS	0x7e
+#define S5K83A_DEFAULT_EXPOSURE		0x00
+#define S5K83A_MAXIMUM_EXPOSURE		0x3c
+#define S5K83A_FLIP_MASK		0x10
 #define S5K83A_GPIO_LED_MASK		0x10
+#define S5K83A_GPIO_ROTATION_MASK 	0x40
 
 /*****************************************************************************/
 
@@ -47,15 +48,14 @@ int s5k83a_init(struct sd *sd);
 int s5k83a_start(struct sd *sd);
 int s5k83a_stop(struct sd *sd);
 int s5k83a_power_down(struct sd *sd);
+void s5k83a_disconnect(struct sd *sd);
 
-int s5k83a_set_led_indication(struct sd *sd, u8 val);
-
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
+int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -68,10 +68,18 @@ static const struct m5602_sensor s5k83a = {
 	.start = s5k83a_start,
 	.stop = s5k83a_stop,
 	.power_down = s5k83a_power_down,
+	.disconnect = s5k83a_disconnect,
 	.i2c_slave_id = 0x5a,
 	.i2c_regW = 2,
 };
 
+struct s5k83a_priv {
+	/* We use another thread periodically
+	   probing the orientation of the camera */
+	struct task_struct *rotation_thread;
+	s32 *settings;
+};
+
 static const unsigned char preinit_s5k83a[][4] =
 {
 	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
@@ -125,7 +133,7 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
+	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	{SENSOR, 0x03, 0x0b, 0x00},
@@ -232,7 +240,7 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
+	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	/* some values like 0x10 give a blue-purple image */
@@ -320,7 +328,7 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
+	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	{SENSOR, 0x03, 0x0b, 0x00},
@@ -374,24 +382,23 @@ static const unsigned char init_s5k83a[][4] =
 	   (this is value after boot, but after tries can be different) */
 	{SENSOR, 0x00, 0x06, 0x00},
 
-	/* set default brightness */
+	/* set default gain */
 	{SENSOR_LONG, 0x14, 0x00, 0x20},
 	{SENSOR_LONG, 0x0d, 0x01, 0x00},
-	{SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3,
-			    S5K83A_DEFAULT_BRIGHTNESS >> 1},
+	{SENSOR_LONG, 0x1b, S5K83A_DEFAULT_GAIN >> 3,
+		S5K83A_DEFAULT_GAIN >> 1},
 
-	/* set default whiteness */
-	{SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
+	/* set default brightness */
+	{SENSOR, S5K83A_BRIGHTNESS, S5K83A_DEFAULT_BRIGHTNESS, 0x00},
 
-	/* set default gain */
-	{SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
+	/* set default exposure */
+	{SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_EXPOSURE},
 
 	/* set default flip */
 	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 	{SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
 	{SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
 	{SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
-
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 05d7d9ced6fa6153735123412ba8bef329f80a53 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 6 Jan 2009 06:39:11 -0300
Subject: V4L/DVB (11452): gspca - m5602-po1030: Convert to have a v4l2 ctrl
 cache

Let the po1030 have a local v4l2 ctrl cache as this minimizes the load on reading the registers and improves performance.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 140 ++++++++++++++-----------
 drivers/media/video/gspca/m5602/m5602_po1030.h |   2 +
 2 files changed, 79 insertions(+), 63 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index eaddf488bad..27596fd6152 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -32,6 +32,7 @@ static struct v4l2_pix_format po1030_modes[] = {
 };
 
 const static struct ctrl po1030_ctrls[] = {
+#define GAIN_IDX 0
 	{
 		{
 			.id 		= V4L2_CID_GAIN,
@@ -45,7 +46,9 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_gain,
 		.get = po1030_get_gain
-	}, {
+	},
+#define EXPOSURE_IDX 1
+	{
 		{
 			.id 		= V4L2_CID_EXPOSURE,
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
@@ -58,7 +61,9 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_exposure,
 		.get = po1030_get_exposure
-	}, {
+	},
+#define RED_BALANCE_IDX 2
+	{
 		{
 			.id 		= V4L2_CID_RED_BALANCE,
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
@@ -71,7 +76,9 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_red_balance,
 		.get = po1030_get_red_balance
-	}, {
+	},
+#define BLUE_BALANCE_IDX 3
+	{
 		{
 			.id 		= V4L2_CID_BLUE_BALANCE,
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
@@ -84,7 +91,9 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_blue_balance,
 		.get = po1030_get_blue_balance
-	}, {
+	},
+#define HFLIP_IDX 4
+	{
 		{
 			.id 		= V4L2_CID_HFLIP,
 			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
@@ -96,7 +105,9 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_hflip,
 		.get = po1030_get_hflip
-	}, {
+	},
+#define VFLIP_IDX 5
+	{
 		{
 			.id 		= V4L2_CID_VFLIP,
 			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
@@ -116,6 +127,7 @@ static void po1030_dump_registers(struct sd *sd);
 int po1030_probe(struct sd *sd)
 {
 	u8 prod_id = 0, ver_id = 0, i;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	if (force_sensor) {
 		if (force_sensor == PO1030_SENSOR) {
@@ -152,10 +164,19 @@ int po1030_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
+	sensor_settings = kmalloc(
+		ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
 	sd->gspca_dev.cam.cam_mode = po1030_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
 	sd->desc->ctrls = po1030_ctrls;
 	sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
+
+	for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
+		sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
+	sd->sensor_priv = sensor_settings;
 	return 0;
 }
 
@@ -195,30 +216,21 @@ int po1030_init(struct sd *sd)
 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
-
-	err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
-				 &i2c_data, 1);
-	if (err < 0)
-		return err;
-	*val = (i2c_data << 8);
-
-	err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
-				 &i2c_data, 1);
-	*val |= i2c_data;
+	s32 *sensor_settings = sd->sensor_priv;
 
+	*val = sensor_settings[EXPOSURE_IDX];
 	PDEBUG(D_V4L2, "Exposure read as %d", *val);
-
-	return err;
+	return 0;
 }
 
 int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
+	sensor_settings[EXPOSURE_IDX] = val;
 	PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
 
 	i2c_data = ((val & 0xff00) >> 8);
@@ -242,39 +254,49 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
-				 &i2c_data, 1);
-	*val = i2c_data;
+	*val = sensor_settings[GAIN_IDX];
 	PDEBUG(D_V4L2, "Read global gain %d", *val);
-
-	return err;
+	return 0;
 }
 
-int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
-	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
+	sensor_settings[GAIN_IDX] = val;
+
+	i2c_data = val & 0xff;
+	PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
+	err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
 				 &i2c_data, 1);
+	return err;
+}
 
-	*val = (i2c_data >> 7) & 0x01 ;
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
+	*val = sensor_settings[HFLIP_IDX];
 	PDEBUG(D_V4L2, "Read hflip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
+	sensor_settings[HFLIP_IDX] = val;
+
 	PDEBUG(D_V4L2, "Set hflip %d", val);
 	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
 	if (err < 0)
@@ -291,25 +313,23 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
-
-	err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
-				 &i2c_data, 1);
-
-	*val = (i2c_data >> 6) & 0x01;
+	s32 *sensor_settings = sd->sensor_priv;
 
+	*val= sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vflip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
+	sensor_settings[VFLIP_IDX] = val;
+
 	PDEBUG(D_V4L2, "Set vflip %d", val);
 	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
 	if (err < 0)
@@ -323,38 +343,25 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
-
-	i2c_data = val & 0xff;
-	PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
-	err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
-				  &i2c_data, 1);
-	return err;
-}
-
 int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
-				 &i2c_data, 1);
-	*val = i2c_data;
+	*val = sensor_settings[RED_BALANCE_IDX];
 	PDEBUG(D_V4L2, "Read red gain %d", *val);
-	return err;
+	return 0;
 }
 
 int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
+	sensor_settings[RED_BALANCE_IDX] = val;
+
 	i2c_data = val & 0xff;
 	PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
 	err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
@@ -365,22 +372,23 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
-				 &i2c_data, 1);
-	*val = i2c_data;
+	*val = sensor_settings[BLUE_BALANCE_IDX];
 	PDEBUG(D_V4L2, "Read blue gain %d", *val);
 
-	return err;
+	return 0;
 }
 
 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
+
+	sensor_settings[BLUE_BALANCE_IDX] = val;
+
 	i2c_data = val & 0xff;
 	PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
 	err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
@@ -394,6 +402,12 @@ int po1030_power_down(struct sd *sd)
 	return 0;
 }
 
+void po1030_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
 static void po1030_dump_registers(struct sd *sd)
 {
 	int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index c10b1233581..4c04d1b9a1b 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -127,6 +127,7 @@ extern int dump_sensor;
 int po1030_probe(struct sd *sd);
 int po1030_init(struct sd *sd);
 int po1030_power_down(struct sd *sd);
+void po1030_disconnect(struct sd *sd);
 
 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
@@ -150,6 +151,7 @@ static const struct m5602_sensor po1030 = {
 	.probe = po1030_probe,
 	.init = po1030_init,
 	.power_down = po1030_power_down,
+	.disconnect = po1030_disconnect,
 };
 
 static const unsigned char preinit_po1030[][3] =
-- 
cgit v1.2.3-70-g09d2


From a594fb4866ddebcb413577974654be8cffc37a1b Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 6 Jan 2009 11:37:03 -0300
Subject: V4L/DVB (11453): gspca - m5602-s5k4aa: Convert to use the v4l2 ctrl
 cache

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 103 +++++++++++++------------
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h |   7 +-
 2 files changed, 59 insertions(+), 51 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 4306d596056..84ca7532c75 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -65,6 +65,7 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
 };
 
 const static struct ctrl s5k4aa_ctrls[] = {
+#define VFLIP_IDX 0
 	{
 		{
 			.id 		= V4L2_CID_VFLIP,
@@ -77,8 +78,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
 		},
 		.set = s5k4aa_set_vflip,
 		.get = s5k4aa_get_vflip
-
-	}, {
+	},
+#define HFLIP_IDX 1
+	{
 		{
 			.id 		= V4L2_CID_HFLIP,
 			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
@@ -90,8 +92,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
 		},
 		.set = s5k4aa_set_hflip,
 		.get = s5k4aa_get_hflip
-
-	}, {
+	},
+#define GAIN_IDX 2
+	{
 		{
 			.id		= V4L2_CID_GAIN,
 			.type		= V4L2_CTRL_TYPE_INTEGER,
@@ -104,7 +107,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
 		},
 		.set = s5k4aa_set_gain,
 		.get = s5k4aa_get_gain
-	}, {
+	},
+#define EXPOSURE_IDX 3
+	{
 		{
 			.id		= V4L2_CID_EXPOSURE,
 			.type		= V4L2_CTRL_TYPE_INTEGER,
@@ -127,6 +132,7 @@ int s5k4aa_probe(struct sd *sd)
 	u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 	const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
 	int i, err = 0;
+	s32 *sensor_settings;
 
 	if (force_sensor) {
 		if (force_sensor == S5K4AA_SENSOR) {
@@ -185,10 +191,19 @@ int s5k4aa_probe(struct sd *sd)
 		info("Detected a s5k4aa sensor");
 
 sensor_found:
+	sensor_settings = kmalloc(
+		ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
 	sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
 	sd->desc->ctrls = s5k4aa_ctrls;
 	sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
+
+	for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
+		sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
+	sd->sensor_priv = sensor_settings;
 	return 0;
 }
 
@@ -301,31 +316,22 @@ int s5k4aa_power_down(struct sd *sd)
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 data = S5K4AA_PAGE_MAP_2;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	if (err < 0)
-		return err;
-
-	err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
-	if (err < 0)
-		return err;
-
-	*val = data << 8;
-	err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
-	*val |= data;
+	*val = sensor_settings[EXPOSURE_IDX];
 	PDEBUG(D_V4L2, "Read exposure %d", *val);
 
-	return err;
+	return 0;
 }
 
 int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
+	sensor_settings[EXPOSURE_IDX] = val;
 	PDEBUG(D_V4L2, "Set exposure to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
@@ -343,26 +349,23 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 data = S5K4AA_PAGE_MAP_2;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	if (err < 0)
-		return err;
-
-	err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	*val = (data & S5K4AA_RM_V_FLIP) >> 7;
+	*val = sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
+	sensor_settings[VFLIP_IDX] = val;
+
 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
@@ -370,6 +373,10 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
 		return err;
+
+	if (dmi_check_system(s5k4aa_vflip_dmi_table))
+		val = !val;
+
 	data = ((data & ~S5K4AA_RM_V_FLIP)
 			| ((val & 0x01) << 7));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
@@ -398,28 +405,24 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 data = S5K4AA_PAGE_MAP_2;
-	int err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	if (err < 0)
-		return err;
-
-	err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	*val = (data & S5K4AA_RM_H_FLIP) >> 6;
+	*val = sensor_settings[HFLIP_IDX];
 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(D_V4L2, "Set horizontal flip to %d",
-	       val);
+	sensor_settings[HFLIP_IDX] = val;
+
+	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
@@ -454,26 +457,22 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 data = S5K4AA_PAGE_MAP_2;
-	int err;
-
-	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-	if (err < 0)
-		return err;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
-	*val = data;
+	*val = sensor_settings[GAIN_IDX];
 	PDEBUG(D_V4L2, "Read gain %d", *val);
-
-	return err;
+	return 0;
 }
 
 int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
+	sensor_settings[GAIN_IDX] = val;
+
 	PDEBUG(D_V4L2, "Set gain to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
@@ -485,6 +484,12 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+void s5k4aa_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
 static void s5k4aa_dump_registers(struct sd *sd)
 {
 	int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index ca854d4f947..958fb72d405 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -67,6 +67,7 @@ int s5k4aa_probe(struct sd *sd);
 int s5k4aa_init(struct sd *sd);
 int s5k4aa_start(struct sd *sd);
 int s5k4aa_power_down(struct sd *sd);
+void s5k4aa_disconnect(struct sd *sd);
 
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
@@ -79,12 +80,14 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 
 static const struct m5602_sensor s5k4aa = {
 	.name = "S5K4AA",
+	.i2c_slave_id = 0x5a,
+	.i2c_regW = 2,
+
 	.probe = s5k4aa_probe,
 	.init = s5k4aa_init,
 	.start = s5k4aa_start,
 	.power_down = s5k4aa_power_down,
-	.i2c_slave_id = 0x5a,
-	.i2c_regW = 2,
+	.disconnect = s5k4aa_disconnect,
 };
 
 static const unsigned char preinit_s5k4aa[][4] =
-- 
cgit v1.2.3-70-g09d2


From 09a7480ec127d26cade353b49f912c3348f6532e Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 6 Jan 2009 11:59:42 -0300
Subject: V4L/DVB (11454): gspca - m5602-mt9m111: Remove the unused power_down
 struct member

The power_down sensor struct member is almost has no purpose in the current driver abstraction. Remove it.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c |  5 -----
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  2 --
 drivers/media/video/gspca/m5602/m5602_ov9650.c  | 17 -----------------
 drivers/media/video/gspca/m5602/m5602_ov9650.h  | 22 ----------------------
 drivers/media/video/gspca/m5602/m5602_po1030.c  |  5 -----
 drivers/media/video/gspca/m5602/m5602_po1030.h  |  2 --
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c  |  5 -----
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h  |  2 --
 drivers/media/video/gspca/m5602/m5602_s5k83a.c  |  5 -----
 drivers/media/video/gspca/m5602/m5602_s5k83a.h  |  2 --
 drivers/media/video/gspca/m5602/m5602_sensor.h  |  3 ---
 11 files changed, 70 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 43791a6b8d2..519548d07af 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -165,11 +165,6 @@ int mt9m111_init(struct sd *sd)
 	return (err < 0) ? err : 0;
 }
 
-int mt9m111_power_down(struct sd *sd)
-{
-	return 0;
-}
-
 void mt9m111_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 03769fc0442..91386324757 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -85,7 +85,6 @@ extern int dump_sensor;
 
 int mt9m111_probe(struct sd *sd);
 int mt9m111_init(struct sd *sd);
-int mt9m111_power_down(struct sd *sd);
 void mt9m111_disconnect(struct sd *sd);
 
 int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -103,7 +102,6 @@ const static struct m5602_sensor mt9m111 = {
 
 	.probe = mt9m111_probe,
 	.init = mt9m111_init,
-	.power_down = mt9m111_power_down,
 	.disconnect = mt9m111_disconnect,
 };
 
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index fc4548fd441..5ea93a85b7d 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -467,26 +467,9 @@ int ov9650_stop(struct sd *sd)
 	return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
 }
 
-int ov9650_power_down(struct sd *sd)
-{
-	int i, err = 0;
-	for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
-		u8 data = power_down_ov9650[i][2];
-		if (power_down_ov9650[i][0] == SENSOR)
-			err = m5602_write_sensor(sd,
-					    power_down_ov9650[i][1], &data, 1);
-		else
-			err = m5602_write_bridge(sd, power_down_ov9650[i][1],
-						 data);
-	}
-
-	return err;
-}
-
 void ov9650_disconnect(struct sd *sd)
 {
 	ov9650_stop(sd);
-	ov9650_power_down(sd);
 
 	sd->sensor = NULL;
 	kfree(sd->sensor_priv);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index fcc54e4c0f4..b81f26505e2 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -137,7 +137,6 @@ int ov9650_probe(struct sd *sd);
 int ov9650_init(struct sd *sd);
 int ov9650_start(struct sd *sd);
 int ov9650_stop(struct sd *sd);
-int ov9650_power_down(struct sd *sd);
 void ov9650_disconnect(struct sd *sd);
 
 int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
@@ -167,7 +166,6 @@ const static struct m5602_sensor ov9650 = {
 	.init = ov9650_init,
 	.start = ov9650_start,
 	.stop = ov9650_stop,
-	.power_down = ov9650_power_down,
 	.disconnect = ov9650_disconnect,
 };
 
@@ -312,26 +310,6 @@ static const unsigned char init_ov9650[][3] =
 	{SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
 };
 
-static const unsigned char power_down_ov9650[][3] =
-{
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{SENSOR, OV9650_COM7, 0x80},
-	{SENSOR, OV9650_OFON, 0xf4},
-	{SENSOR, OV9650_MVFP, 0x80},
-	{SENSOR, OV9650_DBLV, 0x3f},
-	{SENSOR, OV9650_RSVD36, 0x49},
-	{SENSOR, OV9650_COM7, 0x05},
-
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-};
-
 static const unsigned char res_init_ov9650[][3] =
 {
 	{SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 27596fd6152..1e9a3066067 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -397,11 +397,6 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_power_down(struct sd *sd)
-{
-	return 0;
-}
-
 void po1030_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 4c04d1b9a1b..c55c31a913d 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -126,7 +126,6 @@ extern int dump_sensor;
 
 int po1030_probe(struct sd *sd);
 int po1030_init(struct sd *sd);
-int po1030_power_down(struct sd *sd);
 void po1030_disconnect(struct sd *sd);
 
 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -150,7 +149,6 @@ static const struct m5602_sensor po1030 = {
 
 	.probe = po1030_probe,
 	.init = po1030_init,
-	.power_down = po1030_power_down,
 	.disconnect = po1030_disconnect,
 };
 
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 84ca7532c75..e8fbeac626c 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -308,11 +308,6 @@ int s5k4aa_init(struct sd *sd)
 	return (err < 0) ? err : 0;
 }
 
-int s5k4aa_power_down(struct sd *sd)
-{
-	return 0;
-}
-
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 958fb72d405..9ffcb5d1a13 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -66,7 +66,6 @@ extern int dump_sensor;
 int s5k4aa_probe(struct sd *sd);
 int s5k4aa_init(struct sd *sd);
 int s5k4aa_start(struct sd *sd);
-int s5k4aa_power_down(struct sd *sd);
 void s5k4aa_disconnect(struct sd *sd);
 
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -86,7 +85,6 @@ static const struct m5602_sensor s5k4aa = {
 	.probe = s5k4aa_probe,
 	.init = s5k4aa_init,
 	.start = s5k4aa_start,
-	.power_down = s5k4aa_power_down,
 	.disconnect = s5k4aa_disconnect,
 };
 
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index c77afcab179..b43a3b04a82 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -298,11 +298,6 @@ void s5k83a_disconnect(struct sd *sd)
 	kfree(sens_priv);
 }
 
-int s5k83a_power_down(struct sd *sd)
-{
-	return 0;
-}
-
 int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 9ca3ca311c8..02a5e25598c 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -47,7 +47,6 @@ int s5k83a_probe(struct sd *sd);
 int s5k83a_init(struct sd *sd);
 int s5k83a_start(struct sd *sd);
 int s5k83a_stop(struct sd *sd);
-int s5k83a_power_down(struct sd *sd);
 void s5k83a_disconnect(struct sd *sd);
 
 int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
@@ -67,7 +66,6 @@ static const struct m5602_sensor s5k83a = {
 	.init = s5k83a_init,
 	.start = s5k83a_start,
 	.stop = s5k83a_stop,
-	.power_down = s5k83a_power_down,
 	.disconnect = s5k83a_disconnect,
 	.i2c_slave_id = 0x5a,
 	.i2c_regW = 2,
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 0d3026936f2..987dcb23ec6 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -61,9 +61,6 @@ struct m5602_sensor {
 
 	/* Executed when the device is disconnected */
 	void (*disconnect)(struct sd *sd);
-
-	/* Performs a power down sequence */
-	int (*power_down)(struct sd *sd);
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 6f02d76161e7d1b52e4994d83177209a5a93bc7e Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 6 Jan 2009 12:58:50 -0300
Subject: V4L/DVB (11455): gspca - m5602-ov9650: Improve the vflip quirk
 handling.

Regardless of the actual sensor orientation vflip = 0 is normal, and vflip = 1 is upside down. This patch makes that happen

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 5ea93a85b7d..2107f3cf673 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -289,12 +289,6 @@ sensor_found:
 	for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
 		sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
-
-	if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
-		info("vflip quirk active");
-		sensor_settings[VFLIP_IDX] = 1;
-	}
-
 	return 0;
 }
 
@@ -360,7 +354,10 @@ int ov9650_start(struct sd *sd)
 	int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
 	int hor_offs = OV9650_LEFT_OFFSET;
 
-	if (sensor_settings[VFLIP_IDX])
+	if ((!dmi_check_system(ov9650_flip_dmi_table) &&
+		sensor_settings[VFLIP_IDX]) ||
+		(dmi_check_system(ov9650_flip_dmi_table) &&
+		!sensor_settings[VFLIP_IDX]))
 		ver_offs--;
 
 	if (width <= 320)
@@ -629,7 +626,12 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 
 	sensor_settings[HFLIP_IDX] = val;
-	i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
+
+	if (!dmi_check_system(ov9650_flip_dmi_table))
+		i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
+	else
+		i2c_data = ((val & 0x01) << 5) | (!sensor_settings[VFLIP_IDX] << 4);
+
 	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 
 	return err;
@@ -656,6 +658,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 	sensor_settings[VFLIP_IDX] = val;
 
+	if (dmi_check_system(ov9650_flip_dmi_table))
+		val = !val;
+
 	i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
 	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 	if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From bb9460eb96571c3f0ad493e54b28f04e33df6041 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Wed, 7 Jan 2009 13:54:13 -0300
Subject: V4L/DVB (11456): gspca - m5602-po1030: Rename register defines, add
 missing ones.

The po1030 register defines are unnecessarily complex, simplify them and also add some missing ones.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c |  18 +-
 drivers/media/video/gspca/m5602/m5602_po1030.h | 261 +++++++++++++------------
 2 files changed, 143 insertions(+), 136 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 1e9a3066067..413c5b899d8 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -237,7 +237,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
 	       i2c_data);
 
-	err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
+	err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
 				  &i2c_data, 1);
 	if (err < 0)
 		return err;
@@ -245,7 +245,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	i2c_data = (val & 0xff);
 	PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
 	       i2c_data);
-	err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
+	err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
 				  &i2c_data, 1);
 
 	return err;
@@ -272,7 +272,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 
 	i2c_data = val & 0xff;
 	PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
-	err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
+	err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
 				 &i2c_data, 1);
 	return err;
 }
@@ -298,13 +298,13 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	sensor_settings[HFLIP_IDX] = val;
 
 	PDEBUG(D_V4L2, "Set hflip %d", val);
-	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
+	err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
 	if (err < 0)
 		return err;
 
 	i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
 
-	err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
+	err = m5602_write_sensor(sd, PO1030_CONTROL2,
 				 &i2c_data, 1);
 
 	return err;
@@ -331,13 +331,13 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	sensor_settings[VFLIP_IDX] = val;
 
 	PDEBUG(D_V4L2, "Set vflip %d", val);
-	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
+	err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
 	if (err < 0)
 		return err;
 
 	i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
 
-	err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
+	err = m5602_write_sensor(sd, PO1030_CONTROL2,
 				 &i2c_data, 1);
 
 	return err;
@@ -364,7 +364,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 
 	i2c_data = val & 0xff;
 	PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
-	err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
+	err = m5602_write_sensor(sd, PO1030_RED_GAIN,
 				  &i2c_data, 1);
 	return err;
 }
@@ -391,7 +391,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 
 	i2c_data = val & 0xff;
 	PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
-	err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
+	err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
 				  &i2c_data, 1);
 
 	return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index c55c31a913d..7402701d521 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -25,88 +25,95 @@
 
 /*****************************************************************************/
 
-#define PO1030_REG_DEVID_H		0x00
-#define PO1030_REG_DEVID_L		0x01
-#define PO1030_REG_FRAMEWIDTH_H		0x04
-#define PO1030_REG_FRAMEWIDTH_L		0x05
-#define PO1030_REG_FRAMEHEIGHT_H	0x06
-#define PO1030_REG_FRAMEHEIGHT_L	0x07
-#define PO1030_REG_WINDOWX_H		0x08
-#define PO1030_REG_WINDOWX_L		0x09
-#define PO1030_REG_WINDOWY_H		0x0a
-#define PO1030_REG_WINDOWY_L		0x0b
-#define PO1030_REG_WINDOWWIDTH_H	0x0c
-#define PO1030_REG_WINDOWWIDTH_L	0x0d
-#define PO1030_REG_WINDOWHEIGHT_H	0x0e
-#define PO1030_REG_WINDOWHEIGHT_L	0x0f
-
-#define PO1030_REG_GLOBALIBIAS		0x12
-#define PO1030_REG_PIXELIBIAS		0x13
-
-#define PO1030_REG_GLOBALGAIN		0x15
-#define PO1030_REG_RED_GAIN		0x16
-#define PO1030_REG_GREEN_1_GAIN		0x17
-#define PO1030_REG_BLUE_GAIN		0x18
-#define PO1030_REG_GREEN_2_GAIN		0x19
-
-#define PO1030_REG_INTEGLINES_H		0x1a
-#define PO1030_REG_INTEGLINES_M		0x1b
-#define PO1030_REG_INTEGLINES_L		0x1c
-
-#define PO1030_REG_CONTROL1		0x1d
-#define PO1030_REG_CONTROL2		0x1e
-#define PO1030_REG_CONTROL3		0x1f
-#define PO1030_REG_CONTROL4		0x20
-
-#define PO1030_REG_PERIOD50_H		0x23
-#define PO1030_REG_PERIOD50_L		0x24
-#define PO1030_REG_PERIOD60_H		0x25
-#define PO1030_REG_PERIOD60_L		0x26
-#define PO1030_REG_REGCLK167		0x27
-#define PO1030_REG_DELTA50		0x28
-#define PO1030_REG_DELTA60		0x29
-
-#define PO1030_REG_ADCOFFSET		0x2c
+#define PO1030_DEVID_H		0x00
+#define PO1030_DEVID_L		0x01
+#define PO1030_FRAMEWIDTH_H	0x04
+#define PO1030_FRAMEWIDTH_L	0x05
+#define PO1030_FRAMEHEIGHT_H	0x06
+#define PO1030_FRAMEHEIGHT_L	0x07
+#define PO1030_WINDOWX_H	0x08
+#define PO1030_WINDOWX_L	0x09
+#define PO1030_WINDOWY_H	0x0a
+#define PO1030_WINDOWY_L	0x0b
+#define PO1030_WINDOWWIDTH_H	0x0c
+#define PO1030_WINDOWWIDTH_L	0x0d
+#define PO1030_WINDOWHEIGHT_H	0x0e
+#define PO1030_WINDOWHEIGHT_L	0x0f
+
+#define PO1030_GLOBALIBIAS	0x12
+#define PO1030_PIXELIBIAS	0x13
+
+#define PO1030_GLOBALGAIN	0x15
+#define PO1030_RED_GAIN		0x16
+#define PO1030_GREEN_1_GAIN	0x17
+#define PO1030_BLUE_GAIN	0x18
+#define PO1030_GREEN_2_GAIN	0x19
+
+#define PO1030_INTEGLINES_H	0x1a
+#define PO1030_INTEGLINES_M	0x1b
+#define PO1030_INTEGLINES_L	0x1c
+
+#define PO1030_CONTROL1		0x1d
+#define PO1030_CONTROL2		0x1e
+#define PO1030_CONTROL3		0x1f
+#define PO1030_CONTROL4		0x20
+
+#define PO1030_PERIOD50_H	0x23
+#define PO1030_PERIOD50_L	0x24
+#define PO1030_PERIOD60_H	0x25
+#define PO1030_PERIOD60_L	0x26
+#define PO1030_REGCLK167	0x27
+#define PO1030_FLICKER_DELTA50	0x28
+#define PO1030_FLICKERDELTA60	0x29
+
+#define PO1030_ADCOFFSET	0x2c
 
 /* Gamma Correction Coeffs */
-#define PO1030_REG_GC0			0x2d
-#define PO1030_REG_GC1			0x2e
-#define PO1030_REG_GC2			0x2f
-#define PO1030_REG_GC3			0x30
-#define PO1030_REG_GC4			0x31
-#define PO1030_REG_GC5			0x32
-#define PO1030_REG_GC6			0x33
-#define PO1030_REG_GC7			0x34
+#define PO1030_GC0		0x2d
+#define PO1030_GC1		0x2e
+#define PO1030_GC2		0x2f
+#define PO1030_GC3		0x30
+#define PO1030_GC4		0x31
+#define PO1030_GC5		0x32
+#define PO1030_GC6		0x33
+#define PO1030_GC7		0x34
 
 /* Color Transform Matrix */
-#define PO1030_REG_CT0			0x35
-#define PO1030_REG_CT1			0x36
-#define PO1030_REG_CT2			0x37
-#define PO1030_REG_CT3			0x38
-#define PO1030_REG_CT4			0x39
-#define PO1030_REG_CT5			0x3a
-#define PO1030_REG_CT6			0x3b
-#define PO1030_REG_CT7			0x3c
-#define PO1030_REG_CT8			0x3d
-
-#define PO1030_REG_AUTOCTRL1		0x3e
-#define PO1030_REG_AUTOCTRL2		0x3f
-
-#define PO1030_REG_YTARGET		0x40
-#define PO1030_REG_GLOBALGAINMIN	0x41
-#define PO1030_REG_GLOBALGAINMAX	0x42
+#define PO1030_CT0		0x35
+#define PO1030_CT1		0x36
+#define PO1030_CT2		0x37
+#define PO1030_CT3		0x38
+#define PO1030_CT4		0x39
+#define PO1030_CT5		0x3a
+#define PO1030_CT6		0x3b
+#define PO1030_CT7		0x3c
+#define PO1030_CT8		0x3d
+
+#define PO1030_AUTOCTRL1	0x3e
+#define PO1030_AUTOCTRL2	0x3f
+
+#define PO1030_YTARGET		0x40
+#define PO1030_GLOBALGAINMIN	0x41
+#define PO1030_GLOBALGAINMAX	0x42
+
+#define PO1030_AWB_RED_TUNING	0x47
+#define PO1030_AWB_BLUE_TUNING	0x48
 
 /* Output format control */
-#define PO1030_REG_OUTFORMCTRL1		0x5a
-#define PO1030_REG_OUTFORMCTRL2		0x5b
-#define PO1030_REG_OUTFORMCTRL3		0x5c
-#define PO1030_REG_OUTFORMCTRL4		0x5d
-#define PO1030_REG_OUTFORMCTRL5		0x5e
+#define PO1030_OUTFORMCTRL1	0x5a
+#define PO1030_OUTFORMCTRL2	0x5b
+#define PO1030_OUTFORMCTRL3	0x5c
+#define PO1030_OUTFORMCTRL4	0x5d
+#define PO1030_OUTFORMCTRL5	0x5e
 
-/* Imaging coefficients */
-#define PO1030_REG_YBRIGHT		0x73
-#define PO1030_REG_YCONTRAST		0x74
-#define PO1030_REG_YSATURATION		0x75
+#define PO1030_EDGE_ENH_OFF	0x5f
+#define PO1030_EGA		0x60
+
+#define PO1030_Cb_U_GAIN	0x63
+#define PO1030_Cr_V_GAIN	0x64
+
+#define PO1030_YCONTRAST	0x74
+#define PO1030_YSATURATION	0x75
 
 #define PO1030_HFLIP			(1 << 7)
 #define PO1030_VFLIP			(1 << 6)
@@ -164,7 +171,7 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
 
-	{SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, 0x24},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -196,7 +203,7 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 
-	{SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, 0x24},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -229,7 +236,7 @@ static const unsigned char init_po1030[][4] =
 	/*end of sequence 1*/
 
 	/*sequence 2 (same as stop sequence)*/
-	{SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, 0x24},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
@@ -266,7 +273,7 @@ static const unsigned char init_po1030[][4] =
 	/*end of sequence 5*/
 
 	/*sequence 2 stop */
-	{SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, 0x24},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -293,58 +300,58 @@ static const unsigned char init_po1030[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
 
-	{SENSOR, PO1030_REG_AUTOCTRL2, 0x04},
+	{SENSOR, PO1030_AUTOCTRL2, 0x04},
 
 	/* Set the width to 751 */
-	{SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
-	{SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef},
+	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
+	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
 
 	/* Set the height to 540 */
-	{SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02},
-	{SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c},
+	{SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
+	{SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
 
 	/* Set the x window to 1 */
-	{SENSOR, PO1030_REG_WINDOWX_H, 0x00},
-	{SENSOR, PO1030_REG_WINDOWX_L, 0x01},
+	{SENSOR, PO1030_WINDOWX_H, 0x00},
+	{SENSOR, PO1030_WINDOWX_L, 0x01},
 
 	/* Set the y window to 1 */
-	{SENSOR, PO1030_REG_WINDOWY_H, 0x00},
-	{SENSOR, PO1030_REG_WINDOWY_L, 0x01},
-
-	{SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
-	{SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
-	{SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01},
-	{SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3},
-
-	{SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
-	{SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
-	{SENSOR, PO1030_REG_AUTOCTRL1, 0x08},
-	{SENSOR, PO1030_REG_CONTROL2, 0x03},
+	{SENSOR, PO1030_WINDOWY_H, 0x00},
+	{SENSOR, PO1030_WINDOWY_L, 0x01},
+
+	{SENSOR, PO1030_WINDOWWIDTH_H, 0x02},
+	{SENSOR, PO1030_WINDOWWIDTH_L, 0x87},
+	{SENSOR, PO1030_WINDOWHEIGHT_H, 0x01},
+	{SENSOR, PO1030_WINDOWHEIGHT_L, 0xe3},
+
+	{SENSOR, PO1030_OUTFORMCTRL2, 0x04},
+	{SENSOR, PO1030_OUTFORMCTRL2, 0x04},
+	{SENSOR, PO1030_AUTOCTRL1, 0x08},
+	{SENSOR, PO1030_CONTROL2, 0x03},
 	{SENSOR, 0x21, 0x90},
-	{SENSOR, PO1030_REG_YTARGET, 0x60},
+	{SENSOR, PO1030_YTARGET, 0x60},
 	{SENSOR, 0x59, 0x13},
-	{SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40},
-	{SENSOR, 0x5f, 0x00},
-	{SENSOR, 0x60, 0x80},
+	{SENSOR, PO1030_OUTFORMCTRL1, 0x40},
+	{SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
+	{SENSOR, PO1030_EGA, 0x80},
 	{SENSOR, 0x78, 0x14},
 	{SENSOR, 0x6f, 0x01},
-	{SENSOR, PO1030_REG_CONTROL1, 0x18},
-	{SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14},
-	{SENSOR, 0x63, 0x38},
-	{SENSOR, 0x64, 0x38},
-	{SENSOR, PO1030_REG_CONTROL1, 0x58},
-	{SENSOR, PO1030_REG_RED_GAIN, 0x30},
-	{SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30},
-	{SENSOR, PO1030_REG_BLUE_GAIN, 0x30},
-	{SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30},
-	{SENSOR, PO1030_REG_GC0, 0x10},
-	{SENSOR, PO1030_REG_GC1, 0x20},
-	{SENSOR, PO1030_REG_GC2, 0x40},
-	{SENSOR, PO1030_REG_GC3, 0x60},
-	{SENSOR, PO1030_REG_GC4, 0x80},
-	{SENSOR, PO1030_REG_GC5, 0xa0},
-	{SENSOR, PO1030_REG_GC6, 0xc0},
-	{SENSOR, PO1030_REG_GC7, 0xff},
+	{SENSOR, PO1030_CONTROL1, 0x18},
+	{SENSOR, PO1030_GLOBALGAINMAX, 0x14},
+	{SENSOR, PO1030_Cb_U_GAIN, 0x38},
+	{SENSOR, PO1030_Cr_V_GAIN, 0x38},
+	{SENSOR, PO1030_CONTROL1, 0x58},
+	{SENSOR, PO1030_RED_GAIN, 0x30},
+	{SENSOR, PO1030_GREEN_1_GAIN, 0x30},
+	{SENSOR, PO1030_BLUE_GAIN, 0x30},
+	{SENSOR, PO1030_GREEN_2_GAIN, 0x30},
+	{SENSOR, PO1030_GC0, 0x10},
+	{SENSOR, PO1030_GC1, 0x20},
+	{SENSOR, PO1030_GC2, 0x40},
+	{SENSOR, PO1030_GC3, 0x60},
+	{SENSOR, PO1030_GC4, 0x80},
+	{SENSOR, PO1030_GC5, 0xa0},
+	{SENSOR, PO1030_GC6, 0xc0},
+	{SENSOR, PO1030_GC7, 0xff},
 	/*end of sequence 4*/
 	/*sequence 5*/
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
@@ -374,10 +381,10 @@ static const unsigned char init_po1030[][4] =
 	/*sequence 6*/
 	/* Changing 40 in f0 the image becomes green in bayer mode and red in
 	 * rgb mode */
-	{SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
+	{SENSOR, PO1030_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
 	/* in changing 40 in f0 the image becomes green in bayer mode and red in
 	 * rgb mode */
-	{SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
+	{SENSOR, PO1030_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
 
 	/* with a very low lighted environment increase the exposure but
 	 * decrease the FPS (Frame Per Second) */
@@ -386,20 +393,20 @@ static const unsigned char init_po1030[][4] =
 
 	/* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in
 	 * low lighted environment (f0 is more than ff ?)*/
-	{SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2)
+	{SENSOR, PO1030_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2)
 		& 0xff)},
 
 	/* Controls middle exposure, use only in high lighted environment */
-	{SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
+	{SENSOR, PO1030_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
 
 	/* Controls clarity (not sure) */
-	{SENSOR, PO1030_REG_INTEGLINES_L, 0x00},
+	{SENSOR, PO1030_INTEGLINES_L, 0x00},
 	/* Controls gain (the image is more lighted) */
-	{SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
+	{SENSOR, PO1030_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
 
 	/* Sets the width */
-	{SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
-	{SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}
+	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
+	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef}
 	/*end of sequence 6*/
 };
 
-- 
cgit v1.2.3-70-g09d2


From 274290822e22bf4d5394ce029c867a4051342d38 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Wed, 7 Jan 2009 17:41:47 -0300
Subject: V4L/DVB (11457): gspca - m5602-po1030: Simplify register defines

This patch renames some register defines in the ov9650 sensor.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c |  2 +-
 drivers/media/video/gspca/m5602/m5602_po1030.h | 47 ++++++++++++++++++--------
 2 files changed, 33 insertions(+), 16 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 413c5b899d8..800b5f4cb0e 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -315,7 +315,7 @@ int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
 
-	*val= sensor_settings[VFLIP_IDX];
+	*val = sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vflip %d", *val);
 
 	return 0;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 7402701d521..3e9648794df 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -115,8 +115,23 @@
 #define PO1030_YCONTRAST	0x74
 #define PO1030_YSATURATION	0x75
 
-#define PO1030_HFLIP			(1 << 7)
-#define PO1030_VFLIP			(1 << 6)
+#define PO1030_HFLIP		(1 << 7)
+#define PO1030_VFLIP		(1 << 6)
+
+#define PO1030_HREF_ENABLE	(1 << 6)
+
+#define PO1030_RAW_RGB_BAYER	0x4
+
+#define PO1030_FRAME_EQUAL	(1 << 3)
+#define PO1030_AUTO_SUBSAMPLING (1 << 4)
+
+#define PO1030_WEIGHT_WIN_2X	(1 << 3)
+
+#define PO1030_SHUTTER_MODE	(1 << 6)
+#define PO1030_AUTO_SUBSAMPLING	(1 << 4)
+#define PO1030_FRAME_EQUAL	(1 << 3)
+
+#define PO1030_SENSOR_RESET	(1 << 5)
 
 /*****************************************************************************/
 
@@ -171,7 +186,7 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
 
-	{SENSOR, PO1030_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -203,7 +218,7 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 
-	{SENSOR, PO1030_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -271,9 +286,8 @@ static const unsigned char init_po1030[][4] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 	/*end of sequence 5*/
-
 	/*sequence 2 stop */
-	{SENSOR, PO1030_AUTOCTRL2, 0x24},
+	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -318,31 +332,35 @@ static const unsigned char init_po1030[][4] =
 	{SENSOR, PO1030_WINDOWY_H, 0x00},
 	{SENSOR, PO1030_WINDOWY_L, 0x01},
 
+	/* Set the window width to 647 */
 	{SENSOR, PO1030_WINDOWWIDTH_H, 0x02},
 	{SENSOR, PO1030_WINDOWWIDTH_L, 0x87},
+
+	/* Set the window height to 483 */
 	{SENSOR, PO1030_WINDOWHEIGHT_H, 0x01},
 	{SENSOR, PO1030_WINDOWHEIGHT_L, 0xe3},
 
-	{SENSOR, PO1030_OUTFORMCTRL2, 0x04},
-	{SENSOR, PO1030_OUTFORMCTRL2, 0x04},
-	{SENSOR, PO1030_AUTOCTRL1, 0x08},
+	{SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
+	{SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
+	/* This makes no sense, hflip and vflp is located at bit 7, 6 */
 	{SENSOR, PO1030_CONTROL2, 0x03},
 	{SENSOR, 0x21, 0x90},
 	{SENSOR, PO1030_YTARGET, 0x60},
 	{SENSOR, 0x59, 0x13},
-	{SENSOR, PO1030_OUTFORMCTRL1, 0x40},
+	{SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
 	{SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
 	{SENSOR, PO1030_EGA, 0x80},
 	{SENSOR, 0x78, 0x14},
 	{SENSOR, 0x6f, 0x01},
-	{SENSOR, PO1030_CONTROL1, 0x18},
+	{SENSOR, PO1030_CONTROL1, PO1030_AUTO_SUBSAMPLING |
+				  PO1030_FRAME_EQUAL},
 	{SENSOR, PO1030_GLOBALGAINMAX, 0x14},
 	{SENSOR, PO1030_Cb_U_GAIN, 0x38},
 	{SENSOR, PO1030_Cr_V_GAIN, 0x38},
-	{SENSOR, PO1030_CONTROL1, 0x58},
-	{SENSOR, PO1030_RED_GAIN, 0x30},
+	{SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
+				  PO1030_AUTO_SUBSAMPLING |
+				  PO1030_FRAME_EQUAL},
 	{SENSOR, PO1030_GREEN_1_GAIN, 0x30},
-	{SENSOR, PO1030_BLUE_GAIN, 0x30},
 	{SENSOR, PO1030_GREEN_2_GAIN, 0x30},
 	{SENSOR, PO1030_GC0, 0x10},
 	{SENSOR, PO1030_GC1, 0x20},
@@ -377,7 +395,6 @@ static const unsigned char init_po1030[][4] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 	/*end of sequence 5*/
-
 	/*sequence 6*/
 	/* Changing 40 in f0 the image becomes green in bayer mode and red in
 	 * rgb mode */
-- 
cgit v1.2.3-70-g09d2


From cb29e691977ac7677ca62c13cc9aa1eab2463075 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Wed, 7 Jan 2009 18:05:08 -0300
Subject: V4L/DVB (11458): gspca - m5602-po1030: Set all v4l2 controls at
 sensor init

Previously many of the v4l2 ctrls were set to their initial values at resume from ram/disk. This patch enforces the values stored in the ctrl cache.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 34 +++++++++++++++++++++++---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 20 +--------------
 2 files changed, 32 insertions(+), 22 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 800b5f4cb0e..7ec3fbffc4b 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -127,7 +127,7 @@ static void po1030_dump_registers(struct sd *sd);
 int po1030_probe(struct sd *sd)
 {
 	u8 prod_id = 0, ver_id = 0, i;
-	s32 *sensor_settings = sd->sensor_priv;
+	s32 *sensor_settings;
 
 	if (force_sensor) {
 		if (force_sensor == PO1030_SENSOR) {
@@ -177,11 +177,16 @@ sensor_found:
 	for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
 		sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
+
+	if (dump_sensor)
+		po1030_dump_registers(sd);
+
 	return 0;
 }
 
 int po1030_init(struct sd *sd)
 {
+	s32 *sensor_settings = sd->sensor_priv;
 	int i, err = 0;
 
 	/* Init the sensor */
@@ -206,10 +211,33 @@ int po1030_init(struct sd *sd)
 			return -EINVAL;
 		}
 	}
+	if (err < 0)
+		return err;
 
-	if (dump_sensor)
-		po1030_dump_registers(sd);
+	err = po1030_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_red_balance(&sd->gspca_dev,
+				      sensor_settings[RED_BALANCE_IDX]);
+	if (err < 0)
+		return err;
 
+	err = po1030_set_red_balance(&sd->gspca_dev,
+				      sensor_settings[BLUE_BALANCE_IDX]);
 	return err;
 }
 
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 3e9648794df..013be33d1b2 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -371,6 +371,7 @@ static const unsigned char init_po1030[][4] =
 	{SENSOR, PO1030_GC6, 0xc0},
 	{SENSOR, PO1030_GC7, 0xff},
 	/*end of sequence 4*/
+
 	/*sequence 5*/
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
@@ -396,31 +397,12 @@ static const unsigned char init_po1030[][4] =
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 	/*end of sequence 5*/
 	/*sequence 6*/
-	/* Changing 40 in f0 the image becomes green in bayer mode and red in
-	 * rgb mode */
-	{SENSOR, PO1030_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
-	/* in changing 40 in f0 the image becomes green in bayer mode and red in
-	 * rgb mode */
-	{SENSOR, PO1030_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
 
 	/* with a very low lighted environment increase the exposure but
 	 * decrease the FPS (Frame Per Second) */
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 
-	/* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in
-	 * low lighted environment (f0 is more than ff ?)*/
-	{SENSOR, PO1030_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2)
-		& 0xff)},
-
-	/* Controls middle exposure, use only in high lighted environment */
-	{SENSOR, PO1030_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
-
-	/* Controls clarity (not sure) */
-	{SENSOR, PO1030_INTEGLINES_L, 0x00},
-	/* Controls gain (the image is more lighted) */
-	{SENSOR, PO1030_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
-
 	/* Sets the width */
 	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
 	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef}
-- 
cgit v1.2.3-70-g09d2


From 3b9ae658ec77180d13152913a1f63b6f1b2756c2 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 03:53:50 -0300
Subject: V4L/DVB (11459): gspca - m5602-po1030: Add auto white balancing
 control

Add a po1030 auto white balancing control that's disabled by default

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 51 ++++++++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_po1030.h |  2 +
 2 files changed, 53 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 7ec3fbffc4b..7eec6e8ca72 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -119,6 +119,20 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_vflip,
 		.get = po1030_get_vflip
+	},
+#define AUTO_WHITE_BALANCE_IDX 6
+	{
+		{
+			.id 		= V4L2_CID_AUTO_WHITE_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto white balance",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_auto_white_balance,
+		.get = po1030_get_auto_white_balance
 	}
 };
 
@@ -238,6 +252,14 @@ int po1030_init(struct sd *sd)
 
 	err = po1030_set_red_balance(&sd->gspca_dev,
 				      sensor_settings[BLUE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_auto_white_balance(&sd->gspca_dev,
+				      sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
 	return err;
 }
 
@@ -425,6 +447,35 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
+
+	return 0;
+}
+
+int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	u8 i2c_data;
+	int err;
+
+	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
+
+	err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	i2c_data = (i2c_data & 0xfe) | (val & 0x01);
+	err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+	return err;
+}
+
 void po1030_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 013be33d1b2..1260cfa6e4e 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -162,6 +162,8 @@ int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
 
 static const struct m5602_sensor po1030 = {
 	.name = "PO1030",
-- 
cgit v1.2.3-70-g09d2


From 31e1715f9765206711c3a10556428e9d8fa2acad Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 04:01:23 -0300
Subject: V4L/DVB (11460): gspca - m5602-po1030: Remove unnecessary error check

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 3 ---
 1 file changed, 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 7eec6e8ca72..0547841b2cb 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -257,9 +257,6 @@ int po1030_init(struct sd *sd)
 
 	err = po1030_set_auto_white_balance(&sd->gspca_dev,
 				      sensor_settings[AUTO_WHITE_BALANCE_IDX]);
-	if (err < 0)
-		return err;
-
 	return err;
 }
 
-- 
cgit v1.2.3-70-g09d2


From fcb981080a08c033cf6f1e7e5c4ff706a37a659d Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 04:04:19 -0300
Subject: V4L/DVB (11461): gspca - m5602-po1030: Probe read only register at
 probe time

Currently, we're probing r/w registers at probe time.
This is potentially dangerous, probe some read only registers instead.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 0547841b2cb..122c777c71c 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -140,7 +140,7 @@ static void po1030_dump_registers(struct sd *sd);
 
 int po1030_probe(struct sd *sd)
 {
-	u8 prod_id = 0, ver_id = 0, i;
+	u8 dev_id_h = 0, dev_id_l = 0, i;
 	s32 *sensor_settings;
 
 	if (force_sensor) {
@@ -165,13 +165,13 @@ int po1030_probe(struct sd *sd)
 			m5602_write_bridge(sd, preinit_po1030[i][1], data);
 	}
 
-	if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
+	if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
 		return -ENODEV;
 
-	if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
+	if (m5602_read_sensor(sd, PO1030_DEVID_L, &dev_id_l, 1))
 		return -ENODEV;
 
-	if ((prod_id == 0x02) && (ver_id == 0xef)) {
+	if ((dev_id_h == 0x10) && (dev_id_l == 0x30)) {
 		info("Detected a po1030 sensor");
 		goto sensor_found;
 	}
-- 
cgit v1.2.3-70-g09d2


From c996b36809af0e5ee441b411f947c3b53d43a104 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 14:15:06 -0300
Subject: V4L/DVB (11462): gspca - m5602-po1030: Split up the init into init
 and start

Split up the po1030 init into start and init. Add a start function.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 17 +++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_po1030.h | 14 +++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 122c777c71c..c2bd12eeb5e 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -260,6 +260,23 @@ int po1030_init(struct sd *sd)
 	return err;
 }
 
+int po1030_start(struct sd *sd)
+{
+	int i, err = 0;
+	/* Synthesize the vsync/hsync setup */
+	for (i = 0; i < ARRAY_SIZE(start_po1030) && !err; i++) {
+		if (start_po1030[i][0] == BRIDGE)
+			err = m5602_write_bridge(sd, start_po1030[i][1],
+				start_po1030[i][2]);
+		else if (start_po1030[i][0] == SENSOR) {
+			u8 data = start_po1030[i][2];
+			err = m5602_write_sensor(sd,
+					start_po1030[i][1], &data, 1);
+		}
+	}
+	return err;
+}
+
 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 1260cfa6e4e..451d2065213 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -148,6 +148,7 @@ extern int dump_sensor;
 
 int po1030_probe(struct sd *sd);
 int po1030_init(struct sd *sd);
+int po1030_start(struct sd *sd);
 void po1030_disconnect(struct sd *sd);
 
 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -173,6 +174,7 @@ static const struct m5602_sensor po1030 = {
 
 	.probe = po1030_probe,
 	.init = po1030_init,
+	.start = po1030_start,
 	.disconnect = po1030_disconnect,
 };
 
@@ -237,7 +239,7 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00}
 };
 
-static const unsigned char init_po1030[][4] =
+static const unsigned char init_po1030[][3] =
 {
 	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
 	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
@@ -299,11 +301,13 @@ static const unsigned char init_po1030[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	/*end of sequence 2 stop */
+};
 
-/* ---------------------------------
- * end of init - begin of start
- * --------------------------------- */
-
+static const unsigned char start_po1030[][3] =
+{
+	/* ---------------------------------
+	 * end of init - begin of start
+	 * --------------------------------- */
 	/*sequence 3*/
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-- 
cgit v1.2.3-70-g09d2


From 6e5ccf83eff19dee5aba11aa484dd4426adbbfdf Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 14:22:51 -0300
Subject: V4L/DVB (11463): gspca - m5602-po1030: Remove unneeded init sequences

po1030: There's a lot of redundant writes to the bridge and sensor.
Remove them.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 52 --------------------------
 1 file changed, 52 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 451d2065213..9ccf89e5914 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -254,42 +254,6 @@ static const unsigned char init_po1030[][3] =
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
 	/*end of sequence 1*/
 
-	/*sequence 2 (same as stop sequence)*/
-	{SENSOR, PO1030_AUTOCTRL2, 0x24},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	/*end of sequence 2*/
-
-	/*sequence 5*/
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	/*end of sequence 5*/
 	/*sequence 2 stop */
 	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
@@ -305,15 +269,6 @@ static const unsigned char init_po1030[][3] =
 
 static const unsigned char start_po1030[][3] =
 {
-	/* ---------------------------------
-	 * end of init - begin of start
-	 * --------------------------------- */
-	/*sequence 3*/
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	/*end of sequence 3*/
 	/*sequence 4*/
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
@@ -358,8 +313,6 @@ static const unsigned char start_po1030[][3] =
 	{SENSOR, PO1030_EGA, 0x80},
 	{SENSOR, 0x78, 0x14},
 	{SENSOR, 0x6f, 0x01},
-	{SENSOR, PO1030_CONTROL1, PO1030_AUTO_SUBSAMPLING |
-				  PO1030_FRAME_EQUAL},
 	{SENSOR, PO1030_GLOBALGAINMAX, 0x14},
 	{SENSOR, PO1030_Cb_U_GAIN, 0x38},
 	{SENSOR, PO1030_Cr_V_GAIN, 0x38},
@@ -408,11 +361,6 @@ static const unsigned char start_po1030[][3] =
 	 * decrease the FPS (Frame Per Second) */
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-
-	/* Sets the width */
-	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
-	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef}
-	/*end of sequence 6*/
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From dd3ec39871ba83fb47364a26b1caaac4494deb7b Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 8 Jan 2009 18:11:05 -0300
Subject: V4L/DVB (11464): gspca - m5602-mt9m111: Set the cached v4l2 ctrl
 values

When we resume the machine we want the previously set values, not the default
values. Fix this for the mt9m111 sensor

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 17 ++++++++++++++---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  6 ------
 2 files changed, 14 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 519548d07af..8700f37deca 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -136,12 +136,16 @@ sensor_found:
 		sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
 
+	if (dump_sensor)
+		mt9m111_dump_registers(sd);
+
 	return 0;
 }
 
 int mt9m111_init(struct sd *sd)
 {
 	int i, err = 0;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	/* Init the sensor */
 	for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
@@ -159,10 +163,17 @@ int mt9m111_init(struct sd *sd)
 		}
 	}
 
-	if (dump_sensor)
-		mt9m111_dump_registers(sd);
+	err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 
-	return (err < 0) ? err : 0;
+	return err;
 }
 
 void mt9m111_disconnect(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 91386324757..c198734c807 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -290,7 +290,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
-	{SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
 
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -452,7 +451,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
-	{SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 
@@ -590,7 +588,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
-	{SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
@@ -766,7 +763,6 @@ static const unsigned char init_mt9m111[][4] =
 
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
-	{SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
@@ -945,8 +941,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	/* Set number of blank rows chosen to 400 */
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
-	/* Set the global gain to 283 (of 512) */
-	{SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63}
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From d4a389a39bb9586219641144ab0c79706bbc8bcc Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 03:30:54 -0300
Subject: V4L/DVB (11465): gspca - m5602-s5k4aa: Set all v4l2 ctrls on sensor
 init.

Reset all v4l2 ctrls on the s5k4aa init. The prevents all ctrls to be reset
during resume from ram.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 45 +++++++++++++-------------
 1 file changed, 22 insertions(+), 23 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index e8fbeac626c..fe574ef24c9 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -204,6 +204,10 @@ sensor_found:
 	for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
 		sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
+
+	if (dump_sensor)
+		s5k4aa_dump_registers(sd);
+
 	return 0;
 }
 
@@ -213,8 +217,7 @@ int s5k4aa_start(struct sd *sd)
 	u8 data[2];
 	struct cam *cam = &sd->gspca_dev.cam;
 
-	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
-	{
+	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
 
@@ -253,6 +256,7 @@ int s5k4aa_start(struct sd *sd)
 int s5k4aa_init(struct sd *sd)
 {
 	int i, err = 0;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
 		u8 data[2] = {0x00, 0x00};
@@ -282,30 +286,22 @@ int s5k4aa_init(struct sd *sd)
 		}
 	}
 
-	if (dump_sensor)
-		s5k4aa_dump_registers(sd);
+	err = s5k4aa_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
 
-	if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
-		u8 data = 0x02;
-		info("vertical flip quirk active");
-		m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
-		m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
-		data |= S5K4AA_RM_V_FLIP;
-		data &= ~S5K4AA_RM_H_FLIP;
-		m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
-
-		/* Decrement COLSTART to preserve color order (BGGR) */
-		m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-		data--;
-		m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
+	err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
 
-		/* Increment ROWSTART to preserve color order (BGGR) */
-		m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-		data++;
-		m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-	}
+	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
 
-	return (err < 0) ? err : 0;
+	err = s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+
+	return err;
 }
 
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -378,6 +374,9 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
+	if (dmi_check_system(s5k4aa_vflip_dmi_table))
+		val = !val;
+
 	if (val) {
 		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 		if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From cf811d506a3ed5721e3f22c77309aff489ce54c7 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 3 Apr 2009 02:49:10 -0300
Subject: V4L/DVB (11466): gspca - m5602: Let all ctrls on all sensors be
 static

All hail the static keyword

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c |  22 +++--
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |   7 --
 drivers/media/video/gspca/m5602/m5602_ov9650.c  | 115 +++++++++++-------------
 drivers/media/video/gspca/m5602/m5602_ov9650.h  |  19 ----
 drivers/media/video/gspca/m5602/m5602_po1030.c  |  47 +++++++---
 drivers/media/video/gspca/m5602/m5602_po1030.h  |  15 ----
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c  |  25 ++++--
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h  |   9 --
 drivers/media/video/gspca/m5602/m5602_s5k83a.c  |  31 ++++---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h  |  11 ---
 10 files changed, 137 insertions(+), 164 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8700f37deca..8017782efee 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,13 @@
 
 #include "m5602_mt9m111.h"
 
+static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
 		640,
@@ -123,7 +130,8 @@ int mt9m111_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
-	sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), GFP_KERNEL);
+	sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
+				  GFP_KERNEL);
 	if (!sensor_settings)
 		return -ENOMEM;
 
@@ -182,7 +190,7 @@ void mt9m111_disconnect(struct sd *sd)
 	kfree(sd->sensor_priv);
 }
 
-int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -193,7 +201,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2] = {0x00, 0x00};
@@ -219,7 +227,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -230,7 +238,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2] = {0x00, 0x00};
@@ -255,7 +263,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -266,7 +274,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err, tmp;
 	u8 data[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index c198734c807..dbda4a63d83 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -87,13 +87,6 @@ int mt9m111_probe(struct sd *sd);
 int mt9m111_init(struct sd *sd);
 void mt9m111_disconnect(struct sd *sd);
 
-int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-
 const static struct m5602_sensor mt9m111 = {
 	.name = "MT9M111",
 
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 2107f3cf673..8d830afcedb 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,6 +18,25 @@
 
 #include "m5602_ov9650.h"
 
+static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val);
+static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val);
+static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
+
 /* Vertically and horizontally flips the image if matched, needed for machines
    where the sensor is mounted upside down */
 static
@@ -310,7 +329,8 @@ int ov9650_init(struct sd *sd)
 			err = m5602_write_bridge(sd, init_ov9650[i][1], data);
 	}
 
-	err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
+	err = ov9650_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
 	if (err < 0)
 		return err;
 
@@ -318,11 +338,13 @@ int ov9650_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
+	err = ov9650_set_red_balance(&sd->gspca_dev,
+				      sensor_settings[RED_BALANCE_IDX]);
 	if (err < 0)
 		return err;
 
-	err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
+	err = ov9650_set_blue_balance(&sd->gspca_dev,
+				       sensor_settings[BLUE_BALANCE_IDX]);
 	if (err < 0)
 		return err;
 
@@ -334,11 +356,13 @@ int ov9650_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+	err = ov9650_set_auto_white_balance(&sd->gspca_dev,
+				sensor_settings[AUTO_WHITE_BALANCE_IDX]);
 	if (err < 0)
 		return err;
 
-	err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);
+	err = ov9650_set_auto_gain(&sd->gspca_dev,
+				    sensor_settings[AUTO_GAIN_CTRL_IDX]);
 	return err;
 }
 
@@ -472,7 +496,7 @@ void ov9650_disconnect(struct sd *sd)
 	kfree(sd->sensor_priv);
 }
 
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -482,7 +506,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -512,7 +536,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -522,7 +546,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -553,7 +577,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -563,7 +587,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -579,7 +603,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -590,7 +614,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -606,7 +630,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -616,7 +640,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -628,16 +652,18 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	sensor_settings[HFLIP_IDX] = val;
 
 	if (!dmi_check_system(ov9650_flip_dmi_table))
-		i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
+		i2c_data = ((val & 0x01) << 5) |
+				(sensor_settings[VFLIP_IDX] << 4);
 	else
-		i2c_data = ((val & 0x01) << 5) | (!sensor_settings[VFLIP_IDX] << 4);
+		i2c_data = ((val & 0x01) << 5) |
+				(!sensor_settings[VFLIP_IDX] << 4);
 
 	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 
 	return err;
 }
 
-int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -648,7 +674,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -673,48 +699,8 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	s32 *sensor_settings = sd->sensor_priv;
-
-	*val = sensor_settings[GAIN_IDX];
-	PDEBUG(D_V4L2, "Read gain %d", *val);
-
-	return 0;
-}
-
-int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
-{
-	int err;
-	u8 i2c_data;
-	struct sd *sd = (struct sd *) gspca_dev;
-	s32 *sensor_settings = sd->sensor_priv;
-
-	PDEBUG(D_V4L2, "Set gain to %d", val);
-
-	sensor_settings[GAIN_IDX] = val;
-
-	/* Read the OV9650_VREF register first to avoid
-		corrupting the VREF high and low bits */
-	err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
-	if (err < 0)
-		return err;
-
-	/* Mask away all uninteresting bits */
-	i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
-	err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
-	if (err < 0)
-		return err;
-
-	/* The 8 LSBs */
-	i2c_data = val & 0xff;
-	err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
-
-	return err;
-}
-
-int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -723,7 +709,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val)
 {
 	int err;
 	u8 i2c_data;
@@ -743,7 +730,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -753,7 +740,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 i2c_data;
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index b81f26505e2..e0ba41870a4 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -139,25 +139,6 @@ int ov9650_start(struct sd *sd);
 int ov9650_stop(struct sd *sd);
 void ov9650_disconnect(struct sd *sd);
 
-int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
-int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
-
 const static struct m5602_sensor ov9650 = {
 	.name = "OV9650",
 	.i2c_slave_id = 0x60,
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index c2bd12eeb5e..79dcf9bfdd5 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,23 @@
 
 #include "m5602_po1030.h"
 
+static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val);
+static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val);
+
 static struct v4l2_pix_format po1030_modes[] = {
 	{
 		640,
@@ -277,7 +294,7 @@ int po1030_start(struct sd *sd)
 	return err;
 }
 
-int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -287,7 +304,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -315,7 +332,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -325,7 +342,7 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -341,7 +358,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -352,7 +369,7 @@ int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -374,7 +391,7 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -385,7 +402,7 @@ int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -407,7 +424,7 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -417,7 +434,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -433,7 +450,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -444,7 +461,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -461,7 +478,8 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -472,7 +490,8 @@ int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 9ccf89e5914..5ba3f73b787 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -151,21 +151,6 @@ int po1030_init(struct sd *sd);
 int po1030_start(struct sd *sd);
 void po1030_disconnect(struct sd *sd);
 
-int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
-int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
-
 static const struct m5602_sensor po1030 = {
 	.name = "PO1030",
 
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index fe574ef24c9..1ec5ac08d4f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,15 @@
 
 #include "m5602_s5k4aa.h"
 
+static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+
 static
     const
 	struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
@@ -304,7 +313,7 @@ int s5k4aa_init(struct sd *sd)
 	return err;
 }
 
-int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -315,7 +324,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -337,7 +346,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -348,7 +357,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -396,7 +405,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -407,7 +416,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -448,7 +457,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
@@ -458,7 +467,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	s32 *sensor_settings = sd->sensor_priv;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 9ffcb5d1a13..7a8da1dc443 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -68,15 +68,6 @@ int s5k4aa_init(struct sd *sd);
 int s5k4aa_start(struct sd *sd);
 void s5k4aa_disconnect(struct sd *sd);
 
-int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-
 static const struct m5602_sensor s5k4aa = {
 	.name = "S5K4AA",
 	.i2c_slave_id = 0x5a,
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index b43a3b04a82..8d54535724f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -19,6 +19,17 @@
 #include <linux/kthread.h>
 #include "m5602_s5k83a.h"
 
+static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+
 static struct v4l2_pix_format s5k83a_modes[] = {
 	{
 		640,
@@ -298,7 +309,7 @@ void s5k83a_disconnect(struct sd *sd)
 	kfree(sens_priv);
 }
 
-int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
@@ -307,7 +318,7 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2];
@@ -337,7 +348,7 @@ int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
@@ -346,7 +357,7 @@ int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[1];
@@ -359,7 +370,7 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
@@ -368,7 +379,7 @@ int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 data[2];
@@ -382,7 +393,7 @@ int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
@@ -421,7 +432,7 @@ int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip)
 	return err;
 }
 
-int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 reg;
@@ -445,7 +456,7 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
-int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
@@ -454,7 +465,7 @@ int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	u8 reg;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 02a5e25598c..e939385322a 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -49,17 +49,6 @@ int s5k83a_start(struct sd *sd);
 int s5k83a_stop(struct sd *sd);
 void s5k83a_disconnect(struct sd *sd);
 
-int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
-int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
-int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-
 static const struct m5602_sensor s5k83a = {
 	.name = "S5K83A",
 	.probe = s5k83a_probe,
-- 
cgit v1.2.3-70-g09d2


From 36e756c5cc024174fec48ba21f1011aed5707e25 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 13:35:00 -0300
Subject: V4L/DVB (11467): gspca - m5602: Move all dump_sensor to the init
 function

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 6 +++---
 drivers/media/video/gspca/m5602/m5602_po1030.c  | 6 +++---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c  | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8017782efee..8036619e799 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -144,9 +144,6 @@ sensor_found:
 		sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
 
-	if (dump_sensor)
-		mt9m111_dump_registers(sd);
-
 	return 0;
 }
 
@@ -171,6 +168,9 @@ int mt9m111_init(struct sd *sd)
 		}
 	}
 
+	if (dump_sensor)
+		mt9m111_dump_registers(sd);
+
 	err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
 	if (err < 0)
 		return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 79dcf9bfdd5..3ecb53c701a 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -209,9 +209,6 @@ sensor_found:
 		sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
 
-	if (dump_sensor)
-		po1030_dump_registers(sd);
-
 	return 0;
 }
 
@@ -245,6 +242,9 @@ int po1030_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	if (dump_sensor)
+		po1030_dump_registers(sd);
+
 	err = po1030_set_exposure(&sd->gspca_dev,
 				   sensor_settings[EXPOSURE_IDX]);
 	if (err < 0)
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 1ec5ac08d4f..41f6956e3af 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -214,9 +214,6 @@ sensor_found:
 		sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
 	sd->sensor_priv = sensor_settings;
 
-	if (dump_sensor)
-		s5k4aa_dump_registers(sd);
-
 	return 0;
 }
 
@@ -295,6 +292,9 @@ int s5k4aa_init(struct sd *sd)
 		}
 	}
 
+	if (dump_sensor)
+		s5k4aa_dump_registers(sd);
+
 	err = s5k4aa_set_exposure(&sd->gspca_dev,
 				   sensor_settings[EXPOSURE_IDX]);
 	if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From 60b1d3e3de6921fb44661e4772f85ae8d8942f6e Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 13:41:28 -0300
Subject: V4L/DVB (11468): gspca - m5602-mt9m111: Remove redundant init
 sequences

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 122 ------------------------
 1 file changed, 122 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index dbda4a63d83..f7dbce160d6 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -257,58 +257,9 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
 	{SENSOR, 0x30, 0x04, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
@@ -418,32 +369,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
 	{SENSOR, 0x30, 0x04, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 
@@ -557,28 +482,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
 	{SENSOR, 0x30, 0x04, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
@@ -729,31 +632,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
 	{SENSOR, 0x30, 0x04, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 320aaab872474e4b1c3c3d9807dfe304a7850681 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 13:53:20 -0300
Subject: V4L/DVB (11469): gspca - m5602-mt9m111: More redundant init cleanup

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c |  1 -
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 11 +++++------
 2 files changed, 5 insertions(+), 7 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8036619e799..a057b8d5d74 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -84,7 +84,6 @@ const static struct ctrl mt9m111_ctrls[] = {
 	}
 };
 
-
 static void mt9m111_dump_registers(struct sd *sd);
 
 int mt9m111_probe(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index f7dbce160d6..e7b7347ea43 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -74,6 +74,8 @@
 #define MT9M111_COLORPIPE			0x01
 #define MT9M111_CAMERA_CONTROL			0x02
 
+#define MT9M111_COLOR_MATRIX_BYPASS		(1 << 4)
+
 #define INITIAL_MAX_GAIN			64
 #define DEFAULT_GAIN 				283
 
@@ -186,7 +188,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
@@ -298,7 +299,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
@@ -411,7 +411,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
@@ -550,7 +549,6 @@ static const unsigned char init_mt9m111[][4] =
 
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
@@ -700,7 +698,8 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
+	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
+			MT9M111_CP_OPERATING_MODE_CTL},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
@@ -796,7 +795,7 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, /* 480 */
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-- 
cgit v1.2.3-70-g09d2


From b154044a020072c031c7175d2711adc2c6049e93 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 14:03:27 -0300
Subject: V4L/DVB (11470): gspca - m5602-mt9m111: Implement an auto white
 balancing control

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 50 +++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index a057b8d5d74..37a7fc82a53 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -24,6 +24,11 @@ static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val);
+static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					  __s32 *val);
+
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
@@ -81,6 +86,20 @@ const static struct ctrl mt9m111_ctrls[] = {
 		},
 		.set = mt9m111_set_gain,
 		.get = mt9m111_get_gain
+	},
+#define AUTO_WHITE_BALANCE_IDX 3
+	{
+		{
+			.id             = V4L2_CID_AUTO_WHITE_BALANCE,
+			.type           = V4L2_CTRL_TYPE_BOOLEAN,
+			.name           = "auto white balance",
+			.minimum        = 0,
+			.maximum        = 1,
+			.step           = 1,
+			.default_value  = 0,
+		},
+		.set = mt9m111_set_auto_white_balance,
+		.get = mt9m111_get_auto_white_balance
 	}
 };
 
@@ -273,6 +292,37 @@ static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
+static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					  __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	int err;
+	u8 data[2];
+
+	err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
+	if (err < 0)
+		return err;
+
+	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
+	data[0] = ((data[0] & 0xfd) | ((val & 0x01) << 1));
+
+	err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
+
+	PDEBUG(D_V4L2, "Set auto white balance %d", val);
+	return err;
+}
+
+static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					  __s32 *val) {
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Read auto white balance %d", *val);
+	return 0;
+}
+
 static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err, tmp;
-- 
cgit v1.2.3-70-g09d2


From d9cb33bd974a6de94c251c0048c682070ed99dbb Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 9 Jan 2009 14:10:19 -0300
Subject: V4L/DVB (11471): gspca - m5602-mt9m111: Remove more redundant init

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 50 +------------------------
 1 file changed, 1 insertion(+), 49 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index e7b7347ea43..fe83f42937c 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -181,22 +181,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
 
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
-	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-
 	{SENSOR, 0xcd, 0x00, 0x0e},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
 	{SENSOR, 0xd0, 0x00, 0x40},
@@ -292,21 +276,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
 
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
-	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
 	{SENSOR, 0xcd, 0x00, 0x0e},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
@@ -410,14 +379,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
-	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
 
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
 	{SENSOR, 0xcd, 0x00, 0x0e},
@@ -547,16 +508,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
-	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
 	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
@@ -696,6 +647,7 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
+
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
-- 
cgit v1.2.3-70-g09d2


From 65df609b63836d96b0485a0823a81e87f628d3f1 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sat, 10 Jan 2009 10:55:07 -0300
Subject: V4L/DVB (11472): gspca - m5602-mt9m111: Remove lots of redundant init
 code

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 352 ------------------------
 1 file changed, 352 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index fe83f42937c..0ffa98c0ff6 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -159,185 +159,10 @@ static const unsigned char init_mt9m111[][4] =
 
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
 
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
 
-	{SENSOR, 0xcd, 0x00, 0x0e},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
-	{SENSOR, 0xd0, 0x00, 0x40},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
-	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{SENSOR, 0x33, 0x03, 0x49},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
-	{SENSOR, 0x33, 0x03, 0x49},
-	{SENSOR, 0x34, 0xc0, 0x19},
-	{SENSOR, 0x3f, 0x20, 0x20},
-	{SENSOR, 0x40, 0x20, 0x20},
-	{SENSOR, 0x5a, 0xc0, 0x0a},
-	{SENSOR, 0x70, 0x7b, 0x0a},
-	{SENSOR, 0x71, 0xff, 0x00},
-	{SENSOR, 0x72, 0x19, 0x0e},
-	{SENSOR, 0x73, 0x18, 0x0f},
-	{SENSOR, 0x74, 0x57, 0x32},
-	{SENSOR, 0x75, 0x56, 0x34},
-	{SENSOR, 0x76, 0x73, 0x35},
-	{SENSOR, 0x77, 0x30, 0x12},
-	{SENSOR, 0x78, 0x79, 0x02},
-	{SENSOR, 0x79, 0x75, 0x06},
-	{SENSOR, 0x7a, 0x77, 0x0a},
-	{SENSOR, 0x7b, 0x78, 0x09},
-	{SENSOR, 0x7c, 0x7d, 0x06},
-	{SENSOR, 0x7d, 0x31, 0x10},
-	{SENSOR, 0x7e, 0x00, 0x7e},
-	{SENSOR, 0x80, 0x59, 0x04},
-	{SENSOR, 0x81, 0x59, 0x04},
-	{SENSOR, 0x82, 0x57, 0x0a},
-	{SENSOR, 0x83, 0x58, 0x0b},
-	{SENSOR, 0x84, 0x47, 0x0c},
-	{SENSOR, 0x85, 0x48, 0x0e},
-	{SENSOR, 0x86, 0x5b, 0x02},
-	{SENSOR, 0x87, 0x00, 0x5c},
-	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
-	{SENSOR, 0x60, 0x00, 0x80},
-	{SENSOR, 0x61, 0x00, 0x00},
-	{SENSOR, 0x62, 0x00, 0x00},
-	{SENSOR, 0x63, 0x00, 0x00},
-	{SENSOR, 0x64, 0x00, 0x00},
-
-	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
-	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
-	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
-	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
-	{SENSOR, 0x30, 0x04, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-	{SENSOR, 0xcd, 0x00, 0x0e},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
-	{SENSOR, 0xd0, 0x00, 0x40},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
-	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{SENSOR, 0x33, 0x03, 0x49},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
-	{SENSOR, 0x33, 0x03, 0x49},
-	{SENSOR, 0x34, 0xc0, 0x19},
-	{SENSOR, 0x3f, 0x20, 0x20},
-	{SENSOR, 0x40, 0x20, 0x20},
-	{SENSOR, 0x5a, 0xc0, 0x0a},
-	{SENSOR, 0x70, 0x7b, 0x0a},
-	{SENSOR, 0x71, 0xff, 0x00},
-	{SENSOR, 0x72, 0x19, 0x0e},
-	{SENSOR, 0x73, 0x18, 0x0f},
-	{SENSOR, 0x74, 0x57, 0x32},
-	{SENSOR, 0x75, 0x56, 0x34},
-	{SENSOR, 0x76, 0x73, 0x35},
-	{SENSOR, 0x77, 0x30, 0x12},
-	{SENSOR, 0x78, 0x79, 0x02},
-	{SENSOR, 0x79, 0x75, 0x06},
-	{SENSOR, 0x7a, 0x77, 0x0a},
-	{SENSOR, 0x7b, 0x78, 0x09},
-	{SENSOR, 0x7c, 0x7d, 0x06},
-	{SENSOR, 0x7d, 0x31, 0x10},
-	{SENSOR, 0x7e, 0x00, 0x7e},
-	{SENSOR, 0x80, 0x59, 0x04},
-	{SENSOR, 0x81, 0x59, 0x04},
-	{SENSOR, 0x82, 0x57, 0x0a},
-	{SENSOR, 0x83, 0x58, 0x0b},
-	{SENSOR, 0x84, 0x47, 0x0c},
-	{SENSOR, 0x85, 0x48, 0x0e},
-	{SENSOR, 0x86, 0x5b, 0x02},
-	{SENSOR, 0x87, 0x00, 0x5c},
-	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
-	{SENSOR, 0x60, 0x00, 0x80},
-	{SENSOR, 0x61, 0x00, 0x00},
-	{SENSOR, 0x62, 0x00, 0x00},
-	{SENSOR, 0x63, 0x00, 0x00},
-	{SENSOR, 0x64, 0x00, 0x00},
-
-	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
-	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
-	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
-	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
-	{SENSOR, 0x30, 0x04, 0x00},
-
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 
@@ -348,27 +173,8 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
@@ -380,70 +186,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-	{SENSOR, 0xcd, 0x00, 0x0e},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
-	{SENSOR, 0xd0, 0x00, 0x40},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
-	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{SENSOR, 0x33, 0x03, 0x49},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-
-	{SENSOR, 0x33, 0x03, 0x49},
-	{SENSOR, 0x34, 0xc0, 0x19},
-	{SENSOR, 0x3f, 0x20, 0x20},
-	{SENSOR, 0x40, 0x20, 0x20},
-	{SENSOR, 0x5a, 0xc0, 0x0a},
-	{SENSOR, 0x70, 0x7b, 0x0a},
-	{SENSOR, 0x71, 0xff, 0x00},
-	{SENSOR, 0x72, 0x19, 0x0e},
-	{SENSOR, 0x73, 0x18, 0x0f},
-	{SENSOR, 0x74, 0x57, 0x32},
-	{SENSOR, 0x75, 0x56, 0x34},
-	{SENSOR, 0x76, 0x73, 0x35},
-	{SENSOR, 0x77, 0x30, 0x12},
-	{SENSOR, 0x78, 0x79, 0x02},
-	{SENSOR, 0x79, 0x75, 0x06},
-	{SENSOR, 0x7a, 0x77, 0x0a},
-	{SENSOR, 0x7b, 0x78, 0x09},
-	{SENSOR, 0x7c, 0x7d, 0x06},
-	{SENSOR, 0x7d, 0x31, 0x10},
-	{SENSOR, 0x7e, 0x00, 0x7e},
-	{SENSOR, 0x80, 0x59, 0x04},
-	{SENSOR, 0x81, 0x59, 0x04},
-	{SENSOR, 0x82, 0x57, 0x0a},
-	{SENSOR, 0x83, 0x58, 0x0b},
-	{SENSOR, 0x84, 0x47, 0x0c},
-	{SENSOR, 0x85, 0x48, 0x0e},
-	{SENSOR, 0x86, 0x5b, 0x02},
-	{SENSOR, 0x87, 0x00, 0x5c},
-	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
-	{SENSOR, 0x60, 0x00, 0x80},
-	{SENSOR, 0x61, 0x00, 0x00},
-	{SENSOR, 0x62, 0x00, 0x00},
-	{SENSOR, 0x63, 0x00, 0x00},
-	{SENSOR, 0x64, 0x00, 0x00},
-
-	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
-	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
-	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
-	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
-	{SENSOR, 0x30, 0x04, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
@@ -472,24 +214,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
@@ -508,81 +232,10 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, 0xcd, 0x00, 0x0e},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, 0xd0, 0x00, 0x40},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
-	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, 0x33, 0x03, 0x49},
 	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 
-	{SENSOR, 0x33, 0x03, 0x49},
-	{SENSOR, 0x34, 0xc0, 0x19},
-	{SENSOR, 0x3f, 0x20, 0x20},
-	{SENSOR, 0x40, 0x20, 0x20},
-	{SENSOR, 0x5a, 0xc0, 0x0a},
-	{SENSOR, 0x70, 0x7b, 0x0a},
-	{SENSOR, 0x71, 0xff, 0x00},
-	{SENSOR, 0x72, 0x19, 0x0e},
-	{SENSOR, 0x73, 0x18, 0x0f},
-	{SENSOR, 0x74, 0x57, 0x32},
-	{SENSOR, 0x75, 0x56, 0x34},
-	{SENSOR, 0x76, 0x73, 0x35},
-	{SENSOR, 0x77, 0x30, 0x12},
-	{SENSOR, 0x78, 0x79, 0x02},
-	{SENSOR, 0x79, 0x75, 0x06},
-	{SENSOR, 0x7a, 0x77, 0x0a},
-	{SENSOR, 0x7b, 0x78, 0x09},
-	{SENSOR, 0x7c, 0x7d, 0x06},
-	{SENSOR, 0x7d, 0x31, 0x10},
-	{SENSOR, 0x7e, 0x00, 0x7e},
-	{SENSOR, 0x80, 0x59, 0x04},
-	{SENSOR, 0x81, 0x59, 0x04},
-	{SENSOR, 0x82, 0x57, 0x0a},
-	{SENSOR, 0x83, 0x58, 0x0b},
-	{SENSOR, 0x84, 0x47, 0x0c},
-	{SENSOR, 0x85, 0x48, 0x0e},
-	{SENSOR, 0x86, 0x5b, 0x02},
-	{SENSOR, 0x87, 0x00, 0x5c},
-	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
-	{SENSOR, 0x60, 0x00, 0x80},
-	{SENSOR, 0x61, 0x00, 0x00},
-	{SENSOR, 0x62, 0x00, 0x00},
-	{SENSOR, 0x63, 0x00, 0x00},
-	{SENSOR, 0x64, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
-	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
-	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
-	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
-	{SENSOR, 0x30, 0x04, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
@@ -611,7 +264,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
@@ -680,10 +332,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, 0x33, 0x03, 0x49},
 	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
 	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
 	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-- 
cgit v1.2.3-70-g09d2


From d9a11e28c862dd1f05193659025a99712bb507e9 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 11 Jan 2009 12:46:51 -0300
Subject: V4L/DVB (11473): gspca - m5602-po1030: Release reset when init is
 done.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 5ba3f73b787..8865037296b 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -250,6 +250,14 @@ static const unsigned char init_po1030[][3] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	/*end of sequence 2 stop */
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
+	{SENSOR, PO1030_AUTOCTRL2, 0x04},
+
 };
 
 static const unsigned char start_po1030[][3] =
-- 
cgit v1.2.3-70-g09d2


From 3e5cbad030f6c12983f697ecff9fbd8f5a6bee7b Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 11 Jan 2009 12:52:10 -0300
Subject: V4L/DVB (11474): gspca - m5602-po1030: Fix sensor probing.

The po1030 read sensor are currently returning the contents of the address+1 fix the probing of the sensor to cope with this. Obviously this needs to be tracked down and fixed.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 3ecb53c701a..a45d55c530b 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -157,7 +157,7 @@ static void po1030_dump_registers(struct sd *sd);
 
 int po1030_probe(struct sd *sd)
 {
-	u8 dev_id_h = 0, dev_id_l = 0, i;
+	u8 dev_id_h = 0, i;
 	s32 *sensor_settings;
 
 	if (force_sensor) {
@@ -185,10 +185,7 @@ int po1030_probe(struct sd *sd)
 	if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
 		return -ENODEV;
 
-	if (m5602_read_sensor(sd, PO1030_DEVID_L, &dev_id_l, 1))
-		return -ENODEV;
-
-	if ((dev_id_h == 0x10) && (dev_id_l == 0x30)) {
+	if (dev_id_h == 0x30) {
 		info("Detected a po1030 sensor");
 		goto sensor_found;
 	}
-- 
cgit v1.2.3-70-g09d2


From d8a3e35150829ebc3fae2ff18eb16eefef504ef0 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 11 Jan 2009 13:00:15 -0300
Subject: V4L/DVB (11475): gspca - m5602-po1030: Lower the default blue and
 gain balance

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 8865037296b..b70879fddce 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -137,8 +137,8 @@
 
 #define PO1030_GLOBAL_GAIN_DEFAULT	0x12
 #define PO1030_EXPOSURE_DEFAULT		0x0085
-#define PO1030_BLUE_GAIN_DEFAULT 	0x40
-#define PO1030_RED_GAIN_DEFAULT 	0x40
+#define PO1030_BLUE_GAIN_DEFAULT 	0x36
+#define PO1030_RED_GAIN_DEFAULT 	0x36
 
 /*****************************************************************************/
 
-- 
cgit v1.2.3-70-g09d2


From 86c9fb5118820af4740ef1d0896fdd4f0923039f Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 11 Jan 2009 13:39:41 -0300
Subject: V4L/DVB (11476): gspca - m5602: Add some more register defines

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_bridge.h | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 8f1cea6fd3b..34515e54c1a 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -45,6 +45,15 @@
 #define M5602_XB_SEN_CLK_DIV		0x15
 #define M5602_XB_AUD_CLK_CTRL		0x16
 #define M5602_XB_AUD_CLK_DIV		0x17
+#define M5602_OB_AC_LINK_STATE		0x22
+#define M5602_OB_PCM_SLOT_INDEX		0x24
+#define M5602_OB_GPIO_SLOT_INDEX	0x25
+#define M5602_OB_ACRX_STATUS_ADDRESS_H	0x28
+#define M5602_OB_ACRX_STATUS_DATA_L	0x29
+#define M5602_OB_ACRX_STATUS_DATA_H	0x2a
+#define M5602_OB_ACTX_COMMAND_ADDRESS	0x31
+#define M5602_OB_ACRX_COMMAND_DATA_L	0x32
+#define M5602_OB_ACTX_COMMAND_DATA_H	0X33
 #define M5602_XB_DEVCTR1		0x41
 #define M5602_XB_EPSETR0		0x42
 #define M5602_XB_EPAFCTR		0x47
@@ -77,7 +86,18 @@
 #define M5602_XB_GPIO_EN_L		0x75
 #define M5602_XB_GPIO_DAT		0x76
 #define M5602_XB_GPIO_DIR		0x77
-#define M5602_XB_MISC_CTL		0x70
+#define M5602_XB_SEN_CLK_CONTROL	0x80
+#define M5602_XB_SEN_CLK_DIVISION	0x81
+#define M5602_XB_CPR_CLK_CONTROL	0x82
+#define M5602_XB_CPR_CLK_DIVISION	0x83
+#define M5602_XB_MCU_CLK_CONTROL	0x84
+#define M5602_XB_MCU_CLK_DIVISION	0x85
+#define M5602_XB_DCT_CLK_CONTROL	0x86
+#define M5602_XB_DCT_CLK_DIVISION	0x87
+#define M5602_XB_EC_CLK_CONTROL		0x88
+#define M5602_XB_EC_CLK_DIVISION	0x89
+#define M5602_XB_LBUF_CLK_CONTROL	0x8a
+#define M5602_XB_LBUF_CLK_DIVISION	0x8b
 
 #define I2C_BUSY 0x80
 
-- 
cgit v1.2.3-70-g09d2


From 926d5038072c951629bcadbe78f8e251e174cd25 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 11 Jan 2009 15:23:46 -0300
Subject: V4L/DVB (11477): gspca - m5602-po1030: Set the blue balance in the
 init not red balance twice

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index a45d55c530b..26ac619781c 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -264,7 +264,7 @@ int po1030_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = po1030_set_red_balance(&sd->gspca_dev,
+	err = po1030_set_blue_balance(&sd->gspca_dev,
 				      sensor_settings[BLUE_BALANCE_IDX]);
 	if (err < 0)
 		return err;
-- 
cgit v1.2.3-70-g09d2


From 7662dbb373380903f58190dbc514c3db3bfee956 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 12 Jan 2009 13:43:42 -0300
Subject: V4L/DVB (11478): gspca - m5602-mt9m111: Replace various magic
 constants with defines

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 60 ++++++++++++++++---------
 1 file changed, 39 insertions(+), 21 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 0ffa98c0ff6..750a3fd428d 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -37,7 +37,6 @@
 #define MT9M111_SC_VBLANK_CONTEXT_A		0x08
 #define MT9M111_SC_SHUTTER_WIDTH		0x09
 #define MT9M111_SC_ROW_SPEED			0x0a
-
 #define MT9M111_SC_EXTRA_DELAY			0x0b
 #define MT9M111_SC_SHUTTER_DELAY		0x0c
 #define MT9M111_SC_RESET			0x0d
@@ -50,9 +49,6 @@
 #define MT9M111_SC_GREEN_2_GAIN			0x2e
 #define MT9M111_SC_GLOBAL_GAIN			0x2f
 
-#define MT9M111_RMB_MIRROR_ROWS			(1 << 0)
-#define MT9M111_RMB_MIRROR_COLS			(1 << 1)
-
 #define MT9M111_CONTEXT_CONTROL			0xc8
 #define MT9M111_PAGE_MAP			0xf0
 #define MT9M111_BYTEWISE_ADDRESS		0xf1
@@ -74,7 +70,24 @@
 #define MT9M111_COLORPIPE			0x01
 #define MT9M111_CAMERA_CONTROL			0x02
 
+#define MT9M111_RESET 				(1 << 0)
+#define MT9M111_RESTART				(1 << 1)
+#define MT9M111_ANALOG_STANDBY			(1 << 2)
+#define MT9M111_CHIP_ENABLE			(1 << 3)
+#define MT9M111_CHIP_DISABLE			(0 << 3)
+#define MT9M111_OUTPUT_DISABLE			(1 << 4)
+#define MT9M111_SHOW_BAD_FRAMES			(1 << 0)
+#define MT9M111_RESTART_BAD_FRAMES		(1 << 1)
+#define MT9M111_SYNCHRONIZE_CHANGES		(1 << 7)
+
+#define MT9M111_RMB_MIRROR_ROWS			(1 << 0)
+#define MT9M111_RMB_MIRROR_COLS			(1 << 1)
+
 #define MT9M111_COLOR_MATRIX_BYPASS		(1 << 4)
+#define MT9M111_SEL_CONTEXT_B			(1 << 3)
+
+#define MT9M111_TRISTATE_PIN_IN_STANDBY		(1 << 1)
+#define MT9M111_SOC_SOFT_STANDBY		(1 << 0)
 
 #define INITIAL_MAX_GAIN			64
 #define DEFAULT_GAIN 				283
@@ -112,7 +125,14 @@ static const unsigned char preinit_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
 
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
+	{SENSOR, MT9M111_SC_RESET,
+		MT9M111_RESET |
+		MT9M111_RESTART |
+		MT9M111_ANALOG_STANDBY |
+		MT9M111_CHIP_DISABLE,
+		MT9M111_SHOW_BAD_FRAMES |
+		MT9M111_RESTART_BAD_FRAMES |
+		MT9M111_SYNCHRONIZE_CHANGES},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
@@ -149,15 +169,13 @@ static const unsigned char init_mt9m111[][4] =
 
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
 	{SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
 	{SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
 	{SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
-
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
+	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
+		MT9M111_TRISTATE_PIN_IN_STANDBY |
+		MT9M111_SOC_SOFT_STANDBY},
 
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
@@ -364,23 +382,23 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, 0x85, 0x48, 0x0e},
 	{SENSOR, 0x86, 0x5b, 0x02},
 	{SENSOR, 0x87, 0x00, 0x5c},
-	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
+	{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
 	{SENSOR, 0x60, 0x00, 0x80},
 	{SENSOR, 0x61, 0x00, 0x00},
 	{SENSOR, 0x62, 0x00, 0x00},
 	{SENSOR, 0x63, 0x00, 0x00},
 	{SENSOR, 0x64, 0x00, 0x00},
 
-	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
-	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
-	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
-	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
-	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
+	{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
+	{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
+	{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
+	{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
+	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
+	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
+	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
+	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
+	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, /* 271 */
+	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
 	{SENSOR, 0x30, 0x04, 0x00},
 
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 2ed3bf306745578b0cc862a12492fb2a7a8e2adc Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 12 Jan 2009 13:50:29 -0300
Subject: V4L/DVB (11479): gspca - m5602-mt9m111: More magic constants
 replacement

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 750a3fd428d..cac902309f8 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -89,6 +89,8 @@
 #define MT9M111_TRISTATE_PIN_IN_STANDBY		(1 << 1)
 #define MT9M111_SOC_SOFT_STANDBY		(1 << 0)
 
+#define MT9M111_2D_DEFECT_CORRECTION_ENABLE	(1 << 0)
+
 #define INITIAL_MAX_GAIN			64
 #define DEFAULT_GAIN 				283
 
@@ -323,8 +325,8 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
 			MT9M111_CP_OPERATING_MODE_CTL},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
+	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, MT9M111_2D_DEFECT_CORRECTION_ENABLE},
+	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, MT9M111_2D_DEFECT_CORRECTION_ENABLE},
 	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
 	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 6822df520d0140a0adf667ba6e926d90b2ff6d6d Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 12 Jan 2009 13:56:13 -0300
Subject: V4L/DVB (11480): gspca - m5602-mt9m111: Remove lots of redundant
 sensor reads

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 84 +------------------------
 1 file changed, 2 insertions(+), 82 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index cac902309f8..d1bb9ddd62f 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -193,7 +193,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
@@ -209,81 +208,30 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
+
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
@@ -292,8 +240,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -305,21 +251,12 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
+
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
 	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
@@ -332,30 +269,13 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
 
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, 0xcd, 0x00, 0x0e},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, 0xd0, 0x00, 0x40},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
 	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
 	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 
-	{BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
-	{BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
-	{BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
-
 	{SENSOR, 0x33, 0x03, 0x49},
 	{SENSOR, 0x34, 0xc0, 0x19},
 	{SENSOR, 0x3f, 0x20, 0x20},
-- 
cgit v1.2.3-70-g09d2


From da773c9e5fd14249cda578f510dd0e20dd7358fb Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 12 Jan 2009 14:00:51 -0300
Subject: V4L/DVB (11481): gspca - m5602-mt9m111: More constant replacement

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index d1bb9ddd62f..5dd90a66afc 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -193,7 +193,9 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
+	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
+		MT9M111_TRISTATE_PIN_IN_STANDBY |
+		MT9M111_SOC_SOFT_STANDBY},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
@@ -214,7 +216,9 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
+	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
+		MT9M111_TRISTATE_PIN_IN_STANDBY |
+		MT9M111_SOC_SOFT_STANDBY},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
@@ -230,8 +234,9 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
-
+	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
+		MT9M111_TRISTATE_PIN_IN_STANDBY |
+		MT9M111_SOC_SOFT_STANDBY},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
@@ -274,8 +279,8 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
 	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
 	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 
+	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, 0x33, 0x03, 0x49},
 	{SENSOR, 0x34, 0xc0, 0x19},
 	{SENSOR, 0x3f, 0x20, 0x20},
-- 
cgit v1.2.3-70-g09d2


From 938fe53bf07b8a8315d1734302918339d798ab4f Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 12 Jan 2009 14:17:05 -0300
Subject: V4L/DVB (11482): gspca - m5602-mt9m111: Remove lots of redundant init
 code

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 95 ++-----------------------
 1 file changed, 4 insertions(+), 91 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 5dd90a66afc..d0fe02ceabb 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -162,104 +162,19 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
-	{SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
-		MT9M111_TRISTATE_PIN_IN_STANDBY |
-		MT9M111_SOC_SOFT_STANDBY},
-
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
-		MT9M111_TRISTATE_PIN_IN_STANDBY |
-		MT9M111_SOC_SOFT_STANDBY},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
-		MT9M111_TRISTATE_PIN_IN_STANDBY |
-		MT9M111_SOC_SOFT_STANDBY},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
-	{SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00,
-		MT9M111_TRISTATE_PIN_IN_STANDBY |
-		MT9M111_SOC_SOFT_STANDBY},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
 
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
 	{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
@@ -273,9 +188,9 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
-
 	{SENSOR, 0xcd, 0x00, 0x0e},
 	{SENSOR, 0xd0, 0x00, 0x40},
+
 	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
 	{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
 	{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
@@ -327,6 +242,8 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, /* 271 */
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
 	{SENSOR, 0x30, 0x04, 0x00},
+	/* Set number of blank rows chosen to 400 */
+	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
 
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -352,10 +269,6 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
-	/* Set number of blank rows chosen to 400 */
-	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From ebf58f70e853b9ffe50d6b194d3679b7dc2cac9c Mon Sep 17 00:00:00 2001
From: Theodore Kilgore <kilgota@auburn.edu>
Date: Sun, 5 Apr 2009 15:36:04 -0300
Subject: V4L/DVB (11483): gspca - mr97310a: Webcam 093a:010f added.

Signed-off-by: Theodore Kilgore <kilgota@auburn.edu>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/gspca.txt  | 1 +
 drivers/media/video/gspca/mr97310a.c | 1 +
 2 files changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 98529e03a46..e418a8fb9c6 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -209,6 +209,7 @@ sunplus		08ca:2050	Medion MD 41437
 sunplus		08ca:2060	Aiptek PocketDV5300
 tv8532		0923:010f	ICM532 cams
 mars		093a:050f	Mars-Semi Pc-Camera
+mr97310a	093a:010f	Sakar Digital no. 77379
 pac207		093a:2460	Qtec Webcam 100
 pac207		093a:2461	HP Webcam
 pac207		093a:2463	Philips SPC 220 NC
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index f9da55b20fa..30132513400 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = {
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x08ca, 0x0111)},
+	{USB_DEVICE(0x093a, 0x010f)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
-- 
cgit v1.2.3-70-g09d2


From e5db5d44432abc82b1250dd05bd0a4b011392d9d Mon Sep 17 00:00:00 2001
From: Douglas Schilling Landgraf <dougsland@redhat.com>
Date: Thu, 9 Apr 2009 18:24:34 -0300
Subject: V4L/DVB (11486): em28xx: Add EmpireTV board support

Added EmpireTV entry.
Thanks to Xwang <xwang1976@email.it> to provide data for this board.

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.em28xx |  1 +
 drivers/media/video/em28xx/em28xx-cards.c | 27 +++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx-dvb.c   |  1 +
 drivers/media/video/em28xx/em28xx.h       |  1 +
 4 files changed, 30 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 78d0a6eed57..bf58d957e0d 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -61,3 +61,4 @@
  63 -> Kaiomy TVnPC U2                          (em2860)        [eb1a:e303]
  64 -> Easy Cap Capture DC-60                   (em2860)
  65 -> IO-DATA GV-MVP/SZ                        (em2820/em2840) [04bb:0515]
+ 66 -> Empire dual TV                           (em2880)
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7c70738479d..7cb93fbbbbf 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1095,6 +1095,31 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = default_analog,
 		} },
 	},
+	[EM2880_BOARD_EMPIRE_DUAL_TV] = {
+		.name = "Empire dual TV",
+		.tuner_type = TUNER_XC2028,
+		.tuner_gpio = default_tuner_gpio,
+		.has_dvb = 1,
+		.dvb_gpio = default_digital,
+		.mts_firmware = 1,
+		.decoder = EM28XX_TVP5150,
+		.input = { {
+			.type = EM28XX_VMUX_TELEVISION,
+			.vmux = TVP5150_COMPOSITE0,
+			.amux = EM28XX_AMUX_VIDEO,
+			.gpio = default_analog,
+		}, {
+			.type = EM28XX_VMUX_COMPOSITE1,
+			.vmux = TVP5150_COMPOSITE1,
+			.amux = EM28XX_AMUX_LINE_IN,
+			.gpio = default_analog,
+		}, {
+			.type = EM28XX_VMUX_SVIDEO,
+			.vmux = TVP5150_SVIDEO,
+			.amux = EM28XX_AMUX_LINE_IN,
+			.gpio = default_analog,
+		} },
+	},
 	[EM2881_BOARD_DNT_DA2_HYBRID] = {
 		.name         = "DNT DA2 Hybrid",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -1437,6 +1462,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
 	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
+	{0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
 };
 
 /* I2C devicelist hash table for devices with generic USB IDs */
@@ -1664,6 +1690,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
 	ctl->mts = em28xx_boards[dev->model].mts_firmware;
 
 	switch (dev->model) {
+	case EM2880_BOARD_EMPIRE_DUAL_TV:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index fcd25511209..c8188dc2b4b 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -431,6 +431,7 @@ static int dvb_init(struct em28xx *dev)
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 	case EM2880_BOARD_TERRATEC_HYBRID_XS:
 	case EM2880_BOARD_KWORLD_DVB_310U:
+	case EM2880_BOARD_EMPIRE_DUAL_TV:
 		dvb->frontend = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_with_xc3028,
 					   &dev->i2c_adap);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4c4e58004f5..16f4c23f179 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -102,6 +102,7 @@
 #define EM2860_BOARD_KAIOMY_TVNPC_U2              63
 #define EM2860_BOARD_EASYCAP                      64
 #define EM2820_BOARD_IODATA_GVMVP_SZ		  65
+#define EM2880_BOARD_EMPIRE_DUAL_TV		  66
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
-- 
cgit v1.2.3-70-g09d2


From 42ef4632896b0c44f77fb5783b320cbedd38e3e3 Mon Sep 17 00:00:00 2001
From: Filipe Rosset <rosset.filipe@gmail.com>
Date: Thu, 9 Apr 2009 18:27:12 -0300
Subject: V4L/DVB (11487): em28xx: fix typo em28xx_errdev message

Fix typo usbtransfer->usb transfer on em28xx_errdev message.

Signed-off-by: Filipe Rosset <rosset.filipe@gmail.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 192b76cdd5d..7375353c04e 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -938,7 +938,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 	dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
 					      GFP_KERNEL);
 	if (!dev->isoc_ctl.transfer_buffer) {
-		em28xx_errdev("cannot allocate memory for usbtransfer\n");
+		em28xx_errdev("cannot allocate memory for usb transfer\n");
 		kfree(dev->isoc_ctl.urb);
 		return -ENOMEM;
 	}
-- 
cgit v1.2.3-70-g09d2


From e8a574052e3f05a86d7363065f6734626e34f389 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 03:46:24 -0300
Subject: V4L/DVB (11520): gspca - m5602-po1030: Remove redundant init
 sequences

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 48 ++------------------------
 1 file changed, 2 insertions(+), 46 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index b70879fddce..3ecacf0ed48 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -170,55 +170,21 @@ static const unsigned char preinit_po1030[][3] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
 	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-
-	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
-
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 
 	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00}
@@ -228,36 +194,26 @@ static const unsigned char init_po1030[][3] =
 {
 	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
 	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
-	/*sequence 1*/
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
-
 	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	/*end of sequence 1*/
 
-	/*sequence 2 stop */
 	{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	/*end of sequence 2 stop */
-
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
 
 	{SENSOR, PO1030_AUTOCTRL2, 0x04},
-
 };
 
 static const unsigned char start_po1030[][3] =
-- 
cgit v1.2.3-70-g09d2


From 9ae165779720209d4c566c8102dce415a3c7f055 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 03:57:57 -0300
Subject: V4L/DVB (11521): gspca - m5602-ov9650: Add auto exposure ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 57 ++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 8d830afcedb..89fb01c9bc8 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -36,6 +36,8 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 val);
 static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
 
 /* Vertically and horizontally flips the image if matched, needed for machines
    where the sensor is mounted upside down */
@@ -201,7 +203,22 @@ const static struct ctrl ov9650_ctrls[] = {
 		},
 		.set = ov9650_set_auto_gain,
 		.get = ov9650_get_auto_gain
+	},
+#define AUTO_EXPOSURE_IDX 8
+	{
+		{
+			.id 		= V4L2_CID_EXPOSURE_AUTO,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto exposure",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov9650_set_auto_exposure,
+		.get = ov9650_get_auto_exposure
 	}
+
 };
 
 static struct v4l2_pix_format ov9650_modes[] = {
@@ -356,13 +373,18 @@ int ov9650_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = ov9650_set_auto_exposure(&sd->gspca_dev,
+				sensor_settings[AUTO_EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
 	err = ov9650_set_auto_white_balance(&sd->gspca_dev,
 				sensor_settings[AUTO_WHITE_BALANCE_IDX]);
 	if (err < 0)
 		return err;
 
 	err = ov9650_set_auto_gain(&sd->gspca_dev,
-				    sensor_settings[AUTO_GAIN_CTRL_IDX]);
+				sensor_settings[AUTO_GAIN_CTRL_IDX]);
 	return err;
 }
 
@@ -699,6 +721,36 @@ static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_EXPOSURE_IDX];
+	PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
+	return 0;
+}
+
+static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
+				    __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
+
+	sensor_settings[AUTO_EXPOSURE_IDX] = val;
+	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
+
+	return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
+}
+
 static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 *val)
 {
@@ -755,9 +807,8 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 		return err;
 
 	i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
-	err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
 
-	return err;
+	return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
 }
 
 static void ov9650_dump_registers(struct sd *sd)
-- 
cgit v1.2.3-70-g09d2


From dd9ce84a773f9c9919a3c59291e82ec0e8803ecc Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 13:43:46 -0300
Subject: V4L/DVB (11522): gspca - m5602-po1030: Add auto exposure control

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 58 +++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 26ac619781c..e32d03a2cf9 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -34,6 +34,10 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 val);
 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 *val);
+static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
+					 __s32 val);
+static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
+					 __s32 *val);
 
 static struct v4l2_pix_format po1030_modes[] = {
 	{
@@ -150,7 +154,22 @@ const static struct ctrl po1030_ctrls[] = {
 		},
 		.set = po1030_set_auto_white_balance,
 		.get = po1030_get_auto_white_balance
-	}
+	},
+#define AUTO_EXPOSURE_IDX 7
+	{
+		{
+			.id 		= V4L2_CID_EXPOSURE_AUTO,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto exposure",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_auto_exposure,
+		.get = po1030_get_auto_exposure
+	},
+
 };
 
 static void po1030_dump_registers(struct sd *sd);
@@ -270,7 +289,12 @@ int po1030_init(struct sd *sd)
 		return err;
 
 	err = po1030_set_auto_white_balance(&sd->gspca_dev,
-				      sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+				sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = po1030_set_auto_exposure(&sd->gspca_dev,
+				sensor_settings[AUTO_EXPOSURE_IDX]);
 	return err;
 }
 
@@ -501,11 +525,41 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
 	if (err < 0)
 		return err;
 
+	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
 	i2c_data = (i2c_data & 0xfe) | (val & 0x01);
 	err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
 	return err;
 }
 
+static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
+				    __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_EXPOSURE_IDX];
+	PDEBUG(D_V4L2, "Auto exposure is %d", *val);
+	return 0;
+}
+
+static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
+				    __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	u8 i2c_data;
+	int err;
+
+	sensor_settings[AUTO_EXPOSURE_IDX] = val;
+	err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	PDEBUG(D_V4L2, "Set auto exposure to %d", val);
+	i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
+	return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
+}
+
 void po1030_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
-- 
cgit v1.2.3-70-g09d2


From b933d585baf6f6432ca5dd3f6d415ffa145e2c25 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 13:55:52 -0300
Subject: V4L/DVB (11523): gspca - m5602-po1030: Add private green balance
 control

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 54 +++++++++++++++++++++++++-
 drivers/media/video/gspca/m5602/m5602_po1030.h |  1 +
 drivers/media/video/gspca/m5602/m5602_sensor.h |  2 +
 3 files changed, 56 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index e32d03a2cf9..ee8e496090a 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -26,6 +26,8 @@ static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
 static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -169,7 +171,21 @@ const static struct ctrl po1030_ctrls[] = {
 		.set = po1030_set_auto_exposure,
 		.get = po1030_get_auto_exposure
 	},
-
+#define GREEN_BALANCE_IDX 8
+	{
+		{
+			.id 		= M5602_V4L2_CID_GREEN_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "green balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0xff,
+			.step 		= 0x1,
+			.default_value 	= PO1030_GREEN_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = po1030_set_green_balance,
+		.get = po1030_get_green_balance
+	},
 };
 
 static void po1030_dump_registers(struct sd *sd);
@@ -288,6 +304,11 @@ int po1030_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = po1030_set_green_balance(&sd->gspca_dev,
+				       sensor_settings[GREEN_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
 	err = po1030_set_auto_white_balance(&sd->gspca_dev,
 				sensor_settings[AUTO_WHITE_BALANCE_IDX]);
 	if (err < 0)
@@ -499,6 +520,37 @@ static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[GREEN_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Read green gain %d", *val);
+
+	return 0;
+}
+
+static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	u8 i2c_data;
+	int err;
+
+	sensor_settings[GREEN_BALANCE_IDX] = val;
+	i2c_data = val & 0xff;
+	PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
+
+	err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
+			   &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
+				 &i2c_data, 1);
+}
+
 static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 *val)
 {
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 3ecacf0ed48..0b2dab038a6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -139,6 +139,7 @@
 #define PO1030_EXPOSURE_DEFAULT		0x0085
 #define PO1030_BLUE_GAIN_DEFAULT 	0x36
 #define PO1030_RED_GAIN_DEFAULT 	0x36
+#define PO1030_GREEN_GAIN_DEFAULT 	0x40
 
 /*****************************************************************************/
 
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 987dcb23ec6..5b76b6b6215 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -21,6 +21,8 @@
 
 #include "m5602_bridge.h"
 
+#define M5602_V4L2_CID_GREEN_BALANCE	(V4L2_CID_PRIVATE_BASE + 0)
+
 /* Enumerates all supported sensors */
 enum sensors {
 	OV9650_SENSOR	= 1,
-- 
cgit v1.2.3-70-g09d2


From 12e4ed7d5e4a3145cb342be91423e92a24257212 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 14:10:44 -0300
Subject: V4L/DVB (11524): gspca - m5602-mt9m111: Add green balance ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 60 +++++++++++++++++++++++--
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  1 +
 2 files changed, 57 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 37a7fc82a53..c1ff4770e3a 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -28,7 +28,8 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
 					 __s32 val);
 static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
 					  __s32 *val);
-
+static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
@@ -100,7 +101,23 @@ const static struct ctrl mt9m111_ctrls[] = {
 		},
 		.set = mt9m111_set_auto_white_balance,
 		.get = mt9m111_get_auto_white_balance
-	}
+	},
+#define GREEN_BALANCE_IDX 4
+	{
+		{
+			.id 		= M5602_V4L2_CID_GREEN_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "green balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0x7ff,
+			.step 		= 0x1,
+			.default_value 	= MT9M111_GREEN_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = mt9m111_set_green_balance,
+		.get = mt9m111_get_green_balance
+	},
+
 };
 
 static void mt9m111_dump_registers(struct sd *sd);
@@ -197,9 +214,12 @@ int mt9m111_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	err = mt9m111_set_green_balance(&sd->gspca_dev,
+					 sensor_settings[GREEN_BALANCE_IDX]);
+	if (err < 0)
+		return err;
 
-	return err;
+	return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 }
 
 void mt9m111_disconnect(struct sd *sd)
@@ -364,6 +384,38 @@ static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	u8 data[2];
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[GREEN_BALANCE_IDX] = val;
+	data[0] = (val & 0xff);
+	data[1] = (val & 0xff00) >> 8;
+
+	PDEBUG(D_V4L2, "Set green balance %d", val);
+	err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
+				 data, 2);
+	if (err < 0)
+		return err;
+
+	return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
+				  data, 2);
+}
+
+static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[GREEN_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Read green balance %d", *val);
+	return 0;
+}
+
+
 static void mt9m111_dump_registers(struct sd *sd)
 {
 	u8 address, value[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index d0fe02ceabb..2d39e12d642 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -93,6 +93,7 @@
 
 #define INITIAL_MAX_GAIN			64
 #define DEFAULT_GAIN 				283
+#define MT9M111_GREEN_GAIN_DEFAULT		0x20
 
 /*****************************************************************************/
 
-- 
cgit v1.2.3-70-g09d2


From 74b123cf7ac638ede605e483cde0f534951f5266 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 14:16:03 -0300
Subject: V4L/DVB (11525): gspca - m5602-mt9m111: Add blue balance ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 48 ++++++++++++++++++++++++-
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  7 ++--
 2 files changed, 52 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index c1ff4770e3a..8bdd29c7d8f 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -30,6 +30,8 @@ static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
 					  __s32 *val);
 static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
@@ -117,7 +119,21 @@ const static struct ctrl mt9m111_ctrls[] = {
 		.set = mt9m111_set_green_balance,
 		.get = mt9m111_get_green_balance
 	},
-
+#define BLUE_BALANCE_IDX 5
+	{
+		{
+			.id 		= V4L2_CID_BLUE_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "blue balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0x7ff,
+			.step 		= 0x1,
+			.default_value 	= MT9M111_BLUE_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = mt9m111_set_blue_balance,
+		.get = mt9m111_get_blue_balance
+	},
 };
 
 static void mt9m111_dump_registers(struct sd *sd);
@@ -219,6 +235,11 @@ int mt9m111_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = mt9m111_set_blue_balance(&sd->gspca_dev,
+					 sensor_settings[BLUE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
 	return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 }
 
@@ -415,6 +436,31 @@ static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
+static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	u8 data[2];
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[BLUE_BALANCE_IDX] = val;
+	data[0] = (val & 0xff);
+	data[1] = (val & 0xff00) >> 8;
+
+	PDEBUG(D_V4L2, "Set blue balance %d", val);
+
+	return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
+				  data, 2);
+}
+
+static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[BLUE_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Read blue balance %d", *val);
+	return 0;
+}
 
 static void mt9m111_dump_registers(struct sd *sd)
 {
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 2d39e12d642..57dcb56efef 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -94,6 +94,7 @@
 #define INITIAL_MAX_GAIN			64
 #define DEFAULT_GAIN 				283
 #define MT9M111_GREEN_GAIN_DEFAULT		0x20
+#define MT9M111_BLUE_GAIN_DEFAULT		0x20
 
 /*****************************************************************************/
 
@@ -183,8 +184,10 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
 			MT9M111_CP_OPERATING_MODE_CTL},
 	{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, MT9M111_2D_DEFECT_CORRECTION_ENABLE},
-	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, MT9M111_2D_DEFECT_CORRECTION_ENABLE},
+	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
+				MT9M111_2D_DEFECT_CORRECTION_ENABLE},
+	{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
+				MT9M111_2D_DEFECT_CORRECTION_ENABLE},
 	{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
 	{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
 	{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 0746673d21ea53d4bd710b47ad67c413e9510a5a Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 14:18:53 -0300
Subject: V4L/DVB (11526): gspca - m5602-mt9m111: Add red balance ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 48 +++++++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  1 +
 2 files changed, 49 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8bdd29c7d8f..95b6e95aa08 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -32,6 +32,8 @@ static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
 static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
@@ -134,6 +136,21 @@ const static struct ctrl mt9m111_ctrls[] = {
 		.set = mt9m111_set_blue_balance,
 		.get = mt9m111_get_blue_balance
 	},
+#define RED_BALANCE_IDX 5
+	{
+		{
+			.id 		= V4L2_CID_RED_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "red balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0x7ff,
+			.step 		= 0x1,
+			.default_value 	= MT9M111_RED_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = mt9m111_set_red_balance,
+		.get = mt9m111_get_red_balance
+	},
 };
 
 static void mt9m111_dump_registers(struct sd *sd);
@@ -240,6 +257,11 @@ int mt9m111_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = mt9m111_set_red_balance(&sd->gspca_dev,
+					sensor_settings[RED_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
 	return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 }
 
@@ -462,6 +484,32 @@ static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
+static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	u8 data[2];
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[RED_BALANCE_IDX] = val;
+	data[0] = (val & 0xff);
+	data[1] = (val & 0xff00) >> 8;
+
+	PDEBUG(D_V4L2, "Set red balance %d", val);
+
+	return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
+				  data, 2);
+}
+
+static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[RED_BALANCE_IDX];
+	PDEBUG(D_V4L2, "Read red balance %d", *val);
+	return 0;
+}
+
 static void mt9m111_dump_registers(struct sd *sd)
 {
 	u8 address, value[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 57dcb56efef..217728a24da 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -95,6 +95,7 @@
 #define DEFAULT_GAIN 				283
 #define MT9M111_GREEN_GAIN_DEFAULT		0x20
 #define MT9M111_BLUE_GAIN_DEFAULT		0x20
+#define MT9M111_RED_GAIN_DEFAULT		0x20
 
 /*****************************************************************************/
 
-- 
cgit v1.2.3-70-g09d2


From a68985d46962305f537380a572903fb78dbe207c Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 15:44:03 -0300
Subject: V4L/DVB (11527): gspca - m5602-s5k4aa: Try to use proper
 read-modify-write of the vflip/hflip

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 41f6956e3af..317bc32e758 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -374,6 +374,10 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
+	err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
+	if (err < 0)
+		return err;
+
 	if (dmi_check_system(s5k4aa_vflip_dmi_table))
 		val = !val;
 
@@ -433,6 +437,10 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
+	err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
+	if (err < 0)
+		return err;
+
 	data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From 71c6e59d474ed8608b4e5aa998bec47b46c44a93 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 16:24:19 -0300
Subject: V4L/DVB (11528): gspca - m5602-s5k4aa: Consolidate the gain settings,
 adjust row start

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c |  2 +-
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h | 14 ++++----------
 2 files changed, 5 insertions(+), 11 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 317bc32e758..3a3df102637 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -111,7 +111,7 @@ const static struct ctrl s5k4aa_ctrls[] = {
 			.minimum	= 0,
 			.maximum	= 127,
 			.step		= 1,
-			.default_value	= 0xa0,
+			.default_value	= DEFAULT_GAIN_2,
 			.flags		= V4L2_CTRL_FLAG_SLIDER
 		},
 		.set = s5k4aa_set_gain,
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 7a8da1dc443..fbcb9c1e8c9 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -57,6 +57,8 @@
 #define S5K4AA_RM_H_FLIP		0x40
 #define S5K4AA_RM_V_FLIP		0x80
 
+#define DEFAULT_GAIN_2			0x5f
+
 /*****************************************************************************/
 
 /* Kernel module parameters */
@@ -171,9 +173,6 @@ static const unsigned char init_s5k4aa[][4] =
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, 0x0c, 0x05, 0x00},
 	{SENSOR, 0x02, 0x0e, 0x00},
-	{SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00},
-	{SENSOR, S5K4AA_GAIN_2, 0x00, 0x00},
-	{SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00},
 	{SENSOR, 0x11, 0x00, 0x00},
 	{SENSOR, 0x12, 0x00, 0x00},
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
@@ -247,9 +246,6 @@ static const unsigned char init_s5k4aa[][4] =
 	{SENSOR, 0x12, 0xc3, 0x00},
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, 0x02, 0x0e, 0x00},
-	{SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
-	{SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
-	{SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
 };
 
 static const unsigned char VGA_s5k4aa[][4] =
@@ -289,7 +285,7 @@ static const unsigned char VGA_s5k4aa[][4] =
 	{SENSOR, 0x37, 0x01, 0x00},
 	/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
 	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
+	{SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
 	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
 	{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
 	/* window_height_hi, window_height_lo : 960 = 0x03c0 */
@@ -306,9 +302,7 @@ static const unsigned char VGA_s5k4aa[][4] =
 	{SENSOR, 0x12, 0xc3, 0x00},
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, 0x02, 0x0e, 0x00},
-	{SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
-	{SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
-	{SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
+	{SENSOR, S5K4AA_GAIN_1, 0x10, 0x00},
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 3290d40206ce122058a1f1f56dfce3d2000107b3 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 13 Jan 2009 16:40:28 -0300
Subject: V4L/DVB (11529): gspca - m5602-s5k4aa: Add noise suppression ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 54 ++++++++++++++++++++++++--
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h |  1 +
 drivers/media/video/gspca/m5602/m5602_sensor.h |  1 +
 3 files changed, 52 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 3a3df102637..4ecba9b2a5a 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -26,6 +26,8 @@ static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
 
 static
     const
@@ -131,7 +133,21 @@ const static struct ctrl s5k4aa_ctrls[] = {
 		},
 		.set = s5k4aa_set_exposure,
 		.get = s5k4aa_get_exposure
-	}
+	},
+#define NOISE_SUPP_IDX 4
+	{
+		{
+			.id		= V4L2_CID_PRIVATE_BASE,
+			.type		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name		= "Noise suppression (smoothing)",
+			.minimum	= 0,
+			.maximum	= 1,
+			.step		= 1,
+			.default_value	= 1,
+		},
+			.set = s5k4aa_set_noise,
+			.get = s5k4aa_get_noise
+	},
 };
 
 static void s5k4aa_dump_registers(struct sd *sd);
@@ -304,13 +320,15 @@ int s5k4aa_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
 	if (err < 0)
 		return err;
 
-	err = s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
 
-	return err;
+	return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
 }
 
 static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -495,6 +513,34 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[NOISE_SUPP_IDX];
+	PDEBUG(D_V4L2, "Read noise %d", *val);
+	return 0;
+}
+
+static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	u8 data = S5K4AA_PAGE_MAP_2;
+	int err;
+
+	sensor_settings[NOISE_SUPP_IDX] = val;
+
+	PDEBUG(D_V4L2, "Set noise to %d", val);
+	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
+	if (err < 0)
+		return err;
+
+	data = val & 0x01;
+	return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
+}
+
 void s5k4aa_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index fbcb9c1e8c9..8299f216c20 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -49,6 +49,7 @@
 #define S5K4AA_EXPOSURE_LO		0x18
 #define S5K4AA_GAIN_1			0x1f /* (digital?) gain : 5 bits */
 #define S5K4AA_GAIN_2			0x20 /* (analogue?) gain : 7 bits */
+#define S5K4AA_NOISE_SUPP		0x37
 
 #define S5K4AA_RM_ROW_SKIP_4X		0x08
 #define S5K4AA_RM_ROW_SKIP_2X		0x04
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 5b76b6b6215..c3a72117b39 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -22,6 +22,7 @@
 #include "m5602_bridge.h"
 
 #define M5602_V4L2_CID_GREEN_BALANCE	(V4L2_CID_PRIVATE_BASE + 0)
+#define M5602_V4L2_CID_NOISE_SUPPRESION	(V4L2_CID_PRIVATE_BASE + 1)
 
 /* Enumerates all supported sensors */
 enum sensors {
-- 
cgit v1.2.3-70-g09d2


From 7ee4629092aa2982a3fbb9cfb3691637b55b4a40 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Wed, 14 Jan 2009 03:37:03 -0300
Subject: V4L/DVB (11530): gspca - m5602-s5k4aa: Add brightness v4l2 ctrl

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 54 +++++++++++++++++++++++++-
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h |  8 ++--
 2 files changed, 56 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 4ecba9b2a5a..404439fa4bb 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -28,6 +28,8 @@ static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
 static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
+static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
 
 static
     const
@@ -113,7 +115,7 @@ const static struct ctrl s5k4aa_ctrls[] = {
 			.minimum	= 0,
 			.maximum	= 127,
 			.step		= 1,
-			.default_value	= DEFAULT_GAIN_2,
+			.default_value	= S5K4AA_DEFAULT_GAIN,
 			.flags		= V4L2_CTRL_FLAG_SLIDER
 		},
 		.set = s5k4aa_set_gain,
@@ -148,6 +150,21 @@ const static struct ctrl s5k4aa_ctrls[] = {
 			.set = s5k4aa_set_noise,
 			.get = s5k4aa_get_noise
 	},
+#define BRIGHTNESS_IDX 5
+	{
+		{
+			.id		= V4L2_CID_BRIGHTNESS,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Brightness",
+			.minimum	= 0,
+			.maximum	= 0x1f,
+			.step		= 1,
+			.default_value	= S5K4AA_DEFAULT_BRIGHTNESS,
+		},
+			.set = s5k4aa_set_brightness,
+			.get = s5k4aa_get_brightness
+	},
+
 };
 
 static void s5k4aa_dump_registers(struct sd *sd);
@@ -320,6 +337,11 @@ int s5k4aa_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = s5k4aa_set_brightness(&sd->gspca_dev,
+				     sensor_settings[BRIGHTNESS_IDX]);
+	if (err < 0)
+		return err;
+
 	err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
 	if (err < 0)
 		return err;
@@ -508,11 +530,39 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 		return err;
 
 	data = val & 0xff;
-	err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
+	err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
 
 	return err;
 }
 
+static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[BRIGHTNESS_IDX];
+	PDEBUG(D_V4L2, "Read brightness %d", *val);
+	return 0;
+}
+
+static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	u8 data = S5K4AA_PAGE_MAP_2;
+	int err;
+
+	sensor_settings[BRIGHTNESS_IDX] = val;
+
+	PDEBUG(D_V4L2, "Set brightness to %d", val);
+	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
+	if (err < 0)
+		return err;
+
+	data = val & 0xff;
+	return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
+}
+
 static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 8299f216c20..2349174ad66 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -47,8 +47,8 @@
 #define S5K4AA_H_BLANK_LO__		0x1e
 #define S5K4AA_EXPOSURE_HI		0x17
 #define S5K4AA_EXPOSURE_LO		0x18
-#define S5K4AA_GAIN_1			0x1f /* (digital?) gain : 5 bits */
-#define S5K4AA_GAIN_2			0x20 /* (analogue?) gain : 7 bits */
+#define S5K4AA_BRIGHTNESS		0x1f /* (digital?) gain : 5 bits */
+#define S5K4AA_GAIN			0x20 /* (analogue?) gain : 7 bits */
 #define S5K4AA_NOISE_SUPP		0x37
 
 #define S5K4AA_RM_ROW_SKIP_4X		0x08
@@ -58,7 +58,8 @@
 #define S5K4AA_RM_H_FLIP		0x40
 #define S5K4AA_RM_V_FLIP		0x80
 
-#define DEFAULT_GAIN_2			0x5f
+#define S5K4AA_DEFAULT_GAIN		0x5f
+#define S5K4AA_DEFAULT_BRIGHTNESS	0x10
 
 /*****************************************************************************/
 
@@ -303,7 +304,6 @@ static const unsigned char VGA_s5k4aa[][4] =
 	{SENSOR, 0x12, 0xc3, 0x00},
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, 0x02, 0x0e, 0x00},
-	{SENSOR, S5K4AA_GAIN_1, 0x10, 0x00},
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 825f31b05bd6e92da5ef9f3ca21c5b36021f7e6e Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 15 Jan 2009 03:40:01 -0300
Subject: V4L/DVB (11531): gspca - m5602-po1030: Clean up some comments

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 0b2dab038a6..98ef9d05e45 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -219,7 +219,6 @@ static const unsigned char init_po1030[][3] =
 
 static const unsigned char start_po1030[][3] =
 {
-	/*sequence 4*/
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
@@ -253,7 +252,7 @@ static const unsigned char start_po1030[][3] =
 
 	{SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
 	{SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
-	/* This makes no sense, hflip and vflp is located at bit 7, 6 */
+
 	{SENSOR, PO1030_CONTROL2, 0x03},
 	{SENSOR, 0x21, 0x90},
 	{SENSOR, PO1030_YTARGET, 0x60},
@@ -269,8 +268,6 @@ static const unsigned char start_po1030[][3] =
 	{SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
 				  PO1030_AUTO_SUBSAMPLING |
 				  PO1030_FRAME_EQUAL},
-	{SENSOR, PO1030_GREEN_1_GAIN, 0x30},
-	{SENSOR, PO1030_GREEN_2_GAIN, 0x30},
 	{SENSOR, PO1030_GC0, 0x10},
 	{SENSOR, PO1030_GC1, 0x20},
 	{SENSOR, PO1030_GC2, 0x40},
@@ -279,9 +276,7 @@ static const unsigned char start_po1030[][3] =
 	{SENSOR, PO1030_GC5, 0xa0},
 	{SENSOR, PO1030_GC6, 0xc0},
 	{SENSOR, PO1030_GC7, 0xff},
-	/*end of sequence 4*/
 
-	/*sequence 5*/
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -304,8 +299,6 @@ static const unsigned char start_po1030[][3] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	/*end of sequence 5*/
-	/*sequence 6*/
 
 	/* with a very low lighted environment increase the exposure but
 	 * decrease the FPS (Frame Per Second) */
-- 
cgit v1.2.3-70-g09d2


From c86da6b33f1d268483fbdbeaec0b98779d0317c1 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 15 Jan 2009 03:52:08 -0300
Subject: V4L/DVB (11532): gspca - m5602-po1030: Move some code from the start
 vector to the init vector

This is a prepatory patch in order to support multiple resolutions for the po1030 sensor

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.h | 76 +++++++++++++-------------
 1 file changed, 37 insertions(+), 39 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 98ef9d05e45..fb0accfa77a 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -215,40 +215,6 @@ static const unsigned char init_po1030[][3] =
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
 
 	{SENSOR, PO1030_AUTOCTRL2, 0x04},
-};
-
-static const unsigned char start_po1030[][3] =
-{
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
-
-	{SENSOR, PO1030_AUTOCTRL2, 0x04},
-
-	/* Set the width to 751 */
-	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
-	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
-
-	/* Set the height to 540 */
-	{SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
-	{SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
-
-	/* Set the x window to 1 */
-	{SENSOR, PO1030_WINDOWX_H, 0x00},
-	{SENSOR, PO1030_WINDOWX_L, 0x01},
-
-	/* Set the y window to 1 */
-	{SENSOR, PO1030_WINDOWY_H, 0x00},
-	{SENSOR, PO1030_WINDOWY_L, 0x01},
-
-	/* Set the window width to 647 */
-	{SENSOR, PO1030_WINDOWWIDTH_H, 0x02},
-	{SENSOR, PO1030_WINDOWWIDTH_L, 0x87},
-
-	/* Set the window height to 483 */
-	{SENSOR, PO1030_WINDOWHEIGHT_H, 0x01},
-	{SENSOR, PO1030_WINDOWHEIGHT_L, 0xe3},
 
 	{SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
 	{SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
@@ -277,6 +243,43 @@ static const unsigned char start_po1030[][3] =
 	{SENSOR, PO1030_GC6, 0xc0},
 	{SENSOR, PO1030_GC7, 0xff},
 
+	/* Set the width to 751 */
+	{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
+	{SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
+
+	/* Set the height to 540 */
+	{SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
+	{SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
+
+	/* Set the x window to 1 */
+	{SENSOR, PO1030_WINDOWX_H, 0x00},
+	{SENSOR, PO1030_WINDOWX_L, 0x01},
+
+	/* Set the y window to 1 */
+	{SENSOR, PO1030_WINDOWY_H, 0x00},
+	{SENSOR, PO1030_WINDOWY_L, 0x01},
+
+	/* with a very low lighted environment increase the exposure but
+	 * decrease the FPS (Frame Per Second) */
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+};
+
+static const unsigned char start_po1030[][3] =
+{
+	/* Set the window width to 647 */
+	{SENSOR, PO1030_WINDOWWIDTH_H, 0x02},
+	{SENSOR, PO1030_WINDOWWIDTH_L, 0x87},
+
+	/* Set the window height to 483 */
+	{SENSOR, PO1030_WINDOWHEIGHT_H, 0x01},
+	{SENSOR, PO1030_WINDOWHEIGHT_L, 0xe3},
+
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -299,11 +302,6 @@ static const unsigned char start_po1030[][3] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-
-	/* with a very low lighted environment increase the exposure but
-	 * decrease the FPS (Frame Per Second) */
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From e807f20db4f4fbbf2b0c881f0b0dd5cf9c18b17c Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 15 Jan 2009 13:39:39 -0300
Subject: V4L/DVB (11533): gspca - m5602-po1030: Setup window per resolution

This patch for the po1030 sets the drawing window for the VGA resolution

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 29 +++++++++++++++++++++++++-
 drivers/media/video/gspca/m5602/m5602_po1030.h | 11 ----------
 2 files changed, 28 insertions(+), 12 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index ee8e496090a..af0e937451f 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -321,7 +321,34 @@ int po1030_init(struct sd *sd)
 
 int po1030_start(struct sd *sd)
 {
+	struct cam *cam = &sd->gspca_dev.cam;
 	int i, err = 0;
+	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+	u8 data;
+
+	switch (width) {
+	case 640:
+		data = ((width + 7) >> 8) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = (width + 7) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = ((height + 3) >> 8) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = (height + 3) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
+		break;
+	}
+
 	/* Synthesize the vsync/hsync setup */
 	for (i = 0; i < ARRAY_SIZE(start_po1030) && !err; i++) {
 		if (start_po1030[i][0] == BRIDGE)
@@ -330,7 +357,7 @@ int po1030_start(struct sd *sd)
 		else if (start_po1030[i][0] == SENSOR) {
 			u8 data = start_po1030[i][2];
 			err = m5602_write_sensor(sd,
-					start_po1030[i][1], &data, 1);
+				start_po1030[i][1], &data, 1);
 		}
 	}
 	return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index fb0accfa77a..b47f590ef42 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -272,17 +272,6 @@ static const unsigned char init_po1030[][3] =
 
 static const unsigned char start_po1030[][3] =
 {
-	/* Set the window width to 647 */
-	{SENSOR, PO1030_WINDOWWIDTH_H, 0x02},
-	{SENSOR, PO1030_WINDOWWIDTH_L, 0x87},
-
-	/* Set the window height to 483 */
-	{SENSOR, PO1030_WINDOWHEIGHT_H, 0x01},
-	{SENSOR, PO1030_WINDOWHEIGHT_L, 0xe3},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
 	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
 	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-- 
cgit v1.2.3-70-g09d2


From 9536a57e7783c627b2bb83f78a99f5c6dcf5d505 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 15 Jan 2009 14:05:35 -0300
Subject: V4L/DVB (11534): gspca - m5602-po1030: Synthesize the hsync/vsync
 setup

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 59 ++++++++++++++++++++------
 drivers/media/video/gspca/m5602/m5602_po1030.h | 23 ----------
 2 files changed, 47 insertions(+), 35 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index af0e937451f..d75b27221a5 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -50,7 +50,7 @@ static struct v4l2_pix_format po1030_modes[] = {
 		.sizeimage = 640 * 480,
 		.bytesperline = 640,
 		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
+		.priv = 2
 	}
 };
 
@@ -325,6 +325,7 @@ int po1030_start(struct sd *sd)
 	int i, err = 0;
 	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
 	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+	int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
 	u8 data;
 
 	switch (width) {
@@ -346,20 +347,54 @@ int po1030_start(struct sd *sd)
 
 		data = (height + 3) & 0xff;
 		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
+
+		height += 12;
+		width -= 2;
 		break;
 	}
 
-	/* Synthesize the vsync/hsync setup */
-	for (i = 0; i < ARRAY_SIZE(start_po1030) && !err; i++) {
-		if (start_po1030[i][0] == BRIDGE)
-			err = m5602_write_bridge(sd, start_po1030[i][1],
-				start_po1030[i][2]);
-		else if (start_po1030[i][0] == SENSOR) {
-			u8 data = start_po1030[i][2];
-			err = m5602_write_sensor(sd,
-				start_po1030[i][1], &data, 1);
-		}
-	}
+	err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
+				 ((ver_offs >> 8) & 0xff));
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
 	return err;
 }
 
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index b47f590ef42..8ded84d2097 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -270,27 +270,4 @@ static const unsigned char init_po1030[][3] =
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
 };
 
-static const unsigned char start_po1030[][3] =
-{
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-};
-
 #endif
-- 
cgit v1.2.3-70-g09d2


From 931a1c8dbf71d851d9d4e4dbdedc192bcc9e98c1 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Thu, 15 Jan 2009 14:18:36 -0300
Subject: V4L/DVB (11535): gspca - m5602-po1030: Add experimental QVGA support

Adds experimental support for QVGA. This is code is compile tested only.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 42 ++++++++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_po1030.h |  2 ++
 2 files changed, 44 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index d75b27221a5..9e9eed89ea6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -43,6 +43,15 @@ static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
 
 static struct v4l2_pix_format po1030_modes[] = {
 	{
+		320,
+		240,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 320 * 240,
+		.bytesperline = 320,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2
+	}, {
 		640,
 		480,
 		V4L2_PIX_FMT_SBGGR8,
@@ -329,7 +338,40 @@ int po1030_start(struct sd *sd)
 	u8 data;
 
 	switch (width) {
+	case 320:
+		data = PO1030_SUBSAMPLING;
+		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = ((width + 3) >> 8) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = (width + 3) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = ((height + 1) >> 8) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
+		if (err < 0)
+			return err;
+
+		data = (height + 1) & 0xff;
+		err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
+
+		height += 6;
+		width -= 1;
+		break;
+
 	case 640:
+		data = 0;
+		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
+		if (err < 0)
+			return err;
+
 		data = ((width + 7) >> 8) & 0xff;
 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
 		if (err < 0)
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 8ded84d2097..1ea380b2bbe 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -133,6 +133,8 @@
 
 #define PO1030_SENSOR_RESET	(1 << 5)
 
+#define PO1030_SUBSAMPLING	(1 << 6)
+
 /*****************************************************************************/
 
 #define PO1030_GLOBAL_GAIN_DEFAULT	0x12
-- 
cgit v1.2.3-70-g09d2


From 9819267009bfec221159373eafd666db37d20c78 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Fri, 16 Jan 2009 03:48:15 -0300
Subject: V4L/DVB (11536): gspca - m5602-po1030: Impove the bridge vsync/hsync
 configuration

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 9e9eed89ea6..5b9113325ec 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -367,11 +367,6 @@ int po1030_start(struct sd *sd)
 		break;
 
 	case 640:
-		data = 0;
-		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
-		if (err < 0)
-			return err;
-
 		data = ((width + 7) >> 8) & 0xff;
 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
 		if (err < 0)
@@ -394,6 +389,9 @@ int po1030_start(struct sd *sd)
 		width -= 2;
 		break;
 	}
+	err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
+	if (err < 0)
+		return err;
 
 	err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
 	if (err < 0)
@@ -403,6 +401,10 @@ int po1030_start(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
+	if (err < 0)
+		return err;
+
 	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
 				 ((ver_offs >> 8) & 0xff));
 	if (err < 0)
@@ -412,7 +414,8 @@ int po1030_start(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
 	if (err < 0)
 		return err;
 
@@ -427,6 +430,9 @@ int po1030_start(struct sd *sd)
 	for (i = 0; i < 2 && !err; i++)
 		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
 
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+
 	for (i = 0; i < 2 && !err; i++)
 		err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
 	if (err < 0)
@@ -437,6 +443,10 @@ int po1030_start(struct sd *sd)
 		return err;
 
 	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
 	return err;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 894e4087f015cef13a4ac52ea465ecd941118bad Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 18 Jan 2009 11:13:47 -0300
Subject: V4L/DVB (11537): gspca - m5602-po1030: Clear subsampling flag when
 setting VGA mode

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 5b9113325ec..840a3ca5320 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -367,6 +367,11 @@ int po1030_start(struct sd *sd)
 		break;
 
 	case 640:
+		data = 0;
+		err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
+		if (err < 0)
+			return err;
+
 		data = ((width + 7) >> 8) & 0xff;
 		err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
 		if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From 927774605ab4771c67763a7b133e8d84b524489d Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Sun, 18 Jan 2009 15:21:07 -0300
Subject: V4L/DVB (11538): gscpa - m5602-ov9650: Add defines for some magic
 constants

Replaces some magic constants with the defines. Remove a couple of bits that should be set later in the process depending on the v4l2 ctrl.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.h | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index e0ba41870a4..27fe54204c4 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -120,6 +120,10 @@
 #define OV9650_SOFT_SLEEP		(1 << 4)
 #define OV9650_OUTPUT_DRIVE_2X		(1 << 0)
 
+#define OV9650_DENOISE_ENABLE		(1 << 5)
+#define OV9650_WHITE_PIXEL_ENABLE	(1 << 1)
+#define OV9650_WHITE_PIXEL_OPTION	(1 << 0)
+
 #define OV9650_LEFT_OFFSET		0x62
 
 #define GAIN_DEFAULT			0x14
@@ -198,7 +202,7 @@ static const unsigned char init_ov9650[][3] =
 	/* Reset chip */
 	{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
 	/* One extra reset is needed in order to make the sensor behave
-	   properly when resuming from ram */
+	   properly when resuming from ram, could be a timing issue */
 	{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
 
 	/* Enable double clock */
@@ -208,8 +212,7 @@ static const unsigned char init_ov9650[][3] =
 
 	/* Set fast AGC/AEC algorithm with unlimited step size */
 	{SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
-			      OV9650_AEC_UNLIM_STEP_SIZE |
-			      OV9650_AWB_EN | OV9650_AGC_EN},
+			      OV9650_AEC_UNLIM_STEP_SIZE},
 
 	{SENSOR, OV9650_CHLF, 0x10},
 	{SENSOR, OV9650_ARBLM, 0xbf},
@@ -280,8 +283,11 @@ static const unsigned char init_ov9650[][3] =
 	{SENSOR, OV9650_VREF, 0x10},
 	{SENSOR, OV9650_ADC, 0x04},
 	{SENSOR, OV9650_HV, 0x40},
+
 	/* Enable denoise, and white-pixel erase */
-	{SENSOR, OV9650_COM22, 0x23},
+	{SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
+		 OV9650_WHITE_PIXEL_ENABLE |
+		 OV9650_WHITE_PIXEL_OPTION},
 
 	/* Enable VARIOPIXEL */
 	{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
-- 
cgit v1.2.3-70-g09d2


From b05a4ad95d0909bde1caca2ce8ec1d18fd00cfd0 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Mon, 19 Jan 2009 14:02:28 -0300
Subject: V4L/DVB (11539): gspca - m5602-ov9650: Be more strict during the
 hsync/vsync synthesis

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 89fb01c9bc8..d77ec9791bf 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -449,6 +449,14 @@ int ov9650_start(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
+	if (err < 0)
+		return err;
+
 	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
 				 (hor_offs >> 8) & 0xff);
 	if (err < 0)
@@ -468,6 +476,10 @@ int ov9650_start(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+	if (err < 0)
+		return err;
+
 	switch (width) {
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
-- 
cgit v1.2.3-70-g09d2


From 553c91d0b1a9a22bc81c07db589424af658e01cb Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 03:49:00 -0300
Subject: V4L/DVB (11540): gspca - m5602-mt9m111: Replace magic constants with
 defines

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 217728a24da..7bb8ebb860b 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -80,8 +80,12 @@
 #define MT9M111_RESTART_BAD_FRAMES		(1 << 1)
 #define MT9M111_SYNCHRONIZE_CHANGES		(1 << 7)
 
+#define MT9M111_RMB_OVER_SIZED			(1 << 0)
 #define MT9M111_RMB_MIRROR_ROWS			(1 << 0)
 #define MT9M111_RMB_MIRROR_COLS			(1 << 1)
+#define MT9M111_RMB_ROW_SKIP_2X			(1 << 2)
+#define MT9M111_RMB_COLUMN_SKIP_2X		(1 << 3)
+
 
 #define MT9M111_COLOR_MATRIX_BYPASS		(1 << 4)
 #define MT9M111_SEL_CONTEXT_B			(1 << 3)
@@ -244,7 +248,12 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
 	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
 	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, /* 271 */
+	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B,
+		MT9M111_RMB_OVER_SIZED,
+		MT9M111_RMB_MIRROR_ROWS |
+		MT9M111_RMB_MIRROR_COLS |
+		MT9M111_RMB_ROW_SKIP_2X |
+		MT9M111_RMB_COLUMN_SKIP_2X},
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
 	{SENSOR, 0x30, 0x04, 0x00},
 	/* Set number of blank rows chosen to 400 */
-- 
cgit v1.2.3-70-g09d2


From bce0d2d4aefdb258bd4a69e2de2e0d1bed0e5531 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 03:54:51 -0300
Subject: V4L/DVB (11541): gspca - m5602-mt9m111: Add a start function

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 20 ++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  6 ++++++
 2 files changed, 26 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 95b6e95aa08..edf502041b8 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -265,6 +265,26 @@ int mt9m111_init(struct sd *sd)
 	return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 }
 
+int mt9m111_start(struct sd *sd)
+{
+	int i, err = 0;
+	u8 data[2];
+
+	for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
+		if (start_mt9m111[i][0] == BRIDGE) {
+			err = m5602_write_bridge(sd,
+				start_mt9m111[i][1],
+				start_mt9m111[i][2]);
+		} else {
+			data[0] = start_mt9m111[i][2];
+			data[1] = start_mt9m111[i][3];
+			err = m5602_write_sensor(sd,
+				start_mt9m111[i][1], data, 2);
+		}
+	}
+	return err;
+}
+
 void mt9m111_disconnect(struct sd *sd)
 {
 	sd->sensor = NULL;
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 7bb8ebb860b..6598dd9c438 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -109,6 +109,7 @@ extern int dump_sensor;
 
 int mt9m111_probe(struct sd *sd);
 int mt9m111_init(struct sd *sd);
+int mt9m111_start(struct sd *sd);
 void mt9m111_disconnect(struct sd *sd);
 
 const static struct m5602_sensor mt9m111 = {
@@ -120,6 +121,7 @@ const static struct m5602_sensor mt9m111 = {
 	.probe = mt9m111_probe,
 	.init = mt9m111_init,
 	.disconnect = mt9m111_disconnect,
+	.start = mt9m111_start,
 };
 
 static const unsigned char preinit_mt9m111[][4] =
@@ -258,7 +260,10 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, 0x30, 0x04, 0x00},
 	/* Set number of blank rows chosen to 400 */
 	{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
+};
 
+static const unsigned char start_mt9m111[][4] =
+{
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -285,4 +290,5 @@ static const unsigned char init_mt9m111[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 };
 
+
 #endif
-- 
cgit v1.2.3-70-g09d2


From e7ae60f73eebd16cc13e616b096e8b1488915d96 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 04:05:19 -0300
Subject: V4L/DVB (11542): gspca - m5602-mt9m111: Synthesize the hsync/vsync
 setup

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 51 +++++++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 14 -------
 2 files changed, 51 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index edf502041b8..7986ef074c5 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -269,6 +269,10 @@ int mt9m111_start(struct sd *sd)
 {
 	int i, err = 0;
 	u8 data[2];
+	struct cam *cam = &sd->gspca_dev.cam;
+
+	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
 
 	for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
 		if (start_mt9m111[i][0] == BRIDGE) {
@@ -282,6 +286,53 @@ int mt9m111_start(struct sd *sd)
 				start_mt9m111[i][1], data, 2);
 		}
 	}
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+				 (width >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
+	if (err < 0)
+		return err;
+
+	switch (width) {
+	case 640:
+		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
+		break;
+	}
 	return err;
 }
 
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 6598dd9c438..7c8c700bab9 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -275,20 +275,6 @@ static const unsigned char start_mt9m111[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, /* 480 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 };
 
-
 #endif
-- 
cgit v1.2.3-70-g09d2


From f676bb3971b3a77c1936a8507db485af2a3f2d2a Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 04:13:34 -0300
Subject: V4L/DVB (11543): gspca - m5602-mt9m111: Setup VGA resolution

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 10 +++++++++-
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  7 -------
 2 files changed, 9 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7986ef074c5..e7399f3d10a 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -270,8 +270,9 @@ int mt9m111_start(struct sd *sd)
 	int i, err = 0;
 	u8 data[2];
 	struct cam *cam = &sd->gspca_dev.cam;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
 	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
 
 	for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
@@ -331,6 +332,13 @@ int mt9m111_start(struct sd *sd)
 	switch (width) {
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
+		data[0] = MT9M111_RMB_OVER_SIZED;
+		data[1] = MT9M111_RMB_ROW_SKIP_2X |
+			  MT9M111_RMB_COLUMN_SKIP_2X |
+			  (sensor_settings[VFLIP_IDX] << 0) |
+			  (sensor_settings[HFLIP_IDX] << 1);
+
+		err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 		break;
 	}
 	return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 7c8c700bab9..668422676aa 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -86,7 +86,6 @@
 #define MT9M111_RMB_ROW_SKIP_2X			(1 << 2)
 #define MT9M111_RMB_COLUMN_SKIP_2X		(1 << 3)
 
-
 #define MT9M111_COLOR_MATRIX_BYPASS		(1 << 4)
 #define MT9M111_SEL_CONTEXT_B			(1 << 3)
 
@@ -250,12 +249,6 @@ static const unsigned char init_mt9m111[][4] =
 	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
 	{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
 	{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
-	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_B,
-		MT9M111_RMB_OVER_SIZED,
-		MT9M111_RMB_MIRROR_ROWS |
-		MT9M111_RMB_MIRROR_COLS |
-		MT9M111_RMB_ROW_SKIP_2X |
-		MT9M111_RMB_COLUMN_SKIP_2X},
 	{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
 	{SENSOR, 0x30, 0x04, 0x00},
 	/* Set number of blank rows chosen to 400 */
-- 
cgit v1.2.3-70-g09d2


From 60ed6e4f4ec778b195efb92563021a376fa30524 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 04:16:28 -0300
Subject: V4L/DVB (11544): gspca - m5602-mt9m111: Add experimental QVGA support

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 19 +++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  2 ++
 2 files changed, 21 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index e7399f3d10a..54ccc739115 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -37,6 +37,15 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
+		320,
+		240,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 320 * 240,
+		.bytesperline = 320,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}, {
 		640,
 		480,
 		V4L2_PIX_FMT_SBGGR8,
@@ -340,6 +349,16 @@ int mt9m111_start(struct sd *sd)
 
 		err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 		break;
+
+	case 320:
+		PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
+		data[0] = MT9M111_RMB_OVER_SIZED;
+		data[1] = MT9M111_RMB_ROW_SKIP_4X |
+				MT9M111_RMB_COLUMN_SKIP_4X |
+				(sensor_settings[VFLIP_IDX] << 0) |
+				(sensor_settings[HFLIP_IDX] << 1);
+		err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
+		break;
 	}
 	return err;
 }
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 668422676aa..716aba523a1 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -85,6 +85,8 @@
 #define MT9M111_RMB_MIRROR_COLS			(1 << 1)
 #define MT9M111_RMB_ROW_SKIP_2X			(1 << 2)
 #define MT9M111_RMB_COLUMN_SKIP_2X		(1 << 3)
+#define MT9M111_RMB_ROW_SKIP_4X			(1 << 4)
+#define MT9M111_RMB_COLUMN_SKIP_4X		(1 << 5)
 
 #define MT9M111_COLOR_MATRIX_BYPASS		(1 << 4)
 #define MT9M111_SEL_CONTEXT_B			(1 << 3)
-- 
cgit v1.2.3-70-g09d2


From 039efb68626593c70b759d5ece4d87b4afc05379 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 14:32:51 -0300
Subject: V4L/DVB (11545): gspca - m5602-mt9m111: Activate vflip/hflip by
 default

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 54ccc739115..e7fec46ac45 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -67,7 +67,7 @@ const static struct ctrl mt9m111_ctrls[] = {
 			.minimum        = 0,
 			.maximum        = 1,
 			.step           = 1,
-			.default_value  = 0
+			.default_value  = 1
 		},
 		.set = mt9m111_set_vflip,
 		.get = mt9m111_get_vflip
@@ -81,7 +81,7 @@ const static struct ctrl mt9m111_ctrls[] = {
 			.minimum        = 0,
 			.maximum        = 1,
 			.step           = 1,
-			.default_value  = 0
+			.default_value  = 1
 		},
 		.set = mt9m111_set_hflip,
 		.get = mt9m111_get_hflip
-- 
cgit v1.2.3-70-g09d2


From 5a41c9f6b784a9ef7e27a8a27bdb6d541c28b076 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 14:48:16 -0300
Subject: V4L/DVB (11546): gspca - m5602-mt9m111: Endianness fixes.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index e7fec46ac45..241108c786c 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -400,7 +400,7 @@ static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	data[0] = (data[0] & 0xfe) | val;
+	data[1] = (data[1] & 0xfe) | val;
 	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 				   data, 2);
 	return err;
@@ -436,7 +436,7 @@ static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
+	data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
 	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 					data, 2);
 	return err;
@@ -466,7 +466,7 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
 		return err;
 
 	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
-	data[0] = ((data[0] & 0xfd) | ((val & 0x01) << 1));
+	data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
 
 	err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
 
@@ -514,8 +514,8 @@ static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	else
 		tmp = val;
 
-	data[1] = (tmp & 0xff00) >> 8;
-	data[0] = (tmp & 0xff);
+	data[1] = (tmp & 0xff);
+	data[0] = (tmp & 0xff00) >> 8;
 	PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
 	       data[1], data[0]);
 
@@ -533,8 +533,8 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
 	s32 *sensor_settings = sd->sensor_priv;
 
 	sensor_settings[GREEN_BALANCE_IDX] = val;
-	data[0] = (val & 0xff);
-	data[1] = (val & 0xff00) >> 8;
+	data[1] = (val & 0xff);
+	data[0] = (val & 0xff00) >> 8;
 
 	PDEBUG(D_V4L2, "Set green balance %d", val);
 	err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
@@ -563,8 +563,8 @@ static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	s32 *sensor_settings = sd->sensor_priv;
 
 	sensor_settings[BLUE_BALANCE_IDX] = val;
-	data[0] = (val & 0xff);
-	data[1] = (val & 0xff00) >> 8;
+	data[1] = (val & 0xff);
+	data[0] = (val & 0xff00) >> 8;
 
 	PDEBUG(D_V4L2, "Set blue balance %d", val);
 
@@ -589,8 +589,8 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	s32 *sensor_settings = sd->sensor_priv;
 
 	sensor_settings[RED_BALANCE_IDX] = val;
-	data[0] = (val & 0xff);
-	data[1] = (val & 0xff00) >> 8;
+	data[1] = (val & 0xff);
+	data[0] = (val & 0xff00) >> 8;
 
 	PDEBUG(D_V4L2, "Set red balance %d", val);
 
-- 
cgit v1.2.3-70-g09d2


From 00e02567950c9061b8f8d3ba46a842d4006fec8e Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 14:53:21 -0300
Subject: V4L/DVB (11547): gspca - m5602-s5k83a: Align the v4l2 ctrl
 definitions

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.c | 28 +++++++++++++-------------
 1 file changed, 14 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 8d54535724f..e1529afd494 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -94,13 +94,13 @@ const static struct ctrl s5k83a_ctrls[] = {
 #define HFLIP_IDX 3
 	{
 		{
-			.id         = V4L2_CID_HFLIP,
-			.type       = V4L2_CTRL_TYPE_BOOLEAN,
-			.name       = "horizontal flip",
-			.minimum    = 0,
-			.maximum    = 1,
-			.step       = 1,
-			.default_value  = 0
+			.id = V4L2_CID_HFLIP,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "horizontal flip",
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 0
 		},
 			.set = s5k83a_set_hflip,
 			.get = s5k83a_get_hflip
@@ -108,13 +108,13 @@ const static struct ctrl s5k83a_ctrls[] = {
 #define VFLIP_IDX 4
 	{
 		{
-		 .id         = V4L2_CID_VFLIP,
-		.type       = V4L2_CTRL_TYPE_BOOLEAN,
-		.name       = "vertical flip",
-		.minimum    = 0,
-		.maximum    = 1,
-		.step       = 1,
-		.default_value  = 0
+			.id = V4L2_CID_VFLIP,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "vertical flip",
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 0
 		},
 		.set = s5k83a_set_vflip,
 		.get = s5k83a_get_vflip
-- 
cgit v1.2.3-70-g09d2


From 2286745de7b7608b7eb0a899737a7c23ec99b872 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 14:55:53 -0300
Subject: V4L/DVB (11548): gspca - m5602-s5k83a: No need to initialize some
 registers in init

s5k83a: All v4l2 ctrls are initialized later, no need to set those registers during init.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h | 18 ------------------
 1 file changed, 18 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index e939385322a..3bda16996da 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -368,24 +368,6 @@ static const unsigned char init_s5k83a[][4] =
 	/* normal colors
 	   (this is value after boot, but after tries can be different) */
 	{SENSOR, 0x00, 0x06, 0x00},
-
-	/* set default gain */
-	{SENSOR_LONG, 0x14, 0x00, 0x20},
-	{SENSOR_LONG, 0x0d, 0x01, 0x00},
-	{SENSOR_LONG, 0x1b, S5K83A_DEFAULT_GAIN >> 3,
-		S5K83A_DEFAULT_GAIN >> 1},
-
-	/* set default brightness */
-	{SENSOR, S5K83A_BRIGHTNESS, S5K83A_DEFAULT_BRIGHTNESS, 0x00},
-
-	/* set default exposure */
-	{SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_EXPOSURE},
-
-	/* set default flip */
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
-	{SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
-	{SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 0e7e526ac7f8a02dbb7191c4ac237f4a32860176 Mon Sep 17 00:00:00 2001
From: Erik Andr?n <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 15:02:27 -0300
Subject: V4L/DVB (11549): gspca - m5602-s5k83a: Remove lots of useless init

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h | 99 +-------------------------
 1 file changed, 2 insertions(+), 97 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 3bda16996da..0697f8a99d8 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -103,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] =
 	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
 	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
-	{SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}
 };
 
 /* This could probably be considerably shortened.
@@ -120,40 +118,12 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	{SENSOR, 0x03, 0x0b, 0x00},
 	{SENSOR, 0x04, 0xf0, 0x00},
 	{SENSOR, 0x05, 0x0b, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 	{SENSOR, 0x06, 0x71, 0x00},
 	{SENSOR, 0x07, 0xe8, 0x00},
 	{SENSOR, 0x08, 0x02, 0x00},
@@ -164,32 +134,6 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x1a, 0x98, 0x00},
 	{SENSOR, 0x0f, 0x02, 0x00},
 	{SENSOR, 0x10, 0xe5, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR_LONG, 0x14, 0x00, 0x20},
-	{SENSOR_LONG, 0x0d, 0x00, 0x7d},
-	{SENSOR_LONG, 0x1b, 0x0d, 0x05},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
 
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
@@ -227,43 +171,13 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	/* some values like 0x10 give a blue-purple image */
 	{SENSOR, 0x03, 0x0b, 0x00},
 	{SENSOR, 0x04, 0xf0, 0x00},
 	{SENSOR, 0x05, 0x0b, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	/* under 80 don't work, highter depend on value */
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
-
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 	{SENSOR, 0x06, 0x71, 0x00},
 	{SENSOR, 0x07, 0xe8, 0x00},
 	{SENSOR, 0x08, 0x02, 0x00},
@@ -274,10 +188,6 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x1a, 0x98, 0x00},
 	{SENSOR, 0x0f, 0x02, 0x00},
 	{SENSOR, 0x10, 0xe5, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR_LONG, 0x14, 0x00, 0x20},
-	{SENSOR_LONG, 0x0d, 0x00, 0x7d},
-	{SENSOR_LONG, 0x1b, 0x0d, 0x05},
 
 	/* The following sequence is useless after a clean boot
 	   but is necessary after resume from suspend */
@@ -335,7 +245,7 @@ static const unsigned char init_s5k83a[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
@@ -343,12 +253,11 @@ static const unsigned char init_s5k83a[][4] =
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
 	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
 	{SENSOR, 0x06, 0x71, 0x00},
 	{SENSOR, 0x07, 0xe8, 0x00},
 	{SENSOR, 0x08, 0x02, 0x00},
@@ -358,12 +267,8 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x19, 0x00, 0x00},
 	{SENSOR, 0x1a, 0x98, 0x00},
 	{SENSOR, 0x0f, 0x02, 0x00},
-
 	{SENSOR, 0x10, 0xe5, 0x00},
 	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR_LONG, 0x14, 0x00, 0x20},
-	{SENSOR_LONG, 0x0d, 0x00, 0x7d},
-	{SENSOR_LONG, 0x1b, 0x0d, 0x05},
 
 	/* normal colors
 	   (this is value after boot, but after tries can be different) */
-- 
cgit v1.2.3-70-g09d2


From 3aeae407600af24d9505004305c6aef93ca54b21 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Tue, 7 Apr 2009 12:55:17 -0300
Subject: V4L/DVB (11564): tda7432: Delete old driver history

The history of changes does belong to git.

In general I wouldn't care too much but it happens that this specific
comment triggers a false positive in one of my scripts, so I'd rather
get rid of it.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tda7432.c | 14 --------------
 1 file changed, 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 005f8a46803..80f1cee23fa 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -20,20 +20,6 @@
  * loudness - set between 0 and 15 for varying degrees of loudness effect
  *
  * maxvol   - set maximium volume to +20db (1), default is 0db(0)
- *
- *
- *  Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db
- *  				store if muted so we can return it
- *  				change balance only if flaged to
- *  Revision: 0.6 - added tone controls
- *  Revision: 0.5 - Fixed odd balance problem
- *  Revision: 0.4 - added muting
- *  Revision: 0.3 - Fixed silly reversed volume controls.  :)
- *  Revision: 0.2 - Cleaned up #defines
- *			fixed volume control
- *          Added I2C_DRIVERID_TDA7432
- *			added loudness insmod control
- *  Revision: 0.1 - initial version
  */
 
 #include <linux/module.h>
-- 
cgit v1.2.3-70-g09d2


From 9d6e1aa55c3a7f1919e02decac09524cb7d0f33f Mon Sep 17 00:00:00 2001
From: Huang Weiyi <weiyi.huang@gmail.com>
Date: Tue, 7 Apr 2009 19:49:46 -0300
Subject: V4L/DVB: cx231xx: remove unused #include <linux/version.h>'s

Remove unused #include <linux/version.h>'s in
  drivers/media/video/cx231xx/cx231xx-avcore.c
  drivers/media/video/cx231xx/cx231xx-vbi.c

Signed-off-by: Huang Weiyi <weiyi.huang@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-avcore.c | 1 -
 drivers/media/video/cx231xx/cx231xx-vbi.c    | 1 -
 2 files changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 1be3881be99..6a9464079b4 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -29,7 +29,6 @@
 #include <linux/bitmap.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
-#include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
 
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index 94180526909..e97b8023a65 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -26,7 +26,6 @@
 #include <linux/bitmap.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
-#include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
 
-- 
cgit v1.2.3-70-g09d2


From 9086c7b994dcd6d06723bcb48a23af3e3f75e002 Mon Sep 17 00:00:00 2001
From: Márton Németh <nm127@freemail.hu>
Date: Wed, 15 Apr 2009 09:01:58 -0300
Subject: V4L/DVB (11573): uvcvideo: Prevent invormation loss with removing
 implicit casting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The uvcvideo driver supports only one input, which is input 0. For all
other input index the return value shall be EINVAL. This patch fixes the
problem when the value 0x80000000 was incorrectly casted and treated as
a zero value.

The patch was tested with v4l-test 0.10 [2] with CNF7129 webcam found on
EeePC 901.

References:
[1] V4L2 API specification, revision 0.24
    http://v4l2spec.bytesex.org/spec/r11217.htm

[2] v4l-test: Test environment for Video For Linux Two API
    http://v4l-test.sourceforge.net/

[Modified by Laurent Pinchart]

Invalid input value (u32)-1 would be accepted due to integer overflow. Make
sure the driver rejects it and returns -EINVAL.

Signed-off-by: Márton Németh <nm127@freemail.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_v4l2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2a80caa54fb..43b05a7ecdc 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -648,7 +648,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
 	case VIDIOC_S_INPUT:
 	{
-		u8 input = *(u32 *)arg + 1;
+		u32 input = *(u32 *)arg + 1;
 
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
@@ -660,7 +660,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 			break;
 		}
 
-		if (input > video->selector->selector.bNrInPins)
+		if (input == 0 || input > video->selector->selector.bNrInPins)
 			return -EINVAL;
 
 		return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
-- 
cgit v1.2.3-70-g09d2


From 2460cdac94082c7046ab595bf643338e6faed6cb Mon Sep 17 00:00:00 2001
From: Márton Németh <nm127@freemail.hu>
Date: Mon, 20 Apr 2009 14:51:49 -0300
Subject: V4L/DVB (11574): uvcvideo: fill reserved fields with zero of
 VIDIOC_QUERYMENU
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When querying menu items with VIDIOC_QUERYMENU the reserved field
is not set to zero as required by V4L2 API revision 0.24 [1].
Add this fill.

The patch was tested with v4l-test 0.11 [2] with CNF7129 webcam found
on EeePC 901.

References:
[1] V4L2 API specification, revision 0.24
    http://v4l2spec.bytesex.org/spec/r13317.htm#V4L2-QUERYMENU

[2] v4l-test: Test environment for Video For Linux Two API
    http://v4l-test.sourceforge.net/

[Modified by Laurent Pinchart]

Use u32 instead of __u32 in non-exported kernel code.

Signed-off-by: Márton Németh <nm127@freemail.hu>
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_v4l2.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 43b05a7ecdc..ad7e64ff3ad 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
 	struct uvc_menu_info *menu_info;
 	struct uvc_control_mapping *mapping;
 	struct uvc_control *ctrl;
+	u32 index = query_menu->index;
+	u32 id = query_menu->id;
 
 	ctrl = uvc_find_control(video, query_menu->id, &mapping);
 	if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
@@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
 	if (query_menu->index >= mapping->menu_count)
 		return -EINVAL;
 
+	memset(query_menu, 0, sizeof(*query_menu));
+	query_menu->id = id;
+	query_menu->index = index;
+
 	menu_info = &mapping->menu_info[query_menu->index];
 	strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
 	return 0;
-- 
cgit v1.2.3-70-g09d2


From abce21f40f1c7a52c9a126c6c00db1bd76e96b1d Mon Sep 17 00:00:00 2001
From: Dean Anderson <dean@sensoray.com>
Date: Thu, 23 Apr 2009 16:04:41 -0300
Subject: V4L/DVB (11605): patch: s2255drv: code cleanup

This patch does:
	- remove unused structure items.
	- define Response values;
	- change Driver revision printk.

Signed-off-by: Dean Anderson <dean@sensoray.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/s2255drv.c | 47 ++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 30f4698be90..90e1dbc1aa8 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -77,6 +77,8 @@
 #define MAX_CHANNELS		4
 #define S2255_MARKER_FRAME	0x2255DA4AL
 #define S2255_MARKER_RESPONSE	0x2255ACACL
+#define S2255_RESPONSE_SETMODE  0x01
+#define S2255_RESPONSE_FW       0x10
 #define S2255_USB_XFER_SIZE	(16 * 1024)
 #define MAX_CHANNELS		4
 #define MAX_PIPE_BUFFERS	1
@@ -178,9 +180,6 @@ struct s2255_bufferi {
 
 struct s2255_dmaqueue {
 	struct list_head	active;
-	/* thread for acquisition */
-	struct task_struct	*kthread;
-	int			frame;
 	struct s2255_dev	*dev;
 	int			channel;
 };
@@ -210,16 +209,11 @@ struct s2255_pipeinfo {
 	u32 max_transfer_size;
 	u32 cur_transfer_size;
 	u8 *transfer_buffer;
-	u32 transfer_flags;;
 	u32 state;
-	u32 prev_state;
-	u32 urb_size;
 	void *stream_urb;
 	void *dev;	/* back pointer to s2255_dev struct*/
 	u32 err_count;
-	u32 buf_index;
 	u32 idx;
-	u32 priority_set;
 };
 
 struct s2255_fmt; /*forward declaration */
@@ -239,8 +233,6 @@ struct s2255_dev {
 	struct list_head	s2255_devlist;
 	struct timer_list	timer;
 	struct s2255_fw	*fw_data;
-	int			board_num;
-	int			is_open;
 	struct s2255_pipeinfo	pipes[MAX_PIPE_BUFFERS];
 	struct s2255_bufferi		buffer[MAX_CHANNELS];
 	struct s2255_mode	mode[MAX_CHANNELS];
@@ -297,9 +289,10 @@ struct s2255_fh {
 	int			resources[MAX_CHANNELS];
 };
 
-#define CUR_USB_FWVER	774	/* current cypress EEPROM firmware version */
+/* current cypress EEPROM firmware version */
+#define S2255_CUR_USB_FWVER	((3 << 8) | 6)
 #define S2255_MAJOR_VERSION	1
-#define S2255_MINOR_VERSION	13
+#define S2255_MINOR_VERSION	14
 #define S2255_RELEASE		0
 #define S2255_VERSION		KERNEL_VERSION(S2255_MAJOR_VERSION, \
 					       S2255_MINOR_VERSION, \
@@ -1818,7 +1811,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
 		INIT_LIST_HEAD(&dev->vidq[i].active);
 		dev->vidq[i].dev = dev;
 		dev->vidq[i].channel = i;
-		dev->vidq[i].kthread = NULL;
 		/* register 4 video devices */
 		dev->vdev[i] = video_device_alloc();
 		memcpy(dev->vdev[i], &template, sizeof(struct video_device));
@@ -1839,7 +1831,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
 			return ret;
 		}
 	}
-	printk(KERN_INFO "Sensoray 2255 V4L driver\n");
+	printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
+	       S2255_MAJOR_VERSION,
+	       S2255_MINOR_VERSION);
 	return ret;
 }
 
@@ -1929,14 +1923,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
 				if (!(cc >= 0 && cc < MAX_CHANNELS))
 					break;
 				switch (pdword[2]) {
-				case 0x01:
+				case S2255_RESPONSE_SETMODE:
 					/* check if channel valid */
 					/* set mode ready */
 					dev->setmode_ready[cc] = 1;
 					wake_up(&dev->wait_setmode[cc]);
 					dprintk(5, "setmode ready %d\n", cc);
 					break;
-				case 0x10:
+				case S2255_RESPONSE_FW:
 
 					dev->chn_ready |= (1 << cc);
 					if ((dev->chn_ready & 0x0f) != 0x0f)
@@ -2172,10 +2166,15 @@ static int s2255_board_init(struct s2255_dev *dev)
 	/* query the firmware */
 	fw_ver = s2255_get_fx2fw(dev);
 
-	printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
-	if (fw_ver < CUR_USB_FWVER)
+	printk(KERN_INFO "2255 usb firmware version %d.%d\n",
+	       (fw_ver >> 8) & 0xff,
+	       fw_ver & 0xff);
+
+	if (fw_ver < S2255_CUR_USB_FWVER)
 		dev_err(&dev->udev->dev,
-			"usb firmware not up to date %d\n", fw_ver);
+			"usb firmware not up to date %d.%d\n",
+			(fw_ver >> 8) & 0xff,
+			fw_ver & 0xff);
 
 	for (j = 0; j < MAX_CHANNELS; j++) {
 		dev->b_acquire[j] = 0;
@@ -2283,8 +2282,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
 
 	for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
 		pipe_info->state = 1;
-		pipe_info->buf_index = (u32) i;
-		pipe_info->priority_set = 0;
+		pipe_info->err_count = 0;
 		pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!pipe_info->stream_urb) {
 			dev_err(&dev->udev->dev,
@@ -2298,7 +2296,6 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
 				  pipe_info->cur_transfer_size,
 				  read_pipe_completion, pipe_info);
 
-		pipe_info->urb_size = sizeof(pipe_info->stream_urb);
 		dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
 		retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
 		if (retval) {
@@ -2403,8 +2400,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
 			if (pipe_info->state == 0)
 				continue;
 			pipe_info->state = 0;
-			pipe_info->prev_state = 1;
-
 		}
 	}
 
@@ -2542,7 +2537,9 @@ static int s2255_probe(struct usb_interface *interface,
 	s2255_probe_v4l(dev);
 	usb_reset_device(dev->udev);
 	/* load 2255 board specific */
-	s2255_board_init(dev);
+	retval = s2255_board_init(dev);
+	if (retval)
+		goto error;
 
 	dprintk(4, "before probe done %p\n", dev);
 	spin_lock_init(&dev->slock);
-- 
cgit v1.2.3-70-g09d2


From df0dbbe24053b7c669f63341d3d3f090560c3217 Mon Sep 17 00:00:00 2001
From: Andy Shevchenko <andy@smile.org.ua>
Date: Wed, 8 Apr 2009 14:01:19 -0300
Subject: V4L/DVB (11442): saa7134: BZ#7524: Add AVerTV Studio 507UA support

[mchehab@redhat.com: Fix merge conflicts and CodingStyle issues]
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.saa7134  |  1 +
 drivers/media/video/saa7134/saa7134-cards.c | 44 +++++++++++++++++++++++++++++
 drivers/media/video/saa7134/saa7134-input.c |  1 +
 drivers/media/video/saa7134/saa7134.h       |  1 +
 4 files changed, 47 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 6dacf282525..8a15e2b837f 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -155,3 +155,4 @@
 154 -> Avermedia AVerTV GO 007 FM Plus          [1461:f31d]
 155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
 156 -> Hauppauge WinTV-HVR1110r3                [0070:6707,0070:6709,0070:670a]
+157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index fdb19449d26..eab4782861f 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4753,6 +4753,44 @@ struct saa7134_board saa7134_boards[] = {
 			.gpio = 0x01,
 		},
 	},
+	[SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
+		/* Andy Shevchenko <andy@smile.org.ua> */
+		.name           = "Avermedia AVerTV Studio 507UA",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x03,
+		.inputs         = { {
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x00,
+		}, {
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x00,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+			.gpio = 0x00,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+			.gpio = 0x01,
+		},
+		.mute  = {
+			.name = name_mute,
+			.amux = LINE1,
+			.gpio = 0x00,
+		},
+	},
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5440,6 +5478,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subdevice    = 0x9715,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xa11b,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
+	}, {
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x1043,
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 8a106d36e72..25217ae6606 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -447,6 +447,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
 	case SAA7134_BOARD_AVERMEDIA_M102:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 0cbaf90d487..8d251db3a71 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -280,6 +280,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
 #define SAA7134_BOARD_HAUPPAUGE_HVR1120     155
 #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
+#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
-- 
cgit v1.2.3-70-g09d2


From d46de9d2364cad55caddc04632707f5739b4cd87 Mon Sep 17 00:00:00 2001
From: Oldřich Jedlička <oldium.pro@seznam.cz>
Date: Tue, 14 Apr 2009 15:47:17 -0300
Subject: V4L/DVB (11567): saa7134: Added support for AVerMedia Cardbus Plus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Here comes the full support for AVerMedia Cardbus Plus (E501R) - including
remote control. TV, Composite and FM radio tested, I don't have S-Video to
test. I've figured out that the radio works only with xtal frequency 13MHz.

[mchehab@redhat.com: CodingStyle fixes]
Signed-off-by: Oldřich Jedlička <oldium.pro@seznam.cz>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.saa7134  |  1 +
 drivers/media/video/saa7134/saa7134-cards.c | 51 +++++++++++++++++++++++++++++
 drivers/media/video/saa7134/saa7134.h       |  1 +
 3 files changed, 53 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 8a15e2b837f..fb3098d56d8 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -156,3 +156,4 @@
 155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
 156 -> Hauppauge WinTV-HVR1110r3                [0070:6707,0070:6709,0070:670a]
 157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
+158 -> AVerMedia Cardbus TV/Radio (E501R)       [1461:b7e9]
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index eab4782861f..e1c455827b8 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1669,6 +1669,39 @@ struct saa7134_board saa7134_boards[] = {
 			.amux = LINE1,
 		},
 	},
+	[SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = {
+		/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+		.name           = "AVerMedia Cardbus TV/Radio (E501R)",
+		.audio_clock    = 0x187de7,
+		.tuner_type     = TUNER_ALPS_TSBE5_PAL,
+		.radio_type     = TUNER_TEA5767,
+		.tuner_addr	= 0x61,
+		.radio_addr	= 0x60,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x08000000,
+		.inputs         = { {
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x08000000,
+		}, {
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x08000000,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+			.gpio = 0x08000000,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+			.gpio = 0x00000000,
+		},
+	},
 	[SAA7134_BOARD_CINERGY400_CARDBUS] = {
 		.name           = "Terratec Cinergy 400 mobile",
 		.audio_clock    = 0x187de7,
@@ -5065,6 +5098,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subdevice    = 0xd6ee,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_CARDBUS,
 	},{
+		/* AVerMedia CardBus */
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xb7e9,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
+	}, {
 		/* TransGear 3000TV */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -6240,6 +6280,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
 		msleep(10);
 		break;
+	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+		/* power-down tuner chip */
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x08400000, 0x08400000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0);
+		msleep(10);
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x08400000, 0x08400000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000);
+		msleep(10);
+		dev->has_remote = SAA7134_REMOTE_I2C;
+		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
 		saa7134_set_gpio(dev, 23, 0);
 		msleep(10);
@@ -6679,6 +6729,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
 
 	switch (dev->board) {
 	case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
+	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
 	{
 		struct v4l2_priv_tun_config tea5767_cfg;
 		struct tea5767_ctrl ctl;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 8d251db3a71..a8ac046b6eb 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -281,6 +281,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_HAUPPAUGE_HVR1120     155
 #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
+#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
-- 
cgit v1.2.3-70-g09d2


From 84d728c3df9931d1937e4a76324838ce065c521e Mon Sep 17 00:00:00 2001
From: Dmitri Belimov <d.belimov@gmail.com>
Date: Thu, 23 Apr 2009 02:32:49 -0300
Subject: V4L/DVB (11604): saa7134: split Behold`s card entries to properly
 identify the model

Split Beholdr`s cards to correct models.

Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.saa7134  |  16 +-
 drivers/media/video/saa7134/saa7134-cards.c | 341 ++++++++++++++++++++++++++--
 drivers/media/video/saa7134/saa7134-input.c |  12 +-
 drivers/media/video/saa7134/saa7134.h       |  12 +-
 4 files changed, 352 insertions(+), 29 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index fb3098d56d8..112ff4f4fd9 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -124,10 +124,10 @@
 123 -> Beholder BeholdTV 407                    [0000:4070]
 124 -> Beholder BeholdTV 407 FM                 [0000:4071]
 125 -> Beholder BeholdTV 409                    [0000:4090]
-126 -> Beholder BeholdTV 505 FM/RDS             [0000:5051,0000:505B,5ace:5050]
-127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
+126 -> Beholder BeholdTV 505 FM                 [5ace:5050]
+127 -> Beholder BeholdTV 507 FM / BeholdTV 509 FM [5ace:5070,5ace:5090]
 128 -> Beholder BeholdTV Columbus TVFM          [0000:5201]
-129 -> Beholder BeholdTV 607 / BeholdTV 609     [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
+129 -> Beholder BeholdTV 607 FM                 [5ace:6070]
 130 -> Beholder BeholdTV M6                     [5ace:6190]
 131 -> Twinhan Hybrid DTV-DVB 3056 PCI          [1822:0022]
 132 -> Genius TVGO AM11MCE
@@ -157,3 +157,13 @@
 156 -> Hauppauge WinTV-HVR1110r3                [0070:6707,0070:6709,0070:670a]
 157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
 158 -> AVerMedia Cardbus TV/Radio (E501R)       [1461:b7e9]
+159 -> Beholder BeholdTV 505 RDS                [0000:505B]
+160 -> Beholder BeholdTV 507 RDS                [0000:5071]
+161 -> Beholder BeholdTV 507 RDS                [0000:507B]
+162 -> Beholder BeholdTV 607 FM                 [5ace:6071]
+163 -> Beholder BeholdTV 609 FM                 [5ace:6090]
+164 -> Beholder BeholdTV 609 FM                 [5ace:6091]
+165 -> Beholder BeholdTV 607 RDS                [5ace:6072]
+166 -> Beholder BeholdTV 607 RDS                [5ace:6073]
+167 -> Beholder BeholdTV 609 RDS                [5ace:6092]
+168 -> Beholder BeholdTV 609 RDS                [5ace:6093]
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index e1c455827b8..40e620284f5 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4039,7 +4039,7 @@ struct saa7134_board saa7134_boards[] = {
 	[SAA7134_BOARD_BEHOLD_505FM] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
-		.name           = "Beholder BeholdTV 505 FM/RDS",
+		.name           = "Beholder BeholdTV 505 FM",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
 		.radio_type     = UNSET,
@@ -4047,6 +4047,40 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = LINE2,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_505RDS] = {
+		/*       Beholder Intl. Ltd. 2008      */
+		/*Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 505 RDS",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x00008000,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 3,
@@ -4073,7 +4107,7 @@ struct saa7134_board saa7134_boards[] = {
 	[SAA7134_BOARD_BEHOLD_507_9FM] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
-		.name           = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM",
+		.name           = "Beholder BeholdTV 507 FM / BeholdTV 509 FM",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
 		.radio_type     = UNSET,
@@ -4100,6 +4134,66 @@ struct saa7134_board saa7134_boards[] = {
 			.amux = LINE2,
 		},
 	},
+	[SAA7134_BOARD_BEHOLD_507RDS_MK5] = {
+		/*       Beholder Intl. Ltd. 2008      */
+		/*Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 507 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x00008000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+			.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_507RDS_MK3] = {
+		/*       Beholder Intl. Ltd. 2008      */
+		/*Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 507 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0x00008000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+			.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
 	[SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
@@ -4134,15 +4228,211 @@ struct saa7134_board saa7134_boards[] = {
 			.gpio = 0x000A8000,
 		},
 	},
-	[SAA7134_BOARD_BEHOLD_607_9FM] = {
+	[SAA7134_BOARD_BEHOLD_607FM_MK3] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 607 FM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_609FM_MK3] = {
 		/* Andrey Melnikoff <temnota@kmv.ru> */
-		.name           = "Beholder BeholdTV 607 / BeholdTV 609",
+		.name           = "Beholder BeholdTV 609 FM",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_607FM_MK5] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 607 FM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_609FM_MK5] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 609 FM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_607RDS_MK3] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 607 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_609RDS_MK3] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 609 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_607RDS_MK5] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 607 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 1,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_609RDS_MK5] = {
+		/* Andrey Melnikoff <temnota@kmv.ru> */
+		.name           = "Beholder BeholdTV 609 RDS",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 3,
@@ -4242,8 +4532,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
 		.name           = "Beholder BeholdTV M6 Extra",
 		.audio_clock    = 0x00187de7,
-		/* FIXME: Must be PHILIPS_FM1216ME_MK5*/
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
@@ -5727,18 +6016,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subvendor    = 0x0000,
 		.subdevice    = 0x4090,
 		.driver_data  = SAA7134_BOARD_BEHOLD_409,
-	},{
-		.vendor       = PCI_VENDOR_ID_PHILIPS,
-		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-		.subvendor    = 0x0000,
-		.subdevice    = 0x5051,
-		.driver_data  = SAA7134_BOARD_BEHOLD_505FM,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
 		.subvendor    = 0x0000,
 		.subdevice    = 0x505B,
-		.driver_data  = SAA7134_BOARD_BEHOLD_505FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_505RDS,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -5750,13 +6033,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x0000,
 		.subdevice    = 0x5071,
-		.driver_data  = SAA7134_BOARD_BEHOLD_507_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_507RDS_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x0000,
 		.subdevice    = 0x507B,
-		.driver_data  = SAA7134_BOARD_BEHOLD_507_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_507RDS_MK5,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5780,49 +6063,49 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6070,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_607FM_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6071,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_607FM_MK5,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6072,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_607RDS_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6073,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_607RDS_MK5,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6090,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_609FM_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6091,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_609FM_MK5,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6092,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_609RDS_MK3,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5ace,
 		.subdevice    = 0x6093,
-		.driver_data  = SAA7134_BOARD_BEHOLD_607_9FM,
+		.driver_data  = SAA7134_BOARD_BEHOLD_609RDS_MK5,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -6226,7 +6509,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_407FM:
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_505FM:
+	case SAA7134_BOARD_BEHOLD_505RDS:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
+	case SAA7134_BOARD_BEHOLD_507RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_507RDS_MK5:
 	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
 	case SAA7134_BOARD_REAL_ANGEL_220:
 	case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
@@ -6347,7 +6633,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-	case SAA7134_BOARD_BEHOLD_607_9FM:
+	case SAA7134_BOARD_BEHOLD_607FM_MK3:
+	case SAA7134_BOARD_BEHOLD_607FM_MK5:
+	case SAA7134_BOARD_BEHOLD_609FM_MK3:
+	case SAA7134_BOARD_BEHOLD_609FM_MK5:
+	case SAA7134_BOARD_BEHOLD_607RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_607RDS_MK5:
+	case SAA7134_BOARD_BEHOLD_609RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_609RDS_MK5:
 	case SAA7134_BOARD_BEHOLD_M6:
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 25217ae6606..45063751726 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -507,7 +507,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_407FM:
 	case SAA7134_BOARD_BEHOLD_409:
 	case SAA7134_BOARD_BEHOLD_505FM:
+	case SAA7134_BOARD_BEHOLD_505RDS:
 	case SAA7134_BOARD_BEHOLD_507_9FM:
+	case SAA7134_BOARD_BEHOLD_507RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_507RDS_MK5:
 		ir_codes     = ir_codes_manli;
 		mask_keycode = 0x003f00;
 		mask_keyup   = 0x004000;
@@ -714,7 +717,14 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 		ir->get_key   = get_key_hvr1110;
 		ir->ir_codes  = ir_codes_hauppauge_new;
 		break;
-	case SAA7134_BOARD_BEHOLD_607_9FM:
+	case SAA7134_BOARD_BEHOLD_607FM_MK3:
+	case SAA7134_BOARD_BEHOLD_607FM_MK5:
+	case SAA7134_BOARD_BEHOLD_609FM_MK3:
+	case SAA7134_BOARD_BEHOLD_609FM_MK5:
+	case SAA7134_BOARD_BEHOLD_607RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_607RDS_MK5:
+	case SAA7134_BOARD_BEHOLD_609RDS_MK3:
+	case SAA7134_BOARD_BEHOLD_609RDS_MK5:
 	case SAA7134_BOARD_BEHOLD_M6:
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index a8ac046b6eb..1d190e5e1ac 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -252,7 +252,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_BEHOLD_505FM	126
 #define SAA7134_BOARD_BEHOLD_507_9FM	127
 #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
-#define SAA7134_BOARD_BEHOLD_607_9FM	129
+#define SAA7134_BOARD_BEHOLD_607FM_MK3	129
 #define SAA7134_BOARD_BEHOLD_M6		130
 #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
 #define SAA7134_BOARD_GENIUS_TVGO_A11MCE   132
@@ -282,6 +282,16 @@ struct saa7134_format {
 #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
 #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
+#define SAA7134_BOARD_BEHOLD_505RDS         159
+#define SAA7134_BOARD_BEHOLD_507RDS_MK3     160
+#define SAA7134_BOARD_BEHOLD_507RDS_MK5     161
+#define SAA7134_BOARD_BEHOLD_607FM_MK5      162
+#define SAA7134_BOARD_BEHOLD_609FM_MK3      163
+#define SAA7134_BOARD_BEHOLD_609FM_MK5      164
+#define SAA7134_BOARD_BEHOLD_607RDS_MK3     165
+#define SAA7134_BOARD_BEHOLD_607RDS_MK5     166
+#define SAA7134_BOARD_BEHOLD_609RDS_MK3     167
+#define SAA7134_BOARD_BEHOLD_609RDS_MK5     168
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
-- 
cgit v1.2.3-70-g09d2


From 594bb46dbc63934bc65fa95743f83204bd26a641 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Fri, 24 Apr 2009 12:53:51 -0300
Subject: V4L/DVB (11607): soc-camera: add a free_bus method to struct
 soc_camera_link

Currently pcm990 camera bus-width management functions request a GPIO and never
free it again. With this approach the GPIO extender driver cannot be unloaded
once camera drivers have been loaded, also unloading theb i2c-pxa bus driver
produces errors, because the GPIO extender driver cannot unregister properly.
Another problem is, that if camera drivers are once loaded before the GPIO
extender driver, the platform code marks the GPIO unavailable and only a reboot
helps to recover. Adding an explicit free_bus method and using it in mt9m001
and mt9v022 drivers fixes these problems.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 arch/arm/mach-pxa/pcm990-baseboard.c | 23 ++++++++++++++++-------
 drivers/media/video/mt9m001.c        |  3 +++
 drivers/media/video/mt9v022.c        |  3 +++
 include/media/soc_camera.h           |  1 +
 4 files changed, 23 insertions(+), 7 deletions(-)

(limited to 'drivers/media/video')

diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 095521e9ee2..01791d74e08 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -380,12 +380,12 @@ static struct pca953x_platform_data pca9536_data = {
 	.gpio_base	= NR_BUILTIN_GPIO,
 };
 
-static int gpio_bus_switch;
+static int gpio_bus_switch = -EINVAL;
 
 static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
-		unsigned long flags)
+				       unsigned long flags)
 {
-	if (gpio_bus_switch <= 0) {
+	if (gpio_bus_switch < 0) {
 		if (flags == SOCAM_DATAWIDTH_10)
 			return 0;
 		else
@@ -404,25 +404,34 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
 {
 	int ret;
 
-	if (!gpio_bus_switch) {
+	if (gpio_bus_switch < 0) {
 		ret = gpio_request(NR_BUILTIN_GPIO, "camera");
 		if (!ret) {
 			gpio_bus_switch = NR_BUILTIN_GPIO;
 			gpio_direction_output(gpio_bus_switch, 0);
-		} else
-			gpio_bus_switch = -EINVAL;
+		}
 	}
 
-	if (gpio_bus_switch > 0)
+	if (gpio_bus_switch >= 0)
 		return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
 	else
 		return SOCAM_DATAWIDTH_10;
 }
 
+static void pcm990_camera_free_bus(struct soc_camera_link *link)
+{
+	if (gpio_bus_switch < 0)
+		return;
+
+	gpio_free(gpio_bus_switch);
+	gpio_bus_switch = -EINVAL;
+}
+
 static struct soc_camera_link iclink = {
 	.bus_id	= 0, /* Must match with the camera ID above */
 	.query_bus_param = pcm990_camera_query_bus_param,
 	.set_bus_param = pcm990_camera_set_bus_param,
+	.free_bus = pcm990_camera_free_bus,
 };
 
 /* Board I2C devices. */
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 684f62fa789..3838ff77381 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -604,10 +604,13 @@ ei2c:
 static void mt9m001_video_remove(struct soc_camera_device *icd)
 {
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
 
 	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr,
 		icd->dev.parent, icd->vdev);
 	soc_camera_video_stop(icd);
+	if (icl->free_bus)
+		icl->free_bus(icl);
 }
 
 static int mt9m001_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 4d3b4813c32..412b399baca 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -735,10 +735,13 @@ ei2c:
 static void mt9v022_video_remove(struct soc_camera_device *icd)
 {
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
 
 	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr,
 		icd->dev.parent, icd->vdev);
 	soc_camera_video_stop(icd);
+	if (icl->free_bus)
+		icl->free_bus(icl);
 }
 
 static int mt9v022_probe(struct i2c_client *client,
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 37013688af4..396c32550e0 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -107,6 +107,7 @@ struct soc_camera_link {
 	 */
 	int (*set_bus_param)(struct soc_camera_link *, unsigned long flags);
 	unsigned long (*query_bus_param)(struct soc_camera_link *);
+	void (*free_bus)(struct soc_camera_link *);
 };
 
 static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
-- 
cgit v1.2.3-70-g09d2


From eb6c8558f7658b7f31ee022c7bea1d840eda33dc Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Fri, 24 Apr 2009 12:55:18 -0300
Subject: V4L/DVB (11608): soc-camera: host-driver cleanup

Embed struct soc_camera_host in platform-specific per host instance objects
instead of allocating them statically in drivers, use platform_[gs]et_drvdata
consistently, use resource_size().

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/mx1_camera.c           | 21 +++++++++------------
 drivers/media/video/mx3_camera.c           |  2 +-
 drivers/media/video/pxa_camera.c           | 29 +++++++++++++----------------
 drivers/media/video/sh_mobile_ceu_camera.c |  6 +++---
 4 files changed, 26 insertions(+), 32 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 86fab56c5a2..48dd984dadf 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -102,6 +102,7 @@ struct mx1_buffer {
  * Interface. If anyone ever builds hardware to enable more than
  * one camera, they will have to modify this driver too */
 struct mx1_camera_dev {
+	struct soc_camera_host		soc_host;
 	struct soc_camera_device	*icd;
 	struct mx1_camera_pdata		*pdata;
 	struct mx1_buffer		*active;
@@ -633,12 +634,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
 	.querycap	= mx1_camera_querycap,
 };
 
-/* Should be allocated dynamically too, but we have only one. */
-static struct soc_camera_host mx1_soc_camera_host = {
-	.drv_name	= DRIVER_NAME,
-	.ops		= &mx1_soc_camera_host_ops,
-};
-
 static struct fiq_handler fh = {
 	.name		= "csi_sof"
 };
@@ -673,7 +668,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 		goto exit_put_clk;
 	}
 
-	dev_set_drvdata(&pdev->dev, pcdev);
+	platform_set_drvdata(pdev, pcdev);
 	pcdev->res = res;
 	pcdev->clk = clk;
 
@@ -746,10 +741,12 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 	mxc_set_irq_fiq(irq, 1);
 	enable_fiq(irq);
 
-	mx1_soc_camera_host.priv	= pcdev;
-	mx1_soc_camera_host.dev.parent	= &pdev->dev;
-	mx1_soc_camera_host.nr		= pdev->id;
-	err = soc_camera_host_register(&mx1_soc_camera_host);
+	pcdev->soc_host.drv_name	= DRIVER_NAME;
+	pcdev->soc_host.ops		= &mx1_soc_camera_host_ops;
+	pcdev->soc_host.priv		= pcdev;
+	pcdev->soc_host.dev.parent	= &pdev->dev;
+	pcdev->soc_host.nr		= pdev->id;
+	err = soc_camera_host_register(&pcdev->soc_host);
 	if (err)
 		goto exit_free_irq;
 
@@ -787,7 +784,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev)
 
 	clk_put(pcdev->clk);
 
-	soc_camera_host_unregister(&mx1_soc_camera_host);
+	soc_camera_host_unregister(&pcdev->soc_host);
 
 	iounmap(pcdev->base);
 
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 2d0781118eb..3d187f966d6 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -1102,7 +1102,7 @@ static int mx3_camera_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	dev_set_drvdata(&pdev->dev, mx3_cam);
+	platform_set_drvdata(pdev, mx3_cam);
 
 	mx3_cam->pdata = pdev->dev.platform_data;
 	mx3_cam->platform_flags = mx3_cam->pdata->flags;
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c639845460f..ad0d58c01bb 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -202,6 +202,7 @@ struct pxa_buffer {
 };
 
 struct pxa_camera_dev {
+	struct soc_camera_host	soc_host;
 	struct device		*dev;
 	/* PXA27x is only supposed to handle one camera on its Quick Capture
 	 * interface. If anyone ever builds hardware to enable more than
@@ -1552,12 +1553,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
 	.set_bus_param	= pxa_camera_set_bus_param,
 };
 
-/* Should be allocated dynamically too, but we have only one. */
-static struct soc_camera_host pxa_soc_camera_host = {
-	.drv_name		= PXA_CAM_DRV_NAME,
-	.ops			= &pxa_soc_camera_host_ops,
-};
-
 static int pxa_camera_probe(struct platform_device *pdev)
 {
 	struct pxa_camera_dev *pcdev;
@@ -1586,7 +1581,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
 		goto exit_kfree;
 	}
 
-	dev_set_drvdata(&pdev->dev, pcdev);
+	platform_set_drvdata(pdev, pcdev);
 	pcdev->res = res;
 
 	pcdev->pdata = pdev->dev.platform_data;
@@ -1616,13 +1611,13 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	/*
 	 * Request the regions.
 	 */
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				PXA_CAM_DRV_NAME)) {
 		err = -EBUSY;
 		goto exit_clk;
 	}
 
-	base = ioremap(res->start, res->end - res->start + 1);
+	base = ioremap(res->start, resource_size(res));
 	if (!base) {
 		err = -ENOMEM;
 		goto exit_release;
@@ -1670,10 +1665,12 @@ static int pxa_camera_probe(struct platform_device *pdev)
 		goto exit_free_dma;
 	}
 
-	pxa_soc_camera_host.priv	= pcdev;
-	pxa_soc_camera_host.dev.parent	= &pdev->dev;
-	pxa_soc_camera_host.nr		= pdev->id;
-	err = soc_camera_host_register(&pxa_soc_camera_host);
+	pcdev->soc_host.drv_name	= PXA_CAM_DRV_NAME;
+	pcdev->soc_host.ops		= &pxa_soc_camera_host_ops;
+	pcdev->soc_host.priv		= pcdev;
+	pcdev->soc_host.dev.parent	= &pdev->dev;
+	pcdev->soc_host.nr		= pdev->id;
+	err = soc_camera_host_register(&pcdev->soc_host);
 	if (err)
 		goto exit_free_irq;
 
@@ -1690,7 +1687,7 @@ exit_free_dma_y:
 exit_iounmap:
 	iounmap(base);
 exit_release:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 exit_clk:
 	clk_put(pcdev->clk);
 exit_kfree:
@@ -1711,12 +1708,12 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
 	pxa_free_dma(pcdev->dma_chans[2]);
 	free_irq(pcdev->irq, pcdev);
 
-	soc_camera_host_unregister(&pxa_soc_camera_host);
+	soc_camera_host_unregister(&pcdev->soc_host);
 
 	iounmap(pcdev->base);
 
 	res = pcdev->res;
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	kfree(pcdev);
 
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index b5e37a530c6..8e4a8fca976 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -840,7 +840,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 		goto exit_kfree;
 	}
 
-	base = ioremap_nocache(res->start, res->end - res->start + 1);
+	base = ioremap_nocache(res->start, resource_size(res));
 	if (!base) {
 		err = -ENXIO;
 		dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
@@ -856,7 +856,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 	if (res) {
 		err = dma_declare_coherent_memory(&pdev->dev, res->start,
 						  res->start,
-						  (res->end - res->start) + 1,
+						  resource_size(res),
 						  DMA_MEMORY_MAP |
 						  DMA_MEMORY_EXCLUSIVE);
 		if (!err) {
@@ -865,7 +865,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 			goto exit_iounmap;
 		}
 
-		pcdev->video_limit = (res->end - res->start) + 1;
+		pcdev->video_limit = resource_size(res);
 	}
 
 	/* request irq */
-- 
cgit v1.2.3-70-g09d2


From eff505fa1511b753b7cfb397a754b8ff4367cd55 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Fri, 24 Apr 2009 12:55:48 -0300
Subject: V4L/DVB (11609): soc-camera: remove an extra device generation from
 struct soc_camera_host

Make camera devices direct children of host platform devices, move the
inheritance management into the soc_camera.c core driver.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/mx1_camera.c           | 35 ++++++-----
 drivers/media/video/mx3_camera.c           | 40 ++++++------
 drivers/media/video/pxa_camera.c           | 97 +++++++++++++++---------------
 drivers/media/video/sh_mobile_ceu_camera.c | 21 +++----
 drivers/media/video/soc_camera.c           | 35 +++--------
 include/media/soc_camera.h                 |  4 +-
 6 files changed, 107 insertions(+), 125 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 48dd984dadf..2d075205bdf 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -106,7 +106,6 @@ struct mx1_camera_dev {
 	struct soc_camera_device	*icd;
 	struct mx1_camera_pdata		*pdata;
 	struct mx1_buffer		*active;
-	struct device			*dev;
 	struct resource			*res;
 	struct clk			*clk;
 	struct list_head		capture;
@@ -220,7 +219,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 	int ret;
 
 	if (unlikely(!pcdev->active)) {
-		dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+		dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
 		return -EFAULT;
 	}
 
@@ -230,7 +229,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 		vbuf->size, pcdev->res->start +
 		CSIRXR, DMA_MODE_READ);
 	if (unlikely(ret))
-		dev_err(pcdev->dev, "Failed to setup DMA sg list\n");
+		dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n");
 
 	return ret;
 }
@@ -339,14 +338,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
 	imx_dma_disable(channel);
 
 	if (unlikely(!pcdev->active)) {
-		dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+		dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
 		goto out;
 	}
 
 	vb = &pcdev->active->vb;
 	buf = container_of(vb, struct mx1_buffer, vb);
 	WARN_ON(buf->inwork || list_empty(&vb->queue));
-	dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	mx1_camera_wakeup(pcdev, vb, buf);
@@ -367,7 +366,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx1_camera_dev *pcdev = ici->priv;
 
-	videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev,
+	videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev,
 					&pcdev->lock,
 					V4L2_BUF_TYPE_VIDEO_CAPTURE,
 					V4L2_FIELD_NONE,
@@ -386,7 +385,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
 	 * they get a nice Oops */
 	div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
-	dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, "
+	dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, "
 		"divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
 
 	return div;
@@ -396,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
 {
 	unsigned int csicr1 = CSICR1_EN;
 
-	dev_dbg(pcdev->dev, "Activate device\n");
+	dev_dbg(pcdev->soc_host.dev, "Activate device\n");
 
 	clk_enable(pcdev->clk);
 
@@ -412,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
 
 static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
 {
-	dev_dbg(pcdev->dev, "Deactivate device\n");
+	dev_dbg(pcdev->soc_host.dev, "Deactivate device\n");
 
 	/* Disable all CSI interface */
 	__raw_writel(0x00, pcdev->base + CSICR1);
@@ -551,7 +550,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
 		return -EINVAL;
 	}
 
@@ -668,7 +667,6 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 		goto exit_put_clk;
 	}
 
-	platform_set_drvdata(pdev, pcdev);
 	pcdev->res = res;
 	pcdev->clk = clk;
 
@@ -702,16 +700,15 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 	}
 	pcdev->irq = irq;
 	pcdev->base = base;
-	pcdev->dev = &pdev->dev;
 
 	/* request dma */
 	pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
 	if (pcdev->dma_chan < 0) {
-		dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n");
+		dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
 		err = -EBUSY;
 		goto exit_iounmap;
 	}
-	dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
+	dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
 
 	imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
 			       pcdev);
@@ -724,7 +721,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 	/* request irq */
 	err = claim_fiq(&fh);
 	if (err) {
-		dev_err(pcdev->dev, "Camera interrupt register failed \n");
+		dev_err(&pdev->dev, "Camera interrupt register failed \n");
 		goto exit_free_dma;
 	}
 
@@ -744,7 +741,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 	pcdev->soc_host.drv_name	= DRIVER_NAME;
 	pcdev->soc_host.ops		= &mx1_soc_camera_host_ops;
 	pcdev->soc_host.priv		= pcdev;
-	pcdev->soc_host.dev.parent	= &pdev->dev;
+	pcdev->soc_host.dev		= &pdev->dev;
 	pcdev->soc_host.nr		= pdev->id;
 	err = soc_camera_host_register(&pcdev->soc_host);
 	if (err)
@@ -774,7 +771,9 @@ exit:
 
 static int __exit mx1_camera_remove(struct platform_device *pdev)
 {
-	struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev);
+	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+	struct mx1_camera_dev *pcdev = container_of(soc_host,
+					struct mx1_camera_dev, soc_host);
 	struct resource *res;
 
 	imx_dma_free(pcdev->dma_chan);
@@ -784,7 +783,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev)
 
 	clk_put(pcdev->clk);
 
-	soc_camera_host_unregister(&pcdev->soc_host);
+	soc_camera_host_unregister(soc_host);
 
 	iounmap(pcdev->base);
 
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 3d187f966d6..4d47eeb1445 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -87,7 +87,6 @@ struct mx3_camera_buffer {
  * @soc_host:		embedded soc_host object
  */
 struct mx3_camera_dev {
-	struct device		*dev;
 	/*
 	 * i.MX3x is only supposed to handle one camera on its Camera Sensor
 	 * Interface. If anyone ever builds hardware to enable more than one
@@ -431,7 +430,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 
-	videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev,
+	videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev,
 				       &mx3_cam->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				       V4L2_FIELD_NONE,
@@ -599,7 +598,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
 		*flags |= SOCAM_DATAWIDTH_4;
 		break;
 	default:
-		dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth);
+		dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n",
+			 buswidth);
 		return -EINVAL;
 	}
 
@@ -614,7 +614,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
 	unsigned long bus_flags, camera_flags;
 	int ret = test_platform_param(mx3_cam, depth, &bus_flags);
 
-	dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+	dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret);
 
 	if (ret < 0)
 		return ret;
@@ -637,7 +637,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
 	if (!rq)
 		return false;
 
-	pdata = rq->mx3_cam->dev->platform_data;
+	pdata = rq->mx3_cam->soc_host.dev->platform_data;
 
 	return rq->id == chan->chan_id &&
 		pdata->dma_dev == chan->device->dev;
@@ -697,7 +697,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+			dev_dbg(ici->dev, "Providing format %s using %s\n",
 				mx3_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -709,7 +709,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+			dev_dbg(ici->dev, "Providing format %s using %s\n",
 				mx3_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -722,7 +722,7 @@ passthrough:
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(&ici->dev,
+			dev_dbg(ici->dev,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -829,7 +829,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
 		return -EINVAL;
 	}
 
@@ -866,7 +866,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (pixfmt && !xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -933,11 +933,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
-	dev_dbg(&ici->dev, "requested bus width %d bit: %d\n",
+	dev_dbg(ici->dev, "requested bus width %d bit: %d\n",
 		icd->buswidth, ret);
 
 	if (ret < 0)
@@ -947,7 +947,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 
 	common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
 	if (!common_flags) {
-		dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n",
+		dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n",
 			camera_flags, bus_flags);
 		return -EINVAL;
 	}
@@ -1054,7 +1054,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 
 	csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
 
-	dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+	dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
 
 	return 0;
 }
@@ -1102,8 +1102,6 @@ static int mx3_camera_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	platform_set_drvdata(pdev, mx3_cam);
-
 	mx3_cam->pdata = pdev->dev.platform_data;
 	mx3_cam->platform_flags = mx3_cam->pdata->flags;
 	if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
@@ -1135,14 +1133,14 @@ static int mx3_camera_probe(struct platform_device *pdev)
 	}
 
 	mx3_cam->base	= base;
-	mx3_cam->dev	= &pdev->dev;
 
 	soc_host		= &mx3_cam->soc_host;
 	soc_host->drv_name	= MX3_CAM_DRV_NAME;
 	soc_host->ops		= &mx3_soc_camera_host_ops;
 	soc_host->priv		= mx3_cam;
-	soc_host->dev.parent	= &pdev->dev;
+	soc_host->dev		= &pdev->dev;
 	soc_host->nr		= pdev->id;
+
 	err = soc_camera_host_register(soc_host);
 	if (err)
 		goto ecamhostreg;
@@ -1165,11 +1163,13 @@ egetres:
 
 static int __devexit mx3_camera_remove(struct platform_device *pdev)
 {
-	struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev);
+	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+	struct mx3_camera_dev *mx3_cam = container_of(soc_host,
+					struct mx3_camera_dev, soc_host);
 
 	clk_put(mx3_cam->clk);
 
-	soc_camera_host_unregister(&mx3_cam->soc_host);
+	soc_camera_host_unregister(soc_host);
 
 	iounmap(mx3_cam->base);
 
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index ad0d58c01bb..2da5eef19b7 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -203,7 +203,6 @@ struct pxa_buffer {
 
 struct pxa_camera_dev {
 	struct soc_camera_host	soc_host;
-	struct device		*dev;
 	/* PXA27x is only supposed to handle one camera on its Quick Capture
 	 * interface. If anyone ever builds hardware to enable more than
 	 * one camera, they will have to modify this driver too */
@@ -262,7 +261,6 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 {
 	struct soc_camera_device *icd = vq->priv_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
 	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
 	int i;
 
@@ -279,7 +277,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 
 	for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
 		if (buf->dmas[i].sg_cpu)
-			dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size,
+			dma_free_coherent(ici->dev, buf->dmas[i].sg_size,
 					  buf->dmas[i].sg_cpu,
 					  buf->dmas[i].sg_dma);
 		buf->dmas[i].sg_cpu = NULL;
@@ -339,14 +337,14 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 	int dma_len = 0, xfer_len = 0;
 
 	if (pxa_dma->sg_cpu)
-		dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
+		dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
 				  pxa_dma->sg_cpu, pxa_dma->sg_dma);
 
 	sglen = calculate_dma_sglen(*sg_first, dma->sglen,
 				    *sg_first_ofs, size);
 
 	pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
-	pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
+	pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
 					     &pxa_dma->sg_dma, GFP_KERNEL);
 	if (!pxa_dma->sg_cpu)
 		return -ENOMEM;
@@ -354,7 +352,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 	pxa_dma->sglen = sglen;
 	offset = *sg_first_ofs;
 
-	dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+	dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
 		*sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
 
 
@@ -377,7 +375,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 		pxa_dma->sg_cpu[i].ddadr =
 			pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
 
-		dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+		dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
 			 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
 			 sg_dma_address(sg) + offset, xfer_len);
 		offset = 0;
@@ -489,7 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 		ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
 					   &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->dev,
+			dev_err(pcdev->soc_host.dev,
 				"DMA initialization for Y/RGB failed\n");
 			goto fail;
 		}
@@ -499,7 +497,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 			ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
 						   size_u, &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->dev,
+			dev_err(pcdev->soc_host.dev,
 				"DMA initialization for U failed\n");
 			goto fail_u;
 		}
@@ -509,7 +507,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 			ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
 						   size_v, &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->dev,
+			dev_err(pcdev->soc_host.dev,
 				"DMA initialization for V failed\n");
 			goto fail_v;
 		}
@@ -523,10 +521,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 	return 0;
 
 fail_v:
-	dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size,
+	dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size,
 			  buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
 fail_u:
-	dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size,
+	dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size,
 			  buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
 fail:
 	free_buffer(vq, buf);
@@ -550,7 +548,7 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
 	active = pcdev->active;
 
 	for (i = 0; i < pcdev->channels; i++) {
-		dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+		dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__,
 			i, active->dmas[i].sg_dma);
 		DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
 		DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -562,7 +560,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
 	int i;
 
 	for (i = 0; i < pcdev->channels; i++) {
-		dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i);
+		dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i);
 		DCSR(pcdev->dma_chans[i]) = 0;
 	}
 }
@@ -598,7 +596,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
 {
 	unsigned long cicr0, cifr;
 
-	dev_dbg(pcdev->dev, "%s\n", __func__);
+	dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
 	/* Reset the FIFOs */
 	cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
 	__raw_writel(cifr, pcdev->base + CIFR);
@@ -618,7 +616,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
 	__raw_writel(cicr0, pcdev->base + CICR0);
 
 	pcdev->active = NULL;
-	dev_dbg(pcdev->dev, "%s\n", __func__);
+	dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
 }
 
 static void pxa_videobuf_queue(struct videobuf_queue *vq,
@@ -687,7 +685,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
-	dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
+	dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
 
 	if (list_empty(&pcdev->capture)) {
 		pxa_camera_stop_capture(pcdev);
@@ -723,7 +721,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
 	for (i = 0; i < pcdev->channels; i++)
 		if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
 			is_dma_stopped = 0;
-	dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+	dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
 		__func__, pcdev->active, is_dma_stopped);
 	if (pcdev->active && is_dma_stopped)
 		pxa_camera_start_capture(pcdev);
@@ -748,12 +746,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 		overrun |= CISR_IFO_1 | CISR_IFO_2;
 
 	if (status & DCSR_BUSERR) {
-		dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
+		dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n");
 		goto out;
 	}
 
 	if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
-		dev_err(pcdev->dev, "Unknown DMA IRQ source, "
+		dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, "
 			"status: 0x%08x\n", status);
 		goto out;
 	}
@@ -777,7 +775,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 	buf = container_of(vb, struct pxa_buffer, vb);
 	WARN_ON(buf->inwork || list_empty(&vb->queue));
 
-	dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+	dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
 		__func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
 		status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
 
@@ -788,7 +786,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 		 */
 		if (camera_status & overrun &&
 		    !list_is_last(pcdev->capture.next, &pcdev->capture)) {
-			dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n",
+			dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n",
 				camera_status);
 			pxa_camera_stop_capture(pcdev);
 			pxa_camera_start_capture(pcdev);
@@ -855,7 +853,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
 	/* mclk <= ciclk / 4 (27.4.2) */
 	if (mclk > lcdclk / 4) {
 		mclk = lcdclk / 4;
-		dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk);
+		dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk);
 	}
 
 	/* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -865,7 +863,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
 	if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
 		pcdev->mclk = lcdclk / (2 * (div + 1));
 
-	dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, "
+	dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, "
 		"divisor %u\n", lcdclk, mclk, div);
 
 	return div;
@@ -885,12 +883,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
 	struct pxacamera_platform_data *pdata = pcdev->pdata;
 	u32 cicr4 = 0;
 
-	dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n",
+	dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n",
 		pcdev, pdata);
 
 	if (pdata && pdata->init) {
-		dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__);
-		pdata->init(pcdev->dev);
+		dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__);
+		pdata->init(pcdev->soc_host.dev);
 	}
 
 	/* disable all interrupts */
@@ -932,7 +930,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
 	struct videobuf_buffer *vb;
 
 	status = __raw_readl(pcdev->base + CISR);
-	dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
+	dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status);
 
 	if (!status)
 		return IRQ_NONE;
@@ -1260,7 +1258,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+			dev_dbg(ici->dev, "Providing format %s using %s\n",
 				pxa_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -1275,7 +1273,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(&ici->dev, "Providing format %s packed\n",
+			dev_dbg(ici->dev, "Providing format %s packed\n",
 				icd->formats[idx].name);
 		}
 		break;
@@ -1287,7 +1285,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(&ici->dev,
+			dev_dbg(ici->dev,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -1316,11 +1314,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
 	icd->sense = NULL;
 
 	if (ret < 0) {
-		dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+		dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n",
 			 rect->width, rect->height, rect->left, rect->top);
 	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
-			dev_err(&ici->dev,
+			dev_err(ici->dev,
 				"pixel clock %lu set by the camera too high!",
 				sense.pixel_clock);
 			return -EIO;
@@ -1348,7 +1346,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
 		return -EINVAL;
 	}
 
@@ -1364,11 +1362,11 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 	icd->sense = NULL;
 
 	if (ret < 0) {
-		dev_warn(&ici->dev, "Failed to configure for format %x\n",
+		dev_warn(ici->dev, "Failed to configure for format %x\n",
 			 pix->pixelformat);
 	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
-			dev_err(&ici->dev,
+			dev_err(ici->dev,
 				"pixel clock %lu set by the camera too high!",
 				sense.pixel_clock);
 			return -EIO;
@@ -1396,7 +1394,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -1581,7 +1579,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
 		goto exit_kfree;
 	}
 
-	platform_set_drvdata(pdev, pcdev);
 	pcdev->res = res;
 
 	pcdev->pdata = pdev->dev.platform_data;
@@ -1602,7 +1599,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
 		pcdev->mclk = 20000000;
 	}
 
-	pcdev->dev = &pdev->dev;
 	pcdev->mclk_divisor = mclk_get_divisor(pcdev);
 
 	INIT_LIST_HEAD(&pcdev->capture);
@@ -1629,29 +1625,29 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
 			      pxa_camera_dma_irq_y, pcdev);
 	if (err < 0) {
-		dev_err(pcdev->dev, "Can't request DMA for Y\n");
+		dev_err(&pdev->dev, "Can't request DMA for Y\n");
 		goto exit_iounmap;
 	}
 	pcdev->dma_chans[0] = err;
-	dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
+	dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
 
 	err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
 			      pxa_camera_dma_irq_u, pcdev);
 	if (err < 0) {
-		dev_err(pcdev->dev, "Can't request DMA for U\n");
+		dev_err(&pdev->dev, "Can't request DMA for U\n");
 		goto exit_free_dma_y;
 	}
 	pcdev->dma_chans[1] = err;
-	dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
+	dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
 
 	err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
 			      pxa_camera_dma_irq_v, pcdev);
 	if (err < 0) {
-		dev_err(pcdev->dev, "Can't request DMA for V\n");
+		dev_err(&pdev->dev, "Can't request DMA for V\n");
 		goto exit_free_dma_u;
 	}
 	pcdev->dma_chans[2] = err;
-	dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
+	dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
 
 	DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
 	DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
@@ -1661,15 +1657,16 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
 			  pcdev);
 	if (err) {
-		dev_err(pcdev->dev, "Camera interrupt register failed \n");
+		dev_err(&pdev->dev, "Camera interrupt register failed \n");
 		goto exit_free_dma;
 	}
 
 	pcdev->soc_host.drv_name	= PXA_CAM_DRV_NAME;
 	pcdev->soc_host.ops		= &pxa_soc_camera_host_ops;
 	pcdev->soc_host.priv		= pcdev;
-	pcdev->soc_host.dev.parent	= &pdev->dev;
+	pcdev->soc_host.dev		= &pdev->dev;
 	pcdev->soc_host.nr		= pdev->id;
+
 	err = soc_camera_host_register(&pcdev->soc_host);
 	if (err)
 		goto exit_free_irq;
@@ -1698,7 +1695,9 @@ exit:
 
 static int __devexit pxa_camera_remove(struct platform_device *pdev)
 {
-	struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev);
+	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+	struct pxa_camera_dev *pcdev = container_of(soc_host,
+					struct pxa_camera_dev, soc_host);
 	struct resource *res;
 
 	clk_put(pcdev->clk);
@@ -1708,7 +1707,7 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
 	pxa_free_dma(pcdev->dma_chans[2]);
 	free_irq(pcdev->irq, pcdev);
 
-	soc_camera_host_unregister(&pcdev->soc_host);
+	soc_camera_host_unregister(soc_host);
 
 	iounmap(pcdev->base);
 
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 8e4a8fca976..d369e8409ab 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -81,7 +81,6 @@ struct sh_mobile_ceu_buffer {
 };
 
 struct sh_mobile_ceu_dev {
-	struct device *dev;
 	struct soc_camera_host ici;
 	struct soc_camera_device *icd;
 
@@ -617,7 +616,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+			dev_dbg(ici->dev, "Providing format %s using %s\n",
 				sh_mobile_ceu_formats[k].name,
 				icd->formats[idx].name);
 		}
@@ -630,7 +629,7 @@ add_single_format:
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(&ici->dev,
+			dev_dbg(ici->dev,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -657,7 +656,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -684,7 +683,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -782,7 +781,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
 
 	videobuf_queue_dma_contig_init(q,
 				       &sh_mobile_ceu_videobuf_ops,
-				       &ici->dev, &pcdev->lock,
+				       ici->dev, &pcdev->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				       pcdev->is_interlaced ?
 				       V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -829,7 +828,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 		goto exit;
 	}
 
-	platform_set_drvdata(pdev, pcdev);
 	INIT_LIST_HEAD(&pcdev->capture);
 	spin_lock_init(&pcdev->lock);
 
@@ -850,7 +848,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 	pcdev->irq = irq;
 	pcdev->base = base;
 	pcdev->video_limit = 0; /* only enabled if second resource exists */
-	pcdev->dev = &pdev->dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (res) {
@@ -885,7 +882,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 	}
 
 	pcdev->ici.priv = pcdev;
-	pcdev->ici.dev.parent = &pdev->dev;
+	pcdev->ici.dev = &pdev->dev;
 	pcdev->ici.nr = pdev->id;
 	pcdev->ici.drv_name = dev_name(&pdev->dev);
 	pcdev->ici.ops = &sh_mobile_ceu_host_ops;
@@ -913,9 +910,11 @@ exit:
 
 static int sh_mobile_ceu_remove(struct platform_device *pdev)
 {
-	struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev);
+	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+	struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
+					struct sh_mobile_ceu_dev, ici);
 
-	soc_camera_host_unregister(&pcdev->ici);
+	soc_camera_host_unregister(soc_host);
 	clk_put(pcdev->clk);
 	free_irq(pcdev->irq, pcdev);
 	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0e890cc2337..2d341f537d5 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -279,7 +279,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 		return ret;
 	} else if (!icd->current_fmt ||
 		   icd->current_fmt->fourcc != pix->pixelformat) {
-		dev_err(&ici->dev,
+		dev_err(ici->dev,
 			"Host driver hasn't set up current format correctly!\n");
 		return -EINVAL;
 	}
@@ -794,7 +794,7 @@ static void scan_add_host(struct soc_camera_host *ici)
 
 	list_for_each_entry(icd, &devices, list) {
 		if (icd->iface == ici->nr) {
-			icd->dev.parent = &ici->dev;
+			icd->dev.parent = ici->dev;
 			device_register_link(icd);
 		}
 	}
@@ -818,7 +818,7 @@ static int scan_add_device(struct soc_camera_device *icd)
 	list_for_each_entry(ici, &hosts, list) {
 		if (icd->iface == ici->nr) {
 			ret = 1;
-			icd->dev.parent = &ici->dev;
+			icd->dev.parent = ici->dev;
 			break;
 		}
 	}
@@ -952,7 +952,6 @@ static void dummy_release(struct device *dev)
 
 int soc_camera_host_register(struct soc_camera_host *ici)
 {
-	int ret;
 	struct soc_camera_host *ix;
 
 	if (!ici || !ici->ops ||
@@ -965,12 +964,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
 	    !ici->ops->reqbufs ||
 	    !ici->ops->add ||
 	    !ici->ops->remove ||
-	    !ici->ops->poll)
+	    !ici->ops->poll ||
+	    !ici->dev)
 		return -EINVAL;
 
-	/* Number might be equal to the platform device ID */
-	dev_set_name(&ici->dev, "camera_host%d", ici->nr);
-
 	mutex_lock(&list_lock);
 	list_for_each_entry(ix, &hosts, list) {
 		if (ix->nr == ici->nr) {
@@ -979,26 +976,14 @@ int soc_camera_host_register(struct soc_camera_host *ici)
 		}
 	}
 
+	dev_set_drvdata(ici->dev, ici);
+
 	list_add_tail(&ici->list, &hosts);
 	mutex_unlock(&list_lock);
 
-	ici->dev.release = dummy_release;
-
-	ret = device_register(&ici->dev);
-
-	if (ret)
-		goto edevr;
-
 	scan_add_host(ici);
 
 	return 0;
-
-edevr:
-	mutex_lock(&list_lock);
-	list_del(&ici->list);
-	mutex_unlock(&list_lock);
-
-	return ret;
 }
 EXPORT_SYMBOL(soc_camera_host_register);
 
@@ -1012,7 +997,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 	list_del(&ici->list);
 
 	list_for_each_entry(icd, &devices, list) {
-		if (icd->dev.parent == &ici->dev) {
+		if (icd->dev.parent == ici->dev) {
 			device_unregister(&icd->dev);
 			/* Not before device_unregister(), .remove
 			 * needs parent to call ici->ops->remove() */
@@ -1023,7 +1008,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 
 	mutex_unlock(&list_lock);
 
-	device_unregister(&ici->dev);
+	dev_set_drvdata(ici->dev, NULL);
 }
 EXPORT_SYMBOL(soc_camera_host_unregister);
 
@@ -1130,7 +1115,7 @@ int soc_camera_video_start(struct soc_camera_device *icd)
 	vdev = video_device_alloc();
 	if (!vdev)
 		goto evidallocd;
-	dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev);
+	dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
 
 	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 396c32550e0..bef5e81d693 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -60,7 +60,7 @@ struct soc_camera_file {
 
 struct soc_camera_host {
 	struct list_head list;
-	struct device dev;
+	struct device *dev;
 	unsigned char nr;				/* Host number */
 	void *priv;
 	const char *drv_name;
@@ -117,7 +117,7 @@ static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
 
 static inline struct soc_camera_host *to_soc_camera_host(struct device *dev)
 {
-	return container_of(dev, struct soc_camera_host, dev);
+	return dev_get_drvdata(dev);
 }
 
 extern int soc_camera_host_register(struct soc_camera_host *ici);
-- 
cgit v1.2.3-70-g09d2


From 9538e1c226f1fd665126869f542170a2e90f2039 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Fri, 24 Apr 2009 12:57:01 -0300
Subject: V4L/DVB (11610): soc-camera: simplify register access routines in
 multiple sensor drivers

Register access routines only need the I2C client, not the soc-camera device
context.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/mt9m001.c | 105 ++++++++++++++++----------------
 drivers/media/video/mt9m111.c |  73 ++++++++++++-----------
 drivers/media/video/mt9t031.c | 135 ++++++++++++++++++++++--------------------
 drivers/media/video/mt9v022.c | 135 ++++++++++++++++++++++--------------------
 4 files changed, 236 insertions(+), 212 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 3838ff77381..459c04cbf69 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -75,53 +75,50 @@ struct mt9m001 {
 	unsigned char autoexposure;
 };
 
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct i2c_client *client = mt9m001->client;
 	s32 data = i2c_smbus_read_word_data(client, reg);
 	return data < 0 ? data : swab16(data);
 }
 
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data));
+	return i2c_smbus_write_word_data(client, reg, swab16(data));
 }
 
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
 		   const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret | data);
+	return reg_write(client, reg, ret | data);
 }
 
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret & ~data);
+	return reg_write(client, reg, ret & ~data);
 }
 
 static int mt9m001_init(struct soc_camera_device *icd)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(icd->control);
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	dev_dbg(icd->vdev->parent, "%s\n", __func__);
 
 	if (icl->power) {
-		ret = icl->power(&mt9m001->client->dev, 1);
+		ret = icl->power(&client->dev, 1);
 		if (ret < 0) {
 			dev_err(icd->vdev->parent,
 				"Platform failed to power-on the camera.\n");
@@ -131,49 +128,53 @@ static int mt9m001_init(struct soc_camera_device *icd)
 
 	/* The camera could have been already on, we reset it additionally */
 	if (icl->reset)
-		ret = icl->reset(&mt9m001->client->dev);
+		ret = icl->reset(&client->dev);
 	else
 		ret = -ENODEV;
 
 	if (ret < 0) {
 		/* Either no platform reset, or platform reset failed */
-		ret = reg_write(icd, MT9M001_RESET, 1);
+		ret = reg_write(client, MT9M001_RESET, 1);
 		if (!ret)
-			ret = reg_write(icd, MT9M001_RESET, 0);
+			ret = reg_write(client, MT9M001_RESET, 0);
 	}
 	/* Disable chip, synchronous option update */
 	if (!ret)
-		ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
+		ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
 
 	return ret;
 }
 
 static int mt9m001_release(struct soc_camera_device *icd)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(icd->control);
+	struct soc_camera_link *icl = client->dev.platform_data;
 
 	/* Disable the chip */
-	reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
+	reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
 
 	if (icl->power)
-		icl->power(&mt9m001->client->dev, 0);
+		icl->power(&client->dev, 0);
 
 	return 0;
 }
 
 static int mt9m001_start_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
+
 	/* Switch to master "normal" mode */
-	if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0)
+	if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
 		return -EIO;
 	return 0;
 }
 
 static int mt9m001_stop_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
+
 	/* Stop sensor readout */
-	if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0)
+	if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
 		return -EIO;
 	return 0;
 }
@@ -222,28 +223,29 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
 static int mt9m001_set_crop(struct soc_camera_device *icd,
 			    struct v4l2_rect *rect)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
 	int ret;
 	const u16 hblank = 9, vblank = 25;
 
 	/* Blanking and start values - default... */
-	ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank);
+	ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
 	if (!ret)
-		ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank);
+		ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
 
 	/* The caller provides a supported format, as verified per
 	 * call to icd->try_fmt() */
 	if (!ret)
-		ret = reg_write(icd, MT9M001_COLUMN_START, rect->left);
+		ret = reg_write(client, MT9M001_COLUMN_START, rect->left);
 	if (!ret)
-		ret = reg_write(icd, MT9M001_ROW_START, rect->top);
+		ret = reg_write(client, MT9M001_ROW_START, rect->top);
 	if (!ret)
-		ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1);
+		ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1);
 	if (!ret)
-		ret = reg_write(icd, MT9M001_WINDOW_HEIGHT,
+		ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
 				rect->height + icd->y_skip_top - 1);
 	if (!ret && mt9m001->autoexposure) {
-		ret = reg_write(icd, MT9M001_SHUTTER_WIDTH,
+		ret = reg_write(client, MT9M001_SHUTTER_WIDTH,
 				rect->height + icd->y_skip_top + vblank);
 		if (!ret) {
 			const struct v4l2_queryctrl *qctrl =
@@ -312,16 +314,16 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
 static int mt9m001_get_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9m001->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
 	reg->size = 2;
-	reg->val = reg_read(icd, reg->reg);
+	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
 		return -EIO;
@@ -332,15 +334,15 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
 static int mt9m001_set_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9m001->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	if (reg_write(icd, reg->reg, reg->val) < 0)
+	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
 	return 0;
@@ -416,12 +418,13 @@ static struct soc_camera_ops mt9m001_ops = {
 
 static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
 	int data;
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
-		data = reg_read(icd, MT9M001_READ_OPTIONS2);
+		data = reg_read(client, MT9M001_READ_OPTIONS2);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x8000);
@@ -435,6 +438,7 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
 
 static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
 	const struct v4l2_queryctrl *qctrl;
 	int data;
@@ -447,9 +451,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		if (ctrl->value)
-			data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000);
+			data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
 		else
-			data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000);
+			data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
 		if (data < 0)
 			return -EIO;
 		break;
@@ -463,7 +467,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
 
 			dev_dbg(&icd->dev, "Setting gain %d\n", data);
-			data = reg_write(icd, MT9M001_GLOBAL_GAIN, data);
+			data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
 		} else {
@@ -481,8 +485,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 				data = ((gain - 64) * 7 + 28) / 56 + 96;
 
 			dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
-				 reg_read(icd, MT9M001_GLOBAL_GAIN), data);
-			data = reg_write(icd, MT9M001_GLOBAL_GAIN, data);
+				 reg_read(client, MT9M001_GLOBAL_GAIN), data);
+			data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
 		}
@@ -500,8 +504,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 						 range / 2) / range + 1;
 
 			dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n",
-				 reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter);
-			if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0)
+				 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
+			if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
 				return -EIO;
 			icd->exposure = ctrl->value;
 			mt9m001->autoexposure = 0;
@@ -510,7 +514,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 	case V4L2_CID_EXPOSURE_AUTO:
 		if (ctrl->value) {
 			const u16 vblank = 25;
-			if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height +
+			if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height +
 				      icd->y_skip_top + vblank) < 0)
 				return -EIO;
 			qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -529,8 +533,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
  * this wasn't our capture interface, so, we wait for the right one */
 static int mt9m001_video_probe(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	s32 data;
 	int ret;
 	unsigned long flags;
@@ -542,11 +547,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
 		return -ENODEV;
 
 	/* Enable the chip */
-	data = reg_write(icd, MT9M001_CHIP_ENABLE, 1);
+	data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
 	dev_dbg(&icd->dev, "write: %d\n", data);
 
 	/* Read out the chip version register */
-	data = reg_read(icd, MT9M001_CHIP_VERSION);
+	data = reg_read(client, MT9M001_CHIP_VERSION);
 
 	/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
 	switch (data) {
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index cdd1ddb5138..fc5e2de0376 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -113,10 +113,10 @@
  * mt9m111: Camera control register addresses (0x200..0x2ff not implemented)
  */
 
-#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg)
-#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val))
-#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val))
-#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val))
+#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
+#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
+#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
+#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
 
 #define MT9M111_MIN_DARK_ROWS	8
 #define MT9M111_MIN_DARK_COLS	24
@@ -184,58 +184,55 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg)
 	return ret;
 }
 
-static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg)
+static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct i2c_client *client = mt9m111->client;
 	int ret;
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
 		ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff)));
 
-	dev_dbg(&icd->dev, "read  reg.%03x -> %04x\n", reg, ret);
+	dev_dbg(&client->dev, "read  reg.%03x -> %04x\n", reg, ret);
 	return ret;
 }
 
-static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
 			     const u16 data)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct i2c_client *client = mt9m111->client;
 	int ret;
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
-		ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff),
+		ret = i2c_smbus_write_word_data(client, (reg & 0xff),
 						swab16(data));
-	dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
+	dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
 	return ret;
 }
 
-static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
 			   const u16 data)
 {
 	int ret;
 
-	ret = mt9m111_reg_read(icd, reg);
+	ret = mt9m111_reg_read(client, reg);
 	if (ret >= 0)
-		ret = mt9m111_reg_write(icd, reg, ret | data);
+		ret = mt9m111_reg_write(client, reg, ret | data);
 	return ret;
 }
 
-static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg,
+static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
 			     const u16 data)
 {
 	int ret;
 
-	ret = mt9m111_reg_read(icd, reg);
-	return mt9m111_reg_write(icd, reg, ret & ~data);
+	ret = mt9m111_reg_read(client, reg);
+	return mt9m111_reg_write(client, reg, ret & ~data);
 }
 
 static int mt9m111_set_context(struct soc_camera_device *icd,
 			       enum mt9m111_context ctxt)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
 		| MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
 		| MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -252,6 +249,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
 static int mt9m111_setup_rect(struct soc_camera_device *icd,
 			      struct v4l2_rect *rect)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int ret, is_raw_format;
 	int width = rect->width;
@@ -296,6 +294,7 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
 
 static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	int ret;
 
 	ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -357,12 +356,13 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
 
 static int mt9m111_enable(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	if (icl->power) {
-		ret = icl->power(&mt9m111->client->dev, 1);
+		ret = icl->power(&client->dev, 1);
 		if (ret < 0) {
 			dev_err(icd->vdev->parent,
 				"Platform failed to power-on the camera.\n");
@@ -378,8 +378,9 @@ static int mt9m111_enable(struct soc_camera_device *icd)
 
 static int mt9m111_disable(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
@@ -387,15 +388,15 @@ static int mt9m111_disable(struct soc_camera_device *icd)
 		mt9m111->powered = 0;
 
 	if (icl->power)
-		icl->power(&mt9m111->client->dev, 0);
+		icl->power(&client->dev, 0);
 
 	return ret;
 }
 
 static int mt9m111_reset(struct soc_camera_device *icd)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(icd->control);
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,7 +407,7 @@ static int mt9m111_reset(struct soc_camera_device *icd)
 				| MT9M111_RESET_RESET_SOC);
 
 	if (icl->reset)
-		icl->reset(&mt9m111->client->dev);
+		icl->reset(&client->dev);
 
 	return ret;
 }
@@ -562,15 +563,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
 	int val;
-
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
 		return -EINVAL;
-	if (reg->match.addr != mt9m111->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	val = mt9m111_reg_read(icd, reg->reg);
+	val = mt9m111_reg_read(client, reg->reg);
 	reg->size = 2;
 	reg->val = (u64)val;
 
@@ -583,15 +583,15 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
 static int mt9m111_set_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9m111->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0)
+	if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
 	return 0;
@@ -672,6 +672,7 @@ static struct soc_camera_ops mt9m111_ops = {
 
 static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int ret;
 
@@ -692,6 +693,7 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
 
 static int mt9m111_get_global_gain(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	int data;
 
 	data = reg_read(GLOBAL_GAIN);
@@ -703,6 +705,7 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
 
 static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	u16 val;
 
 	if (gain > 63 * 2 * 2)
@@ -721,6 +724,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
 
 static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int ret;
 
@@ -737,6 +741,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
 
 static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int ret;
 
@@ -754,6 +759,7 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
 static int mt9m111_get_control(struct soc_camera_device *icd,
 			       struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int data;
 
@@ -898,6 +904,7 @@ static int mt9m111_release(struct soc_camera_device *icd)
  */
 static int mt9m111_video_probe(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	s32 data;
 	int ret;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 2b0927bfd21..f72aeb7c4de 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -76,64 +76,61 @@ struct mt9t031 {
 	u16 yskip;
 };
 
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	struct i2c_client *client = mt9t031->client;
 	s32 data = i2c_smbus_read_word_data(client, reg);
 	return data < 0 ? data : swab16(data);
 }
 
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data));
+	return i2c_smbus_write_word_data(client, reg, swab16(data));
 }
 
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
 		   const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret | data);
+	return reg_write(client, reg, ret | data);
 }
 
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret & ~data);
+	return reg_write(client, reg, ret & ~data);
 }
 
-static int set_shutter(struct soc_camera_device *icd, const u32 data)
+static int set_shutter(struct i2c_client *client, const u32 data)
 {
 	int ret;
 
-	ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
+	ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
 
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff);
+		ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff);
 
 	return ret;
 }
 
-static int get_shutter(struct soc_camera_device *icd, u32 *data)
+static int get_shutter(struct i2c_client *client, u32 *data)
 {
 	int ret;
 
-	ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER);
+	ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER);
 	*data = ret << 16;
 
 	if (ret >= 0)
-		ret = reg_read(icd, MT9T031_SHUTTER_WIDTH);
+		ret = reg_read(client, MT9T031_SHUTTER_WIDTH);
 	*data |= ret & 0xffff;
 
 	return ret < 0 ? ret : 0;
@@ -141,12 +138,12 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data)
 
 static int mt9t031_init(struct soc_camera_device *icd)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(icd->control);
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	if (icl->power) {
-		ret = icl->power(&mt9t031->client->dev, 1);
+		ret = icl->power(&client->dev, 1);
 		if (ret < 0) {
 			dev_err(icd->vdev->parent,
 				"Platform failed to power-on the camera.\n");
@@ -155,44 +152,48 @@ static int mt9t031_init(struct soc_camera_device *icd)
 	}
 
 	/* Disable chip output, synchronous option update */
-	ret = reg_write(icd, MT9T031_RESET, 1);
+	ret = reg_write(client, MT9T031_RESET, 1);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_RESET, 0);
+		ret = reg_write(client, MT9T031_RESET, 0);
 	if (ret >= 0)
-		ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+		ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
 
 	if (ret < 0 && icl->power)
-		icl->power(&mt9t031->client->dev, 0);
+		icl->power(&client->dev, 0);
 
 	return ret >= 0 ? 0 : -EIO;
 }
 
 static int mt9t031_release(struct soc_camera_device *icd)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(icd->control);
+	struct soc_camera_link *icl = client->dev.platform_data;
 
 	/* Disable the chip */
-	reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+	reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
 
 	if (icl->power)
-		icl->power(&mt9t031->client->dev, 0);
+		icl->power(&client->dev, 0);
 
 	return 0;
 }
 
 static int mt9t031_start_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
+
 	/* Switch to master "normal" mode */
-	if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
+	if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
 		return -EIO;
 	return 0;
 }
 
 static int mt9t031_stop_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
+
 	/* Stop sensor readout */
-	if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
+	if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
 		return -EIO;
 	return 0;
 }
@@ -200,14 +201,16 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd)
 static int mt9t031_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
+
 	/* The caller should have queried our parameters, check anyway */
 	if (flags & ~MT9T031_BUS_PARAM)
 		return -EINVAL;
 
 	if (flags & SOCAM_PCLK_SAMPLE_FALLING)
-		reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+		reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
 	else
-		reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+		reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
 
 	return 0;
 }
@@ -235,6 +238,7 @@ static void recalculate_limits(struct soc_camera_device *icd,
 static int mt9t031_set_params(struct soc_camera_device *icd,
 			      struct v4l2_rect *rect, u16 xskip, u16 yskip)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
 	int ret;
 	u16 xbin, ybin, width, height, left, top;
@@ -277,22 +281,22 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
 	}
 
 	/* Disable register update, reconfigure atomically */
-	ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1);
+	ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
 	if (ret < 0)
 		return ret;
 
 	/* Blanking and start values - default... */
-	ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
+	ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
+		ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank);
 
 	if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
 		/* Binning, skipping */
 		if (ret >= 0)
-			ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
+			ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
 					((xbin - 1) << 4) | (xskip - 1));
 		if (ret >= 0)
-			ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
+			ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
 					((ybin - 1) << 4) | (yskip - 1));
 	}
 	dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
@@ -300,16 +304,16 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
 	/* The caller provides a supported format, as guaranteed by
 	 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_COLUMN_START, left);
+		ret = reg_write(client, MT9T031_COLUMN_START, left);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_ROW_START, top);
+		ret = reg_write(client, MT9T031_ROW_START, top);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
+		ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_WINDOW_HEIGHT,
+		ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
 				height + icd->y_skip_top - 1);
 	if (ret >= 0 && mt9t031->autoexposure) {
-		ret = set_shutter(icd, height + icd->y_skip_top + vblank);
+		ret = set_shutter(client, height + icd->y_skip_top + vblank);
 		if (ret >= 0) {
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
 			const struct v4l2_queryctrl *qctrl =
@@ -324,7 +328,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
 
 	/* Re-enable register update, commit all changes */
 	if (ret >= 0)
-		ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
+		ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
 
 	return ret < 0 ? ret : 0;
 }
@@ -417,15 +421,15 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
 static int mt9t031_get_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9t031->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	reg->val = reg_read(icd, reg->reg);
+	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
 		return -EIO;
@@ -436,15 +440,15 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
 static int mt9t031_set_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9t031->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	if (reg_write(icd, reg->reg, reg->val) < 0)
+	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
 	return 0;
@@ -528,18 +532,19 @@ static struct soc_camera_ops mt9t031_ops = {
 
 static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
 	int data;
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
-		data = reg_read(icd, MT9T031_READ_MODE_2);
+		data = reg_read(client, MT9T031_READ_MODE_2);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x8000);
 		break;
 	case V4L2_CID_HFLIP:
-		data = reg_read(icd, MT9T031_READ_MODE_2);
+		data = reg_read(client, MT9T031_READ_MODE_2);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x4000);
@@ -553,6 +558,7 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
 
 static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
 	const struct v4l2_queryctrl *qctrl;
 	int data;
@@ -565,17 +571,17 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		if (ctrl->value)
-			data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000);
+			data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
 		else
-			data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000);
+			data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
 		if (data < 0)
 			return -EIO;
 		break;
 	case V4L2_CID_HFLIP:
 		if (ctrl->value)
-			data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000);
+			data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
 		else
-			data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000);
+			data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
 		if (data < 0)
 			return -EIO;
 		break;
@@ -589,7 +595,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
 
 			dev_dbg(&icd->dev, "Setting gain %d\n", data);
-			data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
+			data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
 		} else {
@@ -609,8 +615,8 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 				data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
 
 			dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
-				reg_read(icd, MT9T031_GLOBAL_GAIN), data);
-			data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
+				reg_read(client, MT9T031_GLOBAL_GAIN), data);
+			data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
 		}
@@ -628,10 +634,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 					     range / 2) / range + 1;
 			u32 old;
 
-			get_shutter(icd, &old);
+			get_shutter(client, &old);
 			dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n",
 				old, shutter);
-			if (set_shutter(icd, shutter) < 0)
+			if (set_shutter(client, shutter) < 0)
 				return -EIO;
 			icd->exposure = ctrl->value;
 			mt9t031->autoexposure = 0;
@@ -641,7 +647,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 		if (ctrl->value) {
 			const u16 vblank = MT9T031_VERTICAL_BLANK;
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
-			if (set_shutter(icd, icd->height +
+			if (set_shutter(client, icd->height +
 					icd->y_skip_top + vblank) < 0)
 				return -EIO;
 			qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -661,6 +667,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
  * this wasn't our capture interface, so, we wait for the right one */
 static int mt9t031_video_probe(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
 	s32 data;
 	int ret;
@@ -672,11 +679,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
 		return -ENODEV;
 
 	/* Enable the chip */
-	data = reg_write(icd, MT9T031_CHIP_ENABLE, 1);
+	data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
 	dev_dbg(&icd->dev, "write: %d\n", data);
 
 	/* Read out the chip version register */
-	data = reg_read(icd, MT9T031_CHIP_VERSION);
+	data = reg_read(client, MT9T031_CHIP_VERSION);
 
 	switch (data) {
 	case 0x1621:
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 412b399baca..be20d312b1d 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -91,51 +91,49 @@ struct mt9v022 {
 	u16 chip_control;
 };
 
-static int reg_read(struct soc_camera_device *icd, const u8 reg)
+static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct i2c_client *client = mt9v022->client;
 	s32 data = i2c_smbus_read_word_data(client, reg);
 	return data < 0 ? data : swab16(data);
 }
 
-static int reg_write(struct soc_camera_device *icd, const u8 reg,
+static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data));
+	return i2c_smbus_write_word_data(client, reg, swab16(data));
 }
 
-static int reg_set(struct soc_camera_device *icd, const u8 reg,
+static int reg_set(struct i2c_client *client, const u8 reg,
 		   const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret | data);
+	return reg_write(client, reg, ret | data);
 }
 
-static int reg_clear(struct soc_camera_device *icd, const u8 reg,
+static int reg_clear(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
 	int ret;
 
-	ret = reg_read(icd, reg);
+	ret = reg_read(client, reg);
 	if (ret < 0)
 		return ret;
-	return reg_write(icd, reg, ret & ~data);
+	return reg_write(client, reg, ret & ~data);
 }
 
 static int mt9v022_init(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	if (icl->power) {
-		ret = icl->power(&mt9v022->client->dev, 1);
+		ret = icl->power(&client->dev, 1);
 		if (ret < 0) {
 			dev_err(icd->vdev->parent,
 				"Platform failed to power-on the camera.\n");
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd)
 	 * if available. Soft reset is done in video_probe().
 	 */
 	if (icl->reset)
-		icl->reset(&mt9v022->client->dev);
+		icl->reset(&client->dev);
 
 	/* Almost the default mode: master, parallel, simultaneous, and an
 	 * undocumented bit 0x200, which is present in table 7, but not in 8,
 	 * plus snapshot mode to disable scan for now */
 	mt9v022->chip_control |= 0x10;
-	ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_READ_MODE, 0x300);
+		ret = reg_write(client, MT9V022_READ_MODE, 0x300);
 
 	/* All defaults */
 	if (!ret)
 		/* AEC, AGC on */
-		ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3);
+		ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
+		ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
 	if (!ret)
 		/* default - auto */
-		ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
+		ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0);
+		ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
 
 	return ret;
 }
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd)
 
 static int mt9v022_start_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
 	/* Switch to master "normal" mode */
 	mt9v022->chip_control &= ~0x10;
-	if (reg_write(icd, MT9V022_CHIP_CONTROL,
+	if (reg_write(client, MT9V022_CHIP_CONTROL,
 		      mt9v022->chip_control) < 0)
 		return -EIO;
 	return 0;
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd)
 
 static int mt9v022_stop_capture(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
 	/* Switch to snapshot mode */
 	mt9v022->chip_control |= 0x10;
-	if (reg_write(icd, MT9V022_CHIP_CONTROL,
+	if (reg_write(client, MT9V022_CHIP_CONTROL,
 		      mt9v022->chip_control) < 0)
 		return -EIO;
 	return 0;
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
 static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
 	int ret;
 	u16 pixclk = 0;
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 	if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
 		pixclk |= 0x2;
 
-	ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk);
+	ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
 	if (ret < 0)
 		return ret;
 
 	if (!(flags & SOCAM_MASTER))
 		mt9v022->chip_control &= ~0x8;
 
-	ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
 	if (ret < 0)
 		return ret;
 
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 static int mt9v022_set_crop(struct soc_camera_device *icd,
 			    struct v4l2_rect *rect)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	int ret;
 
 	/* Like in example app. Contradicts the datasheet though */
-	ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+	ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 	if (ret >= 0) {
 		if (ret & 1) /* Autoexposure */
-			ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+			ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
 					rect->height + icd->y_skip_top + 43);
 		else
-			ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH,
+			ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
 					rect->height + icd->y_skip_top + 43);
 	}
 	/* Setup frame format: defaults apart from width and height */
 	if (!ret)
-		ret = reg_write(icd, MT9V022_COLUMN_START, rect->left);
+		ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_ROW_START, rect->top);
+		ret = reg_write(client, MT9V022_ROW_START, rect->top);
 	if (!ret)
 		/* Default 94, Phytec driver says:
 		 * "width + horizontal blank >= 660" */
-		ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING,
+		ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
 				rect->width > 660 - 43 ? 43 :
 				660 - rect->width);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45);
+		ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width);
+		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
 	if (!ret)
-		ret = reg_write(icd, MT9V022_WINDOW_HEIGHT,
+		ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
 				rect->height + icd->y_skip_top);
 
 	if (ret < 0)
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
 static int mt9v022_get_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9v022->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
 	reg->size = 2;
-	reg->val = reg_read(icd, reg->reg);
+	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
 		return -EIO;
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
 static int mt9v022_set_register(struct soc_camera_device *icd,
 				struct v4l2_dbg_register *reg)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != mt9v022->client->addr)
+	if (reg->match.addr != client->addr)
 		return -ENODEV;
 
-	if (reg_write(icd, reg->reg, reg->val) < 0)
+	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
 	return 0;
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = {
 static int mt9v022_get_control(struct soc_camera_device *icd,
 			       struct v4l2_control *ctrl)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	int data;
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
-		data = reg_read(icd, MT9V022_READ_MODE);
+		data = reg_read(client, MT9V022_READ_MODE);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x10);
 		break;
 	case V4L2_CID_HFLIP:
-		data = reg_read(icd, MT9V022_READ_MODE);
+		data = reg_read(client, MT9V022_READ_MODE);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x20);
 		break;
 	case V4L2_CID_EXPOSURE_AUTO:
-		data = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x1);
 		break;
 	case V4L2_CID_AUTOGAIN:
-		data = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
+		data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 		if (data < 0)
 			return -EIO;
 		ctrl->value = !!(data & 0x2);
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			       struct v4l2_control *ctrl)
 {
 	int data;
+	struct i2c_client *client = to_i2c_client(icd->control);
 	const struct v4l2_queryctrl *qctrl;
 
 	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		if (ctrl->value)
-			data = reg_set(icd, MT9V022_READ_MODE, 0x10);
+			data = reg_set(client, MT9V022_READ_MODE, 0x10);
 		else
-			data = reg_clear(icd, MT9V022_READ_MODE, 0x10);
+			data = reg_clear(client, MT9V022_READ_MODE, 0x10);
 		if (data < 0)
 			return -EIO;
 		break;
 	case V4L2_CID_HFLIP:
 		if (ctrl->value)
-			data = reg_set(icd, MT9V022_READ_MODE, 0x20);
+			data = reg_set(client, MT9V022_READ_MODE, 0x20);
 		else
-			data = reg_clear(icd, MT9V022_READ_MODE, 0x20);
+			data = reg_clear(client, MT9V022_READ_MODE, 0x20);
 		if (data < 0)
 			return -EIO;
 		break;
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			/* The user wants to set gain manually, hope, she
 			 * knows, what she's doing... Switch AGC off. */
 
-			if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
+			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
 				return -EIO;
 
 			dev_info(&icd->dev, "Setting gain from %d to %lu\n",
-				 reg_read(icd, MT9V022_ANALOG_GAIN), gain);
-			if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0)
+				 reg_read(client, MT9V022_ANALOG_GAIN), gain);
+			if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
 				return -EIO;
 			icd->gain = ctrl->value;
 		}
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			/* The user wants to set shutter width manually, hope,
 			 * she knows, what she's doing... Switch AEC off. */
 
-			if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
+			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
 				return -EIO;
 
 			dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
-				reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH),
+				reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
 				shutter);
-			if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH,
+			if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
 				      shutter) < 0)
 				return -EIO;
 			icd->exposure = ctrl->value;
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 		break;
 	case V4L2_CID_AUTOGAIN:
 		if (ctrl->value)
-			data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2);
+			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
 		else
-			data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2);
+			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
 		if (data < 0)
 			return -EIO;
 		break;
 	case V4L2_CID_EXPOSURE_AUTO:
 		if (ctrl->value)
-			data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1);
+			data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
 		else
-			data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1);
+			data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
 		if (data < 0)
 			return -EIO;
 		break;
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
  * this wasn't our capture interface, so, we wait for the right one */
 static int mt9v022_video_probe(struct soc_camera_device *icd)
 {
+	struct i2c_client *client = to_i2c_client(icd->control);
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	struct soc_camera_link *icl = client->dev.platform_data;
 	s32 data;
 	int ret;
 	unsigned long flags;
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 		return -ENODEV;
 
 	/* Read out the chip version register */
-	data = reg_read(icd, MT9V022_CHIP_VERSION);
+	data = reg_read(client, MT9V022_CHIP_VERSION);
 
 	/* must be 0x1311 or 0x1313 */
 	if (data != 0x1311 && data != 0x1313) {
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	}
 
 	/* Soft reset */
-	ret = reg_write(icd, MT9V022_RESET, 1);
+	ret = reg_write(client, MT9V022_RESET, 1);
 	if (ret < 0)
 		goto ei2c;
 	/* 15 clock cycles */
 	udelay(200);
-	if (reg_read(icd, MT9V022_RESET)) {
+	if (reg_read(client, MT9V022_RESET)) {
 		dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
 		goto ei2c;
 	}
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	/* Set monochrome or colour sensor type */
 	if (sensor_type && (!strcmp("colour", sensor_type) ||
 			    !strcmp("color", sensor_type))) {
-		ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
+		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
 		icd->formats = mt9v022_colour_formats;
 	} else {
-		ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
+		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
 		icd->formats = mt9v022_monochrome_formats;
 	}
-- 
cgit v1.2.3-70-g09d2


From c09b77806e692d8e58c55b4f4592a855b95f13cd Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <lyakh@axis700.grange>
Date: Fri, 24 Apr 2009 12:57:42 -0300
Subject: V4L/DVB (11611): soc-camera: link host drivers after clients

With the transition of soc-camera to become a platform driver and to the
v4l2-subdev framework the initialisation order becomes important. In case
of a static build clients (i2c) drivers have to be available when host
drivers are probed. Moving host drivers down in the Makefile achieves the
desired order.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Makefile | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3f1a0350a56..7aefac64330 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -134,10 +134,6 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
 obj-$(CONFIG_VIDEO_VIVI) += vivi.o
 obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
-obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
-obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
-obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
@@ -147,6 +143,11 @@ obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
 obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
 obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
 obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
+# soc-camera host drivers have to be linked after camera drivers
+obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
+obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
+obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
+obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
-- 
cgit v1.2.3-70-g09d2


From deed75ed9f7576ada4bca02e6c851833a352a38d Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Mon, 13 Apr 2009 22:22:40 -0300
Subject: V4L/DVB (11615): cx18: Rename the work queue to "in_work_queue"

Rename the work queue to "in_work_queue" to indicate it is handling
incoming mailbox commands.  This is preparation for adding a work queue
for handling deferrable outgoing mailbox commands.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-driver.c  | 28 ++++++++++++-----------
 drivers/media/video/cx18/cx18-driver.h  |  9 ++++----
 drivers/media/video/cx18/cx18-mailbox.c | 40 ++++++++++++++++-----------------
 drivers/media/video/cx18/cx18-mailbox.h |  2 +-
 4 files changed, 41 insertions(+), 38 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 49b1c3d7b1a..79750208e04 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -562,16 +562,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
 	mutex_init(&cx->epu2apu_mb_lock);
 	mutex_init(&cx->epu2cpu_mb_lock);
 
-	cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
-	if (cx->work_queue == NULL) {
-		CX18_ERR("Unable to create work hander thread\n");
+	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
+		 cx->v4l2_dev.name);
+	cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
+	if (cx->in_work_queue == NULL) {
+		CX18_ERR("Unable to create incoming mailbox handler thread\n");
 		return -ENOMEM;
 	}
 
-	for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
-		cx->epu_work_order[i].cx = cx;
-		cx->epu_work_order[i].str = cx->epu_debug_str;
-		INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler);
+	for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
+		cx->in_work_order[i].cx = cx;
+		cx->in_work_order[i].str = cx->epu_debug_str;
+		INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
 	}
 
 	/* start counting open_id at 1 */
@@ -944,7 +946,7 @@ free_map:
 free_mem:
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 free_workqueue:
-	destroy_workqueue(cx->work_queue);
+	destroy_workqueue(cx->in_work_queue);
 err:
 	if (retval == 0)
 		retval = -ENODEV;
@@ -1053,11 +1055,11 @@ int cx18_init_on_first_open(struct cx18 *cx)
 	return 0;
 }
 
-static void cx18_cancel_epu_work_orders(struct cx18 *cx)
+static void cx18_cancel_in_work_orders(struct cx18 *cx)
 {
 	int i;
-	for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
-		cancel_work_sync(&cx->epu_work_order[i].work);
+	for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
+		cancel_work_sync(&cx->in_work_order[i].work);
 }
 
 static void cx18_remove(struct pci_dev *pci_dev)
@@ -1079,9 +1081,9 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
 	cx18_halt_firmware(cx);
 
-	cx18_cancel_epu_work_orders(cx);
+	cx18_cancel_in_work_orders(cx);
 
-	destroy_workqueue(cx->work_queue);
+	destroy_workqueue(cx->in_work_queue);
 
 	cx18_streams_cleanup(cx, 1);
 
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index ece4f281ef4..e6f42d0cb2b 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -305,7 +305,7 @@ struct cx18_scb; /* forward reference */
 
 
 #define CX18_MAX_MDL_ACKS 2
-#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
+#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
 /* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
 
 #define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
@@ -313,7 +313,7 @@ struct cx18_scb; /* forward reference */
 #define CX18_F_EWO_MB_STALE \
 	     (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
 
-struct cx18_epu_work_order {
+struct cx18_in_work_order {
 	struct work_struct work;
 	atomic_t pending;
 	struct cx18 *cx;
@@ -568,8 +568,9 @@ struct cx18 {
 	u32 sw2_irq_mask;
 	u32 hw2_irq_mask;
 
-	struct workqueue_struct *work_queue;
-	struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS];
+	struct workqueue_struct *in_work_queue;
+	char in_workq_name[11]; /* "cx18-NN-in" */
+	struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
 	char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
 
 	/* i2c */
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2226e5791e9..2a4d4356d1b 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
  * Functions that run in a work_queue work handling context
  */
 
-static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 handle, mdl_ack_count, id;
 	struct cx18_mailbox *mb;
@@ -213,7 +213,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
 		wake_up(&s->waitq);
 }
 
-static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	char *p;
 	char *str = order->str;
@@ -224,7 +224,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
 		CX18_INFO("FW version: %s\n", p - 1);
 }
 
-static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	switch (order->rpu) {
 	case CPU:
@@ -253,18 +253,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
 }
 
 static
-void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order)
+void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	atomic_set(&order->pending, 0);
 }
 
-void cx18_epu_work_handler(struct work_struct *work)
+void cx18_in_work_handler(struct work_struct *work)
 {
-	struct cx18_epu_work_order *order =
-			container_of(work, struct cx18_epu_work_order, work);
+	struct cx18_in_work_order *order =
+			container_of(work, struct cx18_in_work_order, work);
 	struct cx18 *cx = order->cx;
 	epu_cmd(cx, order);
-	free_epu_work_order(cx, order);
+	free_in_work_order(cx, order);
 }
 
 
@@ -272,7 +272,7 @@ void cx18_epu_work_handler(struct work_struct *work)
  * Functions that run in an interrupt handling context
  */
 
-static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	struct cx18_mailbox __iomem *ack_mb;
 	u32 ack_irq, req;
@@ -308,7 +308,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
 	return;
 }
 
-static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 handle, mdl_ack_offset, mdl_ack_count;
 	struct cx18_mailbox *mb;
@@ -334,7 +334,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
 }
 
 static
-int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 str_offset;
 	char *str = order->str;
@@ -355,7 +355,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
 }
 
 static inline
-int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
+int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	int ret = -1;
 
@@ -387,12 +387,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
 }
 
 static inline
-struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
+struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
 {
 	int i;
-	struct cx18_epu_work_order *order = NULL;
+	struct cx18_in_work_order *order = NULL;
 
-	for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
+	for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
 		/*
 		 * We only need "pending" atomic to inspect its contents,
 		 * and need not do a check and set because:
@@ -401,8 +401,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
 		 * 2. "pending" is only set here, and we're serialized because
 		 * we're called in an IRQ handler context.
 		 */
-		if (atomic_read(&cx->epu_work_order[i].pending) == 0) {
-			order = &cx->epu_work_order[i];
+		if (atomic_read(&cx->in_work_order[i].pending) == 0) {
+			order = &cx->in_work_order[i];
 			atomic_set(&order->pending, 1);
 			break;
 		}
@@ -414,7 +414,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
 {
 	struct cx18_mailbox __iomem *mb;
 	struct cx18_mailbox *order_mb;
-	struct cx18_epu_work_order *order;
+	struct cx18_in_work_order *order;
 	int submit;
 
 	switch (rpu) {
@@ -428,7 +428,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
 		return;
 	}
 
-	order = alloc_epu_work_order_irq(cx);
+	order = alloc_in_work_order_irq(cx);
 	if (order == NULL) {
 		CX18_WARN("Unable to find blank work order form to schedule "
 			  "incoming mailbox command processing\n");
@@ -461,7 +461,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
 	 */
 	submit = epu_cmd_irq(cx, order);
 	if (submit > 0) {
-		queue_work(cx->work_queue, &order->work);
+		queue_work(cx->in_work_queue, &order->work);
 	}
 }
 
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index ce2b6686aa0..e23aaac5b28 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out,
 
 void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
 
-void cx18_epu_work_handler(struct work_struct *work);
+void cx18_in_work_handler(struct work_struct *work);
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 87116159517ecf6b9cf62a136f2935a63833c485 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Mon, 13 Apr 2009 22:42:43 -0300
Subject: V4L/DVB (11616): cx18: Add a work queue for deferring empty buffer
 handoffs to the firmware

This change defers sending all CX18_CPU_DE_SET_MDL commands, for a stream with
an ongoing capture, by adding a work queue to handle sending such commands when
needed.  This prevents any sleeps, caused by notifying the firmware of new
usable buffers, when a V4L2 application read() is being satisfied or when
an incoming buffer is processed by the cx18-NN-in work queue thread.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-driver.c  | 92 +++++++++++++++++++++++-------
 drivers/media/video/cx18/cx18-driver.h  | 32 +++++++++++
 drivers/media/video/cx18/cx18-streams.c | 99 +++++++++++++++++++++++++++++++--
 drivers/media/video/cx18/cx18-streams.h |  5 +-
 4 files changed, 202 insertions(+), 26 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 79750208e04..658cfbb1b97 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -546,6 +546,47 @@ done:
 	cx->card_i2c = cx->card->i2c;
 }
 
+static int __devinit cx18_create_in_workq(struct cx18 *cx)
+{
+	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
+		 cx->v4l2_dev.name);
+	cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
+	if (cx->in_work_queue == NULL) {
+		CX18_ERR("Unable to create incoming mailbox handler thread\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int __devinit cx18_create_out_workq(struct cx18 *cx)
+{
+	snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
+		 cx->v4l2_dev.name);
+	cx->out_work_queue = create_workqueue(cx->out_workq_name);
+	if (cx->out_work_queue == NULL) {
+		CX18_ERR("Unable to create outgoing mailbox handler threads\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
+{
+	int i;
+	for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
+		cx->in_work_order[i].cx = cx;
+		cx->in_work_order[i].str = cx->epu_debug_str;
+		INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
+	}
+}
+
+static void __devinit cx18_init_out_work_orders(struct cx18 *cx)
+{
+	int i;
+	for (i = 0; i < CX18_MAX_OUT_WORK_ORDERS; i++)
+		INIT_WORK(&cx->out_work_order[i].work, cx18_out_work_handler);
+}
+
 /* Precondition: the cx18 structure has been memset to 0. Only
    the dev and instance fields have been filled in.
    No assumptions on the card type may be made here (see cx18_init_struct2
@@ -553,7 +594,7 @@ done:
  */
 static int __devinit cx18_init_struct1(struct cx18 *cx)
 {
-	int i;
+	int ret;
 
 	cx->base_addr = pci_resource_start(cx->pci_dev, 0);
 
@@ -562,20 +603,19 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
 	mutex_init(&cx->epu2apu_mb_lock);
 	mutex_init(&cx->epu2cpu_mb_lock);
 
-	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
-		 cx->v4l2_dev.name);
-	cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
-	if (cx->in_work_queue == NULL) {
-		CX18_ERR("Unable to create incoming mailbox handler thread\n");
-		return -ENOMEM;
-	}
+	ret = cx18_create_out_workq(cx);
+	if (ret)
+		return ret;
 
-	for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
-		cx->in_work_order[i].cx = cx;
-		cx->in_work_order[i].str = cx->epu_debug_str;
-		INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
+	ret = cx18_create_in_workq(cx);
+	if (ret) {
+		destroy_workqueue(cx->out_work_queue);
+		return ret;
 	}
 
+	cx18_init_out_work_orders(cx);
+	cx18_init_in_work_orders(cx);
+
 	/* start counting open_id at 1 */
 	cx->open_id = 1;
 
@@ -761,17 +801,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
 		retval = -ENODEV;
 		goto err;
 	}
-	if (cx18_init_struct1(cx)) {
-		retval = -ENOMEM;
+
+	retval = cx18_init_struct1(cx);
+	if (retval)
 		goto err;
-	}
 
 	CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
 
 	/* PCI Device Setup */
 	retval = cx18_setup_pci(cx, pci_dev, pci_id);
 	if (retval != 0)
-		goto free_workqueue;
+		goto free_workqueues;
 
 	/* map io memory */
 	CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -945,8 +985,9 @@ free_map:
 	cx18_iounmap(cx);
 free_mem:
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
-free_workqueue:
+free_workqueues:
 	destroy_workqueue(cx->in_work_queue);
+	destroy_workqueue(cx->out_work_queue);
 err:
 	if (retval == 0)
 		retval = -ENODEV;
@@ -1075,15 +1116,26 @@ static void cx18_remove(struct pci_dev *pci_dev)
 	if (atomic_read(&cx->tot_capturing) > 0)
 		cx18_stop_all_captures(cx);
 
-	/* Interrupts */
+	/* Stop interrupts that cause incoming work to be queued */
 	cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
+
+	/* Incoming work can cause outgoing work, so clean up incoming first */
+	cx18_cancel_in_work_orders(cx);
+
+	/*
+	 * An outgoing work order can have the only pointer to a dynamically
+	 * allocated buffer, so we need to flush outgoing work and not just
+	 * cancel it, so we don't lose the pointer and leak memory.
+	 */
+	flush_workqueue(cx->out_work_queue);
+
+	/* Stop ack interrupts that may have been needed for work to finish */
 	cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
 
 	cx18_halt_firmware(cx);
 
-	cx18_cancel_in_work_orders(cx);
-
 	destroy_workqueue(cx->in_work_queue);
+	destroy_workqueue(cx->out_work_queue);
 
 	cx18_streams_cleanup(cx, 1);
 
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index e6f42d0cb2b..62dca432fdb 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -254,6 +254,7 @@ struct cx18_options {
 #define CX18_F_S_INTERNAL_USE	5	/* this stream is used internally (sliced VBI processing) */
 #define CX18_F_S_STREAMOFF	7	/* signal end of stream EOS */
 #define CX18_F_S_APPL_IO        8	/* this stream is used read/written by an application */
+#define CX18_F_S_STOPPING	9	/* telling the fw to stop capturing */
 
 /* per-cx18, i_flags */
 #define CX18_F_I_LOADED_FW		0 	/* Loaded firmware 1st time */
@@ -324,6 +325,33 @@ struct cx18_in_work_order {
 	char *str;
 };
 
+/*
+ * There are 2 types of deferrable tasks that send messages out to the firmware:
+ * 1. Sending individual buffers back to the firmware
+ * 2. Sending as many free buffers for a stream from q_free as we can to the fw
+ *
+ * The worst case scenario for multiple simultaneous streams is
+ * TS, YUV, PCM, VBI, MPEG, and IDX all going at once.
+ *
+ * We try to load the firmware queue with as many free buffers as possible,
+ * whenever we get a buffer back for a stream.  For the TS we return the single
+ * buffer to the firmware at that time as well.  For all other streams, we
+ * return single buffers to the firmware as the application drains them.
+ *
+ * 6 streams * 2 sets of orders * (1 single buf + 1 load fw from q_free)
+ * = 24 work orders should cover our needs, provided the applications read
+ * at a fairly steady rate.  If apps don't, we fall back to non-deferred
+ * operation, when no cx18_out_work_orders are available for use.
+ */
+#define CX18_MAX_OUT_WORK_ORDERS (24)
+
+struct cx18_out_work_order {
+	struct work_struct work;
+	atomic_t pending;
+	struct cx18_stream *s;
+	struct cx18_buffer *buf; /* buf == NULL, means load fw from q_free */
+};
+
 #define CX18_INVALID_TASK_HANDLE 0xffffffff
 
 struct cx18_stream {
@@ -573,6 +601,10 @@ struct cx18 {
 	struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
 	char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
 
+	struct workqueue_struct *out_work_queue;
+	char out_workq_name[12]; /* "cx18-NN-out" */
+	struct cx18_out_work_order out_work_order[CX18_MAX_OUT_WORK_ORDERS];
+
 	/* i2c */
 	struct i2c_adapter i2c_adap[2];
 	struct i2c_algo_bit_data i2c_algo[2];
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 0932b76b237..bbeb01c5cf3 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -431,14 +431,16 @@ static void cx18_vbi_setup(struct cx18_stream *s)
 	cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
 }
 
-struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
-					  struct cx18_buffer *buf)
+static
+struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
+					   struct cx18_buffer *buf)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_queue *q;
 
 	/* Don't give it to the firmware, if we're not running a capture */
 	if (s->handle == CX18_INVALID_TASK_HANDLE ||
+	    test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
 	    !test_bit(CX18_F_S_STREAMING, &s->s_flags))
 		return cx18_enqueue(s, buf, &s->q_free);
 
@@ -453,7 +455,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
 	return q;
 }
 
-void cx18_stream_load_fw_queue(struct cx18_stream *s)
+static
+void _cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 	struct cx18_queue *q;
 	struct cx18_buffer *buf;
@@ -467,11 +470,93 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s)
 		buf = cx18_dequeue(s, &s->q_free);
 		if (buf == NULL)
 			break;
-		q = cx18_stream_put_buf_fw(s, buf);
+		q = _cx18_stream_put_buf_fw(s, buf);
 	} while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
 		 && q == &s->q_busy);
 }
 
+static inline
+void free_out_work_order(struct cx18_out_work_order *order)
+{
+	atomic_set(&order->pending, 0);
+}
+
+void cx18_out_work_handler(struct work_struct *work)
+{
+	struct cx18_out_work_order *order =
+			container_of(work, struct cx18_out_work_order, work);
+	struct cx18_stream *s = order->s;
+	struct cx18_buffer *buf = order->buf;
+
+	free_out_work_order(order);
+
+	if (buf == NULL)
+		_cx18_stream_load_fw_queue(s);
+	else
+		_cx18_stream_put_buf_fw(s, buf);
+}
+
+static
+struct cx18_out_work_order *alloc_out_work_order(struct cx18 *cx)
+{
+	int i;
+	struct cx18_out_work_order *order = NULL;
+
+	for (i = 0; i < CX18_MAX_OUT_WORK_ORDERS; i++) {
+		/*
+		 * We need "pending" to be atomic to inspect & set its contents
+		 * 1. "pending" is only set to 1 here, but needs multiple access
+		 * protection
+		 * 2. work handler threads only clear "pending" and only
+		 * on one, particular work order at a time, per handler thread.
+		 */
+		if (atomic_add_unless(&cx->out_work_order[i].pending, 1, 1)) {
+			order = &cx->out_work_order[i];
+			break;
+		}
+	}
+	return order;
+}
+
+struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
+					  struct cx18_buffer *buf)
+{
+	struct cx18 *cx = s->cx;
+	struct cx18_out_work_order *order;
+
+	order = alloc_out_work_order(cx);
+	if (order == NULL) {
+		CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
+				"order forms available; sending buffer %u back "
+				"to the firmware immediately for stream %s\n",
+				buf->id, s->name);
+		return _cx18_stream_put_buf_fw(s, buf);
+	}
+	order->s = s;
+	order->buf = buf;
+	queue_work(cx->out_work_queue, &order->work);
+	return NULL;
+}
+
+void cx18_stream_load_fw_queue(struct cx18_stream *s)
+{
+	struct cx18 *cx = s->cx;
+	struct cx18_out_work_order *order;
+
+	order = alloc_out_work_order(cx);
+	if (order == NULL) {
+		CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
+				"order forms available; filling the firmware "
+				"buffer queue immediately for stream %s\n",
+				s->name);
+		_cx18_stream_load_fw_queue(s);
+		return;
+	}
+	order->s = s;
+	order->buf = NULL; /* Indicates to load the fw queue */
+	queue_work(cx->out_work_queue, &order->work);
+}
+
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 {
 	u32 data[MAX_MB_ARGUMENTS];
@@ -607,12 +692,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 		cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
 	}
 	mutex_unlock(&s->qlock);
-	cx18_stream_load_fw_queue(s);
+	_cx18_stream_load_fw_queue(s);
 
 	/* begin_capture */
 	if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
 		CX18_DEBUG_WARN("Error starting capture!\n");
 		/* Ensure we're really not capturing before releasing MDLs */
+		set_bit(CX18_F_S_STOPPING, &s->s_flags);
 		if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 			cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
 		else
@@ -622,6 +708,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 		cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
 		cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
 		s->handle = CX18_INVALID_TASK_HANDLE;
+		clear_bit(CX18_F_S_STOPPING, &s->s_flags);
 		if (atomic_read(&cx->tot_capturing) == 0) {
 			set_bit(CX18_F_I_EOS, &cx->i_flags);
 			cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
@@ -666,6 +753,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
 	if (atomic_read(&cx->tot_capturing) == 0)
 		return 0;
 
+	set_bit(CX18_F_S_STOPPING, &s->s_flags);
 	if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 		cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
 	else
@@ -689,6 +777,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
 
 	cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
 	s->handle = CX18_INVALID_TASK_HANDLE;
+	clear_bit(CX18_F_S_STOPPING, &s->s_flags);
 
 	if (atomic_read(&cx->tot_capturing) > 0)
 		return 0;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 420e0a17294..1fdcfffb07e 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,10 +28,13 @@ int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
 void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
-/* Capture related */
+/* Related to submission of buffers to firmware */
 void cx18_stream_load_fw_queue(struct cx18_stream *s);
 struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
 					  struct cx18_buffer *buf);
+void cx18_out_work_handler(struct work_struct *work);
+
+/* Capture related */
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
 int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
 
-- 
cgit v1.2.3-70-g09d2


From 5f0a3cfcfd315d87de8f80af49b114daf7137823 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Mon, 13 Apr 2009 22:53:09 -0300
Subject: V4L/DVB (11617): cx18: Set up to wait for a one-shot response before
 sending a firmware cmd

When sending an outgoing firmware command, prepare to wait before we raise the
interrupt, so we don't miss the wake_up() on the acknowledgment.  When waiting
for the acknowledgement, there is no need to loop around schedule(), as there
will only be one interrupt, and hence one wake_up(), issued.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-mailbox.c | 49 +++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 12 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2a4d4356d1b..df7d61d0a13 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -478,9 +478,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
 	u32 __iomem *xpu_state;
 	wait_queue_head_t *waitq;
 	struct mutex *mb_lock;
-	long int timeout, ret;
+	unsigned long int t0, timeout, ret;
 	int i;
 	char argstr[MAX_MB_ARGUMENTS*11+1];
+	DEFINE_WAIT(w);
 
 	if (info == NULL) {
 		CX18_WARN("unknown cmd %x\n", cmd);
@@ -562,25 +563,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
 
 	CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
 			  irq, info->name);
+
+	/* So we don't miss the wakeup, prepare to wait before notifying fw */
+	prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
 	cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
 
-	ret = wait_event_timeout(
-		       *waitq,
-		       cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request),
-		       timeout);
+	t0 = jiffies;
+	ack = cx18_readl(cx, &mb->ack);
+	if (ack != req) {
+		schedule_timeout(timeout);
+		ret = jiffies - t0;
+		ack = cx18_readl(cx, &mb->ack);
+	} else {
+		ret = jiffies - t0;
+	}
+
+	finish_wait(waitq, &w);
 
-	if (ret == 0) {
-		/* Timed out */
+	if (req != ack) {
 		mutex_unlock(mb_lock);
-		CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU "
-				"acknowledgement\n",
-				info->name, jiffies_to_msecs(timeout));
+		if (ret >= timeout) {
+			/* Timed out */
+			CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
+					"for RPU acknowledgement\n",
+					info->name, jiffies_to_msecs(ret));
+		} else {
+			CX18_DEBUG_WARN("woken up before mailbox ack was ready "
+					"after submitting %s to RPU.  only "
+					"waited %d msecs on req %u but awakened"
+					" with unmatched ack %u\n",
+					info->name,
+					jiffies_to_msecs(ret),
+					req, ack);
+		}
 		return -EINVAL;
 	}
 
-	if (ret != timeout)
+	if (ret >= timeout)
+		CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
+				"sending %s; timed out waiting %d msecs\n",
+				info->name, jiffies_to_msecs(ret));
+	else
 		CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
-				  jiffies_to_msecs(timeout-ret), info->name);
+				  jiffies_to_msecs(ret), info->name);
 
 	/* Collect data returned by the XPU */
 	for (i = 0; i < MAX_MB_ARGUMENTS; i++)
-- 
cgit v1.2.3-70-g09d2


From 40c5520f55924ba87090d0d93222baad74202559 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Mon, 13 Apr 2009 23:08:00 -0300
Subject: V4L/DVB (11618): cx18: Convert per stream mutex locks to per queue
 spin locks

To avoid sleeps in providing buffers to user space and in handling incoming
buffers from the capture unit, converted the per stream mutex for locking
queues to 3 spin locks.  There is now a spin lock per queue
to increase concurrency when moving buffers around.

Also simplified queue manipulations and buffer handling of incoming buffers
of data from the capture unit.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-driver.h  |  2 +-
 drivers/media/video/cx18/cx18-mailbox.c | 25 +++++-----
 drivers/media/video/cx18/cx18-queue.c   | 83 ++++++++++++++++++++-------------
 drivers/media/video/cx18/cx18-streams.c |  8 ++--
 4 files changed, 69 insertions(+), 49 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 62dca432fdb..35a6758a7aa 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -286,6 +286,7 @@ struct cx18_queue {
 	struct list_head list;
 	atomic_t buffers;
 	u32 bytesused;
+	spinlock_t lock;
 };
 
 struct cx18_dvb {
@@ -365,7 +366,6 @@ struct cx18_stream {
 	unsigned mdl_offset;
 
 	u32 id;
-	struct mutex qlock; 	/* locks access to the queues */
 	unsigned long s_flags;	/* status flags, see above */
 	int dma;		/* can be PCI_DMA_TODEVICE,
 				   PCI_DMA_FROMDEVICE or
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index df7d61d0a13..afe46c3d405 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -191,23 +191,24 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
 		if (buf == NULL) {
 			CX18_WARN("Could not find buf %d for stream %s\n",
 				  id, s->name);
-			/* Put as many buffers as possible back into fw use */
-			cx18_stream_load_fw_queue(s);
 			continue;
 		}
 
-		if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
-			CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
-					  buf->bytesused);
-			dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
-					 buf->bytesused);
+		CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
+				  s->name, buf->bytesused);
+
+		if (s->type != CX18_ENC_STREAM_TYPE_TS)
+			cx18_enqueue(s, buf, &s->q_full);
+		else {
+			if (s->dvb.enabled)
+				dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
+						 buf->bytesused);
+			cx18_enqueue(s, buf, &s->q_free);
 		}
-		/* Put as many buffers as possible back into fw use */
-		cx18_stream_load_fw_queue(s);
-		/* Put back TS buffer, since it was removed from all queues */
-		if (s->type == CX18_ENC_STREAM_TYPE_TS)
-			cx18_stream_put_buf_fw(s, buf);
 	}
+	/* Put as many buffers as possible back into fw use */
+	cx18_stream_load_fw_queue(s);
+
 	wake_up(&cx->dma_waitq);
 	if (s->id != -1)
 		wake_up(&s->waitq);
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 3046b8e7434..693a745b085 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 		buf->skipped = 0;
 	}
 
-	mutex_lock(&s->qlock);
-
 	/* q_busy is restricted to a max buffer count imposed by firmware */
 	if (q == &s->q_busy &&
 	    atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
 		q = &s->q_free;
 
+	spin_lock(&q->lock);
+
 	if (to_front)
 		list_add(&buf->list, &q->list); /* LIFO */
 	else
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 	q->bytesused += buf->bytesused - buf->readpos;
 	atomic_inc(&q->buffers);
 
-	mutex_unlock(&s->qlock);
+	spin_unlock(&q->lock);
 	return q;
 }
 
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
 {
 	struct cx18_buffer *buf = NULL;
 
-	mutex_lock(&s->qlock);
+	spin_lock(&q->lock);
 	if (!list_empty(&q->list)) {
 		buf = list_first_entry(&q->list, struct cx18_buffer, list);
 		list_del_init(&buf->list);
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
 		buf->skipped = 0;
 		atomic_dec(&q->buffers);
 	}
-	mutex_unlock(&s->qlock);
+	spin_unlock(&q->lock);
 	return buf;
 }
 
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
 	struct cx18_buffer *buf;
 	struct cx18_buffer *tmp;
 	struct cx18_buffer *ret = NULL;
-
-	mutex_lock(&s->qlock);
+	LIST_HEAD(sweep_up);
+
+	/*
+	 * We don't have to acquire multiple q locks here, because we are
+	 * serialized by the single threaded work handler.
+	 * Buffers from the firmware will thus remain in order as
+	 * they are moved from q_busy to q_full or to the dvb ring buffer.
+	 */
+	spin_lock(&s->q_busy.lock);
 	list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
+		/*
+		 * We should find what the firmware told us is done,
+		 * right at the front of the queue.  If we don't, we likely have
+		 * missed a buffer done message from the firmware.
+		 * Once we skip a buffer repeatedly, relative to the size of
+		 * q_busy, we have high confidence we've missed it.
+		 */
 		if (buf->id != id) {
 			buf->skipped++;
 			if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
 					  "times - it must have dropped out of "
 					  "rotation\n", s->name, buf->id,
 					  buf->skipped);
-				/* move it to q_free */
-				list_move_tail(&buf->list, &s->q_free.list);
-				buf->bytesused = buf->readpos = buf->b_flags =
-					buf->skipped = 0;
+				/* Sweep it up to put it back into rotation */
+				list_move_tail(&buf->list, &sweep_up);
 				atomic_dec(&s->q_busy.buffers);
-				atomic_inc(&s->q_free.buffers);
 			}
 			continue;
 		}
-
-		buf->bytesused = bytesused;
-		/* Sync the buffer before we release the qlock */
-		cx18_buf_sync_for_cpu(s, buf);
-		if (s->type == CX18_ENC_STREAM_TYPE_TS) {
-			/*
-			 * TS doesn't use q_full.  As we pull the buffer off of
-			 * the queue here, the caller will have to put it back.
-			 */
-			list_del_init(&buf->list);
-		} else {
-			/* Move buffer from q_busy to q_full */
-			list_move_tail(&buf->list, &s->q_full.list);
-			set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
-			s->q_full.bytesused += buf->bytesused;
-			atomic_inc(&s->q_full.buffers);
-		}
+		/*
+		 * We pull the desired buffer off of the queue here.  Something
+		 * will have to put it back on a queue later.
+		 */
+		list_del_init(&buf->list);
 		atomic_dec(&s->q_busy.buffers);
-
 		ret = buf;
 		break;
 	}
-	mutex_unlock(&s->qlock);
+	spin_unlock(&s->q_busy.lock);
+
+	/*
+	 * We found the buffer for which we were looking.  Get it ready for
+	 * the caller to put on q_full or in the dvb ring buffer.
+	 */
+	if (ret != NULL) {
+		ret->bytesused = bytesused;
+		ret->skipped = 0;
+		/* readpos and b_flags were 0'ed when the buf went on q_busy */
+		cx18_buf_sync_for_cpu(s, ret);
+		if (s->type != CX18_ENC_STREAM_TYPE_TS)
+			set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
+	}
+
+	/* Put any buffers the firmware is ignoring back into normal rotation */
+	list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
+		list_del_init(&buf->list);
+		cx18_enqueue(s, buf, &s->q_free);
+	}
 	return ret;
 }
 
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
 	if (q == &s->q_free)
 		return;
 
-	mutex_lock(&s->qlock);
+	spin_lock(&q->lock);
 	while (!list_empty(&q->list)) {
 		buf = list_first_entry(&q->list, struct cx18_buffer, list);
 		list_move_tail(&buf->list, &s->q_free.list);
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
 		atomic_inc(&s->q_free.buffers);
 	}
 	cx18_queue_init(q);
-	mutex_unlock(&s->qlock);
+	spin_unlock(&q->lock);
 }
 
 void cx18_flush_queues(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index bbeb01c5cf3..e1934e9cfdc 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -116,11 +116,13 @@ static void cx18_stream_init(struct cx18 *cx, int type)
 	s->buffers = cx->stream_buffers[type];
 	s->buf_size = cx->stream_buf_size[type];
 
-	mutex_init(&s->qlock);
 	init_waitqueue_head(&s->waitq);
 	s->id = -1;
+	spin_lock_init(&s->q_free.lock);
 	cx18_queue_init(&s->q_free);
+	spin_lock_init(&s->q_busy.lock);
 	cx18_queue_init(&s->q_busy);
+	spin_lock_init(&s->q_full.lock);
 	cx18_queue_init(&s->q_full);
 }
 
@@ -685,13 +687,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 
 	/* Init all the cpu_mdls for this stream */
 	cx18_flush_queues(s);
-	mutex_lock(&s->qlock);
+	spin_lock(&s->q_free.lock);
 	list_for_each_entry(buf, &s->q_free.list, list) {
 		cx18_writel(cx, buf->dma_handle,
 					&cx->scb->cpu_mdl[buf->id].paddr);
 		cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
 	}
-	mutex_unlock(&s->qlock);
+	spin_unlock(&s->q_free.lock);
 	_cx18_stream_load_fw_queue(s);
 
 	/* begin_capture */
-- 
cgit v1.2.3-70-g09d2


From 21a278b85d3c6b8064af0c03aec3205e28aad3b7 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Wed, 15 Apr 2009 20:45:10 -0300
Subject: V4L/DVB (11619): cx18: Simplify the work handler for outgoing mailbox
 commands

Simplify the way outgoing work handler gets scheduled to send empty buffers
back to the firmware for use.  Also reduced the memory required for scheduling
this outgoing work, by using a single, per stream work object.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-driver.c  | 25 ++++------
 drivers/media/video/cx18/cx18-driver.h  | 30 +-----------
 drivers/media/video/cx18/cx18-dvb.c     |  1 +
 drivers/media/video/cx18/cx18-queue.c   |  2 +-
 drivers/media/video/cx18/cx18-streams.c | 82 ++-------------------------------
 drivers/media/video/cx18/cx18-streams.h | 17 +++++--
 6 files changed, 33 insertions(+), 124 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 658cfbb1b97..f0006edc635 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -30,6 +30,7 @@
 #include "cx18-irq.h"
 #include "cx18-gpio.h"
 #include "cx18-firmware.h"
+#include "cx18-queue.h"
 #include "cx18-streams.h"
 #include "cx18-av-core.h"
 #include "cx18-scb.h"
@@ -580,13 +581,6 @@ static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
 	}
 }
 
-static void __devinit cx18_init_out_work_orders(struct cx18 *cx)
-{
-	int i;
-	for (i = 0; i < CX18_MAX_OUT_WORK_ORDERS; i++)
-		INIT_WORK(&cx->out_work_order[i].work, cx18_out_work_handler);
-}
-
 /* Precondition: the cx18 structure has been memset to 0. Only
    the dev and instance fields have been filled in.
    No assumptions on the card type may be made here (see cx18_init_struct2
@@ -613,7 +607,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
 		return ret;
 	}
 
-	cx18_init_out_work_orders(cx);
 	cx18_init_in_work_orders(cx);
 
 	/* start counting open_id at 1 */
@@ -1103,6 +1096,14 @@ static void cx18_cancel_in_work_orders(struct cx18 *cx)
 		cancel_work_sync(&cx->in_work_order[i].work);
 }
 
+static void cx18_cancel_out_work_orders(struct cx18 *cx)
+{
+	int i;
+	for (i = 0; i < CX18_MAX_STREAMS; i++)
+		if (&cx->streams[i].video_dev != NULL)
+			cancel_work_sync(&cx->streams[i].out_work_order);
+}
+
 static void cx18_remove(struct pci_dev *pci_dev)
 {
 	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
@@ -1121,13 +1122,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
 	/* Incoming work can cause outgoing work, so clean up incoming first */
 	cx18_cancel_in_work_orders(cx);
-
-	/*
-	 * An outgoing work order can have the only pointer to a dynamically
-	 * allocated buffer, so we need to flush outgoing work and not just
-	 * cancel it, so we don't lose the pointer and leak memory.
-	 */
-	flush_workqueue(cx->out_work_queue);
+	cx18_cancel_out_work_orders(cx);
 
 	/* Stop ack interrupts that may have been needed for work to finish */
 	cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 35a6758a7aa..f89b8236796 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -326,33 +326,6 @@ struct cx18_in_work_order {
 	char *str;
 };
 
-/*
- * There are 2 types of deferrable tasks that send messages out to the firmware:
- * 1. Sending individual buffers back to the firmware
- * 2. Sending as many free buffers for a stream from q_free as we can to the fw
- *
- * The worst case scenario for multiple simultaneous streams is
- * TS, YUV, PCM, VBI, MPEG, and IDX all going at once.
- *
- * We try to load the firmware queue with as many free buffers as possible,
- * whenever we get a buffer back for a stream.  For the TS we return the single
- * buffer to the firmware at that time as well.  For all other streams, we
- * return single buffers to the firmware as the application drains them.
- *
- * 6 streams * 2 sets of orders * (1 single buf + 1 load fw from q_free)
- * = 24 work orders should cover our needs, provided the applications read
- * at a fairly steady rate.  If apps don't, we fall back to non-deferred
- * operation, when no cx18_out_work_orders are available for use.
- */
-#define CX18_MAX_OUT_WORK_ORDERS (24)
-
-struct cx18_out_work_order {
-	struct work_struct work;
-	atomic_t pending;
-	struct cx18_stream *s;
-	struct cx18_buffer *buf; /* buf == NULL, means load fw from q_free */
-};
-
 #define CX18_INVALID_TASK_HANDLE 0xffffffff
 
 struct cx18_stream {
@@ -381,6 +354,8 @@ struct cx18_stream {
 	struct cx18_queue q_busy;	/* busy buffers - in use by firmware */
 	struct cx18_queue q_full;	/* full buffers - data for user apps */
 
+	struct work_struct out_work_order;
+
 	/* DVB / Digital Transport */
 	struct cx18_dvb dvb;
 };
@@ -603,7 +578,6 @@ struct cx18 {
 
 	struct workqueue_struct *out_work_queue;
 	char out_workq_name[12]; /* "cx18-NN-out" */
-	struct cx18_out_work_order out_work_order[CX18_MAX_OUT_WORK_ORDERS];
 
 	/* i2c */
 	struct i2c_adapter i2c_adap[2];
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 3b86f57cd15..e7285a1096f 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -23,6 +23,7 @@
 #include "cx18-version.h"
 #include "cx18-dvb.h"
 #include "cx18-io.h"
+#include "cx18-queue.h"
 #include "cx18-streams.h"
 #include "cx18-cards.h"
 #include "s5h1409.h"
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 693a745b085..fa1ed7897d9 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -23,8 +23,8 @@
  */
 
 #include "cx18-driver.h"
-#include "cx18-streams.h"
 #include "cx18-queue.h"
+#include "cx18-streams.h"
 #include "cx18-scb.h"
 
 void cx18_buf_swap(struct cx18_buffer *buf)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index e1934e9cfdc..41a1b2618aa 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -124,6 +124,8 @@ static void cx18_stream_init(struct cx18 *cx, int type)
 	cx18_queue_init(&s->q_busy);
 	spin_lock_init(&s->q_full.lock);
 	cx18_queue_init(&s->q_full);
+
+	INIT_WORK(&s->out_work_order, cx18_out_work_handler);
 }
 
 static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -477,86 +479,12 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s)
 		 && q == &s->q_busy);
 }
 
-static inline
-void free_out_work_order(struct cx18_out_work_order *order)
-{
-	atomic_set(&order->pending, 0);
-}
-
 void cx18_out_work_handler(struct work_struct *work)
 {
-	struct cx18_out_work_order *order =
-			container_of(work, struct cx18_out_work_order, work);
-	struct cx18_stream *s = order->s;
-	struct cx18_buffer *buf = order->buf;
-
-	free_out_work_order(order);
-
-	if (buf == NULL)
-		_cx18_stream_load_fw_queue(s);
-	else
-		_cx18_stream_put_buf_fw(s, buf);
-}
-
-static
-struct cx18_out_work_order *alloc_out_work_order(struct cx18 *cx)
-{
-	int i;
-	struct cx18_out_work_order *order = NULL;
-
-	for (i = 0; i < CX18_MAX_OUT_WORK_ORDERS; i++) {
-		/*
-		 * We need "pending" to be atomic to inspect & set its contents
-		 * 1. "pending" is only set to 1 here, but needs multiple access
-		 * protection
-		 * 2. work handler threads only clear "pending" and only
-		 * on one, particular work order at a time, per handler thread.
-		 */
-		if (atomic_add_unless(&cx->out_work_order[i].pending, 1, 1)) {
-			order = &cx->out_work_order[i];
-			break;
-		}
-	}
-	return order;
-}
-
-struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
-					  struct cx18_buffer *buf)
-{
-	struct cx18 *cx = s->cx;
-	struct cx18_out_work_order *order;
-
-	order = alloc_out_work_order(cx);
-	if (order == NULL) {
-		CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
-				"order forms available; sending buffer %u back "
-				"to the firmware immediately for stream %s\n",
-				buf->id, s->name);
-		return _cx18_stream_put_buf_fw(s, buf);
-	}
-	order->s = s;
-	order->buf = buf;
-	queue_work(cx->out_work_queue, &order->work);
-	return NULL;
-}
-
-void cx18_stream_load_fw_queue(struct cx18_stream *s)
-{
-	struct cx18 *cx = s->cx;
-	struct cx18_out_work_order *order;
+	struct cx18_stream *s =
+			 container_of(work, struct cx18_stream, out_work_order);
 
-	order = alloc_out_work_order(cx);
-	if (order == NULL) {
-		CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
-				"order forms available; filling the firmware "
-				"buffer queue immediately for stream %s\n",
-				s->name);
-		_cx18_stream_load_fw_queue(s);
-		return;
-	}
-	order->s = s;
-	order->buf = NULL; /* Indicates to load the fw queue */
-	queue_work(cx->out_work_queue, &order->work);
+	_cx18_stream_load_fw_queue(s);
 }
 
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 1fdcfffb07e..1afc3fd9d82 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -29,9 +29,20 @@ int cx18_streams_register(struct cx18 *cx);
 void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
 /* Related to submission of buffers to firmware */
-void cx18_stream_load_fw_queue(struct cx18_stream *s);
-struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
-					  struct cx18_buffer *buf);
+static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
+{
+	struct cx18 *cx = s->cx;
+	queue_work(cx->out_work_queue, &s->out_work_order);
+}
+
+static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
+					  struct cx18_buffer *buf)
+{
+	/* Put buf on q_free; the out work handler will move buf(s) to q_busy */
+	cx18_enqueue(s, buf, &s->q_free);
+	cx18_stream_load_fw_queue(s);
+}
+
 void cx18_out_work_handler(struct work_struct *work);
 
 /* Capture related */
-- 
cgit v1.2.3-70-g09d2


From 9982be8a14e4bff0c3750cbfb669d2648a98b2e8 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Wed, 15 Apr 2009 20:49:19 -0300
Subject: V4L/DVB (11620): cx18: Increment version due to significant buffer
 handling changes

Version bump from 1.1.0 to 1.2.0

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index bd9bd44da79..45494b094e7 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 1
+#define CX18_DRIVER_VERSION_MINOR 2
 #define CX18_DRIVER_VERSION_PATCHLEVEL 0
 
 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
-- 
cgit v1.2.3-70-g09d2


From 0c6292522968427d4f8e01f7c2e4216f04470072 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 26 Apr 2009 16:34:36 -0300
Subject: V4L/DVB (11622): cx18: Allow IVTV format VBI insertion in MPEG-2 SVCD
 and DVD streams

Both the MPEG-2 SVCD stream format and the MPEG-2 DVD stream format should
use an MPEG-2 PS container.  This makes it safe to stuff IVTV Private Stream 1
VBI packets in these stream types using the existing cx18 driver routines.

Reported-by: Helen Buus <mythtv@hbuus.com>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-controls.c | 6 ++++--
 drivers/media/video/cx18/cx18-fileops.c  | 7 ++++++-
 2 files changed, 10 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 82fc2f9d402..8e35c3aed54 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
 		return -EBUSY;
 
 	if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
-	    type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
-		/* We don't do VBI insertion aside from IVTV format in a PS */
+	    !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
+	      type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
+	      type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
+		/* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
 		cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
 		CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
 				"the MPEG stream\n");
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index b3889c0b269..29969c18949 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
 		 * an MPEG-2 Program Pack start code, and provide only
 		 * up to that point to the user, so it's easy to insert VBI data
 		 * the next time around.
+		 *
+		 * This will not work for an MPEG-2 TS and has only been
+		 * verified by analysis to work for an MPEG-2 PS.  Helen Buus
+		 * pointed out this works for the CX23416 MPEG-2 DVD compatible
+		 * stream, and research indicates both the MPEG 2 SVCD and DVD
+		 * stream types use an MPEG-2 PS container.
 		 */
-		/* FIXME - This only works for an MPEG-2 PS, not a TS */
 		/*
 		 * An MPEG-2 Program Stream (PS) is a series of
 		 * MPEG-2 Program Packs terminated by an
-- 
cgit v1.2.3-70-g09d2


From 1bd8e15ac31f7f3d9f1ace70660330ba0055c69c Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 26 Apr 2009 17:02:25 -0300
Subject: V4L/DVB (11623): cx18: Verify cx18-av-core digitizer firmware loads
 correctly

Add code to verify the cx18-av-core digitizer firmware loads correctly.  The
verification function reads back and compares the firmware bytes loaded
into the A/V core.  The result of the verification is only used to log a
message in the system log.

This change was prompted by users with multiple card setups that have problems
with broadcast audio decoding the first time the cx18 module is loaded.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-firmware.c | 50 +++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 49a55cc8d83..ab99030dc18 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -27,6 +27,48 @@
 #define CX18_AUDIO_ENABLE 0xc72014
 #define FWFILE "v4l-cx23418-dig.fw"
 
+static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
+{
+	struct v4l2_subdev *sd = &cx->av_state.sd;
+	int ret = 0;
+	const u8 *data;
+	u32 size;
+	int addr;
+	u32 expected, dl_control;
+
+	/* Ensure we put the 8051 in reset and enable firmware upload mode */
+	dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+	do {
+		dl_control &= 0x00ffffff;
+		dl_control |= 0x0f000000;
+		cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
+		dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+	} while ((dl_control & 0xff000000) != 0x0f000000);
+
+	/* Read and auto increment until at address 0x0000 */
+	while (dl_control & 0x3fff)
+		dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+
+	data = fw->data;
+	size = fw->size;
+	for (addr = 0; addr < size; addr++) {
+		dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
+		expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
+		if (expected != dl_control) {
+			CX18_ERR_DEV(sd, "verification of %s firmware load "
+				     "failed: expected %#010x got %#010x\n",
+				     FWFILE, expected, dl_control);
+			ret = -EIO;
+			break;
+		}
+		dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+	}
+	if (ret == 0)
+		CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
+			      FWFILE, size);
+	return ret;
+}
+
 int cx18_av_loadfw(struct cx18 *cx)
 {
 	struct v4l2_subdev *sd = &cx->av_state.sd;
@@ -95,6 +137,12 @@ int cx18_av_loadfw(struct cx18 *cx)
 	}
 
 	cx18_av_write4_expect(cx, CXADEC_DL_CTL,
+				0x03000000 | fw->size, 0x03000000, 0x13000000);
+
+	CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
+
+	if (cx18_av_verifyfw(cx, fw) == 0)
+		cx18_av_write4_expect(cx, CXADEC_DL_CTL,
 				0x13000000 | fw->size, 0x13000000, 0x13000000);
 
 	/* Output to the 416 */
@@ -143,7 +191,5 @@ int cx18_av_loadfw(struct cx18 *cx)
 	cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
 
 	release_firmware(fw);
-
-	CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2


From 33b55a0a7d5d0cd109d0506004a51e4000affbf2 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 26 Apr 2009 18:46:14 -0300
Subject: V4L/DVB (11624): cx18: Toggle the AI1 mux when changing the
 CX18_AUDIO_ENABLE register

Toggle the AI1 mux when changing the CX18_AUDIO_ENABLE register.  It's hard to
reliably tell when we have written to this register successfully unless we
change some bits we know we can read back.  The AI mux bits always read back
what we wrote to them, so force them to toggle whenever we have to write to
the register, so we can tell we wrote to the register successfully.

This change was prompted by users experiencing broadcast audio decoding
problems after the cx18 module loads for the first time.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-audio.c       | 44 +++++++++++++++++++++++++----
 drivers/media/video/cx18/cx18-av-firmware.c | 32 +++++++++++++++++++--
 2 files changed, 68 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 7a8ad5963de..35268923911 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -26,14 +26,18 @@
 #include "cx18-cards.h"
 #include "cx18-audio.h"
 
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE    0xc72014
+#define CX18_AI1_MUX_MASK    0x30
+#define CX18_AI1_MUX_I2S1    0x00
+#define CX18_AI1_MUX_I2S2    0x10
+#define CX18_AI1_MUX_843_I2S 0x20
 
 /* Selects the audio input and output according to the current
    settings. */
 int cx18_audio_set_io(struct cx18 *cx)
 {
 	const struct cx18_card_audio_input *in;
-	u32 val;
+	u32 u, v;
 	int err;
 
 	/* Determine which input to use */
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx)
 		return err;
 
 	/* FIXME - this internal mux should be abstracted to a subdev */
-	val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
-	val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
-					(in->audio_input << 4);
-	cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
+	u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+	v = u & ~CX18_AI1_MUX_MASK;
+	switch (in->audio_input) {
+	case CX18_AV_AUDIO_SERIAL1:
+		v |= CX18_AI1_MUX_I2S1;
+		break;
+	case CX18_AV_AUDIO_SERIAL2:
+		v |= CX18_AI1_MUX_I2S2;
+		break;
+	default:
+		v |= CX18_AI1_MUX_843_I2S;
+		break;
+	}
+	if (v == u) {
+		/* force a toggle of some AI1 MUX control bits */
+		u &= ~CX18_AI1_MUX_MASK;
+		switch (in->audio_input) {
+		case CX18_AV_AUDIO_SERIAL1:
+			u |= CX18_AI1_MUX_843_I2S;
+			break;
+		case CX18_AV_AUDIO_SERIAL2:
+			u |= CX18_AI1_MUX_843_I2S;
+			break;
+		default:
+			u |= CX18_AI1_MUX_I2S1;
+			break;
+		}
+		cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
+				      u, CX18_AI1_MUX_MASK);
+	}
+	cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+			      v, CX18_AI1_MUX_MASK);
 	return 0;
 }
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index ab99030dc18..b9e8cc5d264 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -24,7 +24,13 @@
 #include "cx18-io.h"
 #include <linux/firmware.h>
 
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE    0xc72014
+#define CX18_AI1_MUX_MASK    0x30
+#define CX18_AI1_MUX_I2S1    0x00
+#define CX18_AI1_MUX_I2S2    0x10
+#define CX18_AI1_MUX_843_I2S 0x20
+#define CX18_AI1_MUX_INVALID 0x30
+
 #define FWFILE "v4l-cx23418-dig.fw"
 
 static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
@@ -74,7 +80,7 @@ int cx18_av_loadfw(struct cx18 *cx)
 	struct v4l2_subdev *sd = &cx->av_state.sd;
 	const struct firmware *fw = NULL;
 	u32 size;
-	u32 v;
+	u32 u, v;
 	const u8 *ptr;
 	int i;
 	int retries1 = 0;
@@ -183,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx)
 		cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
 				      0, 0x400);
 
+	/* Toggle the AI1 MUX */
+	v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+	u = v & CX18_AI1_MUX_MASK;
+	v &= ~CX18_AI1_MUX_MASK;
+	if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
+		/* Switch to I2S1 */
+		v |= CX18_AI1_MUX_I2S1;
+		cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+				      v, CX18_AI1_MUX_MASK);
+		/* Switch back to the A/V decoder core I2S output */
+		v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
+	} else {
+		/* Switch to the A/V decoder core I2S output */
+		v |= CX18_AI1_MUX_843_I2S;
+		cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+				      v, CX18_AI1_MUX_MASK);
+		/* Switch back to I2S1 or I2S2 */
+		v = (v & ~CX18_AI1_MUX_MASK) | u;
+	}
+	cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+			      v, CX18_AI1_MUX_MASK);
+
 	/* Enable WW auto audio standard detection */
 	v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
 	v |= 0xFF;   /* Auto by default */
-- 
cgit v1.2.3-70-g09d2


From 24c64f42788004d2ec0cae2f8c07b4e76b0f69e1 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 15:07:54 -0300
Subject: V4L/DVB (11628): gspca - m5602-s5k83a: Remove more init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h | 79 --------------------------
 1 file changed, 79 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 0697f8a99d8..12ad43a0cbe 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -110,85 +110,6 @@ static const unsigned char preinit_s5k83a[][4] =
 */
 static const unsigned char init_s5k83a[][4] =
 {
-	{SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
-	{SENSOR, 0xaf, 0x01, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
-	{SENSOR, 0x7b, 0xff, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR, 0x01, 0x50, 0x00},
-	{SENSOR, 0x12, 0x20, 0x00},
-	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, 0x1c, 0x00, 0x00},
-	{SENSOR, 0x02, 0x70, 0x00},
-	{SENSOR, 0x03, 0x0b, 0x00},
-	{SENSOR, 0x04, 0xf0, 0x00},
-	{SENSOR, 0x05, 0x0b, 0x00},
-
-	{SENSOR, 0x06, 0x71, 0x00},
-	{SENSOR, 0x07, 0xe8, 0x00},
-	{SENSOR, 0x08, 0x02, 0x00},
-	{SENSOR, 0x09, 0x88, 0x00},
-	{SENSOR, 0x14, 0x00, 0x00},
-	{SENSOR, 0x15, 0x20, 0x00},
-	{SENSOR, 0x19, 0x00, 0x00},
-	{SENSOR, 0x1a, 0x98, 0x00},
-	{SENSOR, 0x0f, 0x02, 0x00},
-	{SENSOR, 0x10, 0xe5, 0x00},
-
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
-	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
-	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
-	{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
-
-	{SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
-	{SENSOR, 0xaf, 0x01, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	/* ff ( init value )is very dark) || 71 and f0 better */
-	{SENSOR, 0x7b, 0xff, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-	{SENSOR, 0x01, 0x50, 0x00},
-	{SENSOR, 0x12, 0x20, 0x00},
-	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, 0x1c, 0x00, 0x00},
-	{SENSOR, 0x02, 0x70, 0x00},
-	/* some values like 0x10 give a blue-purple image */
-	{SENSOR, 0x03, 0x0b, 0x00},
-	{SENSOR, 0x04, 0xf0, 0x00},
-	{SENSOR, 0x05, 0x0b, 0x00},
-
-	{SENSOR, 0x06, 0x71, 0x00},
-	{SENSOR, 0x07, 0xe8, 0x00},
-	{SENSOR, 0x08, 0x02, 0x00},
-	{SENSOR, 0x09, 0x88, 0x00},
-	{SENSOR, 0x14, 0x00, 0x00},
-	{SENSOR, 0x15, 0x20, 0x00},
-	{SENSOR, 0x19, 0x00, 0x00},
-	{SENSOR, 0x1a, 0x98, 0x00},
-	{SENSOR, 0x0f, 0x02, 0x00},
-	{SENSOR, 0x10, 0xe5, 0x00},
-
 	/* The following sequence is useless after a clean boot
 	   but is necessary after resume from suspend */
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 326405de18bbff737eb7349e2f887fb1ea95e5d8 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 15:10:17 -0300
Subject: V4L/DVB (11629): gspca - m5602-s5k83a: Move some init code around
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h | 31 +++++++++++---------------
 1 file changed, 13 insertions(+), 18 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 12ad43a0cbe..9a2566d5ed9 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -146,13 +146,24 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x01, 0x50, 0x00},
 	{SENSOR, 0x12, 0x20, 0x00},
 	{SENSOR, 0x17, 0x40, 0x00},
-	{SENSOR, S5K83A_GAIN, 0x0f, 0x00},
 	{SENSOR, 0x1c, 0x00, 0x00},
 	{SENSOR, 0x02, 0x70, 0x00},
 	{SENSOR, 0x03, 0x0b, 0x00},
 	{SENSOR, 0x04, 0xf0, 0x00},
 	{SENSOR, 0x05, 0x0b, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
+	{SENSOR, 0x06, 0x71, 0x00},
+	{SENSOR, 0x07, 0xe8, 0x00},
+	{SENSOR, 0x08, 0x02, 0x00},
+	{SENSOR, 0x09, 0x88, 0x00},
+	{SENSOR, 0x14, 0x00, 0x00},
+	{SENSOR, 0x15, 0x20, 0x00},
+	{SENSOR, 0x19, 0x00, 0x00},
+	{SENSOR, 0x1a, 0x98, 0x00},
+	{SENSOR, 0x0f, 0x02, 0x00},
+	{SENSOR, 0x10, 0xe5, 0x00},
+	/* normal colors
+	(this is value after boot, but after tries can be different) */
+	{SENSOR, 0x00, 0x06, 0x00},
 
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -178,22 +189,6 @@ static const unsigned char init_s5k83a[][4] =
 	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-
-	{SENSOR, 0x06, 0x71, 0x00},
-	{SENSOR, 0x07, 0xe8, 0x00},
-	{SENSOR, 0x08, 0x02, 0x00},
-	{SENSOR, 0x09, 0x88, 0x00},
-	{SENSOR, 0x14, 0x00, 0x00},
-	{SENSOR, 0x15, 0x20, 0x00},
-	{SENSOR, 0x19, 0x00, 0x00},
-	{SENSOR, 0x1a, 0x98, 0x00},
-	{SENSOR, 0x0f, 0x02, 0x00},
-	{SENSOR, 0x10, 0xe5, 0x00},
-	{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
-
-	/* normal colors
-	   (this is value after boot, but after tries can be different) */
-	{SENSOR, 0x00, 0x06, 0x00},
 };
 
 #endif
-- 
cgit v1.2.3-70-g09d2


From 04e84f87192b5b599187e3f5edc54ebe4a89e954 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Tue, 20 Jan 2009 15:15:25 -0300
Subject: V4L/DVB (11630): gspca - s5k83a: Add resolution annotations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 9a2566d5ed9..47c0bb4731d 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -152,15 +152,15 @@ static const unsigned char init_s5k83a[][4] =
 	{SENSOR, 0x04, 0xf0, 0x00},
 	{SENSOR, 0x05, 0x0b, 0x00},
 	{SENSOR, 0x06, 0x71, 0x00},
-	{SENSOR, 0x07, 0xe8, 0x00},
+	{SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
 	{SENSOR, 0x08, 0x02, 0x00},
-	{SENSOR, 0x09, 0x88, 0x00},
+	{SENSOR, 0x09, 0x88, 0x00}, /* 648 */
 	{SENSOR, 0x14, 0x00, 0x00},
-	{SENSOR, 0x15, 0x20, 0x00},
+	{SENSOR, 0x15, 0x20, 0x00}, /* 32 */
 	{SENSOR, 0x19, 0x00, 0x00},
-	{SENSOR, 0x1a, 0x98, 0x00},
+	{SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
 	{SENSOR, 0x0f, 0x02, 0x00},
-	{SENSOR, 0x10, 0xe5, 0x00},
+	{SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
 	/* normal colors
 	(this is value after boot, but after tries can be different) */
 	{SENSOR, 0x00, 0x06, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 4c3414eeb3a275a017399ea162615292b00d087f Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 03:43:49 -0300
Subject: V4L/DVB (11631): gspca - m5602: Remove useless error check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 93302f31aa6..9147e39271c 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -84,10 +84,11 @@ int m5602_wait_for_i2c(struct sd *sd)
 {
 	int err;
 	u8 data;
+
 	do {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
 	} while ((data & I2C_BUSY) && !err);
-	return (err < 0) ? err : 0;
+	return err;
 }
 
 int m5602_read_sensor(struct sd *sd, const u8 address,
-- 
cgit v1.2.3-70-g09d2


From 57851d0cd0b4b9058a10ca81efc4cb6cbc9323e7 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 27 Apr 2009 15:38:05 -0300
Subject: V4L/DVB (11632): gspca - m5602-s5k83a: Reset the v4l2 ctrl cache upon
 sensor init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.c | 34 ++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index e1529afd494..646796d21c5 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -124,7 +124,8 @@ const static struct ctrl s5k83a_ctrls[] = {
 static void s5k83a_dump_registers(struct sd *sd);
 static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
 static int s5k83a_set_led_indication(struct sd *sd, u8 val);
-int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip);
+static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
+				__s32 vflip, __s32 hflip);
 
 int s5k83a_probe(struct sd *sd)
 {
@@ -198,6 +199,7 @@ sensor_found:
 int s5k83a_init(struct sd *sd)
 {
 	int i, err = 0;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
 		u8 data[2] = {0x00, 0x00};
@@ -230,7 +232,27 @@ int s5k83a_init(struct sd *sd)
 	if (dump_sensor)
 		s5k83a_dump_registers(sd);
 
-	return (err < 0) ? err : 0;
+	err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k83a_set_brightness(&sd->gspca_dev,
+				     sensor_settings[BRIGHTNESS_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k83a_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+
+	return err;
 }
 
 static int rotation_thread_function(void *data)
@@ -282,7 +304,8 @@ int s5k83a_start(struct sd *sd)
 	/* Create another thread, polling the GPIO ports of the camera to check
 	   if it got rotated. This is how the windows driver does it so we have
 	   to assume that there is no better way of accomplishing this */
-	sens_priv->rotation_thread = kthread_create(rotation_thread_function, sd, "rotation thread");
+	sens_priv->rotation_thread = kthread_create(rotation_thread_function,
+							sd, "rotation thread");
 	wake_up_process(sens_priv->rotation_thread);
 
 	return s5k83a_set_led_indication(sd, 1);
@@ -402,7 +425,8 @@ static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
-int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip)
+static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
+				__s32 vflip, __s32 hflip)
 {
 	int err;
 	u8 data[1];
@@ -505,7 +529,7 @@ static int s5k83a_set_led_indication(struct sd *sd, u8 val)
 
 	err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
 
-	return (err < 0) ? err : 0;
+	return err;
 }
 
 /* Get camera rotation on Acer notebooks */
-- 
cgit v1.2.3-70-g09d2


From cde41bb292c5f5475213ebed96cd5f18b51ecd48 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 03:33:14 -0300
Subject: V4L/DVB (11633): gspca - m5602-s5k83a: Move hsync/vsync setup to
 start function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.c | 16 +++++++++++++++-
 drivers/media/video/gspca/m5602/m5602_s5k83a.h |  3 +++
 2 files changed, 18 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 646796d21c5..118ec8f8cbd 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -299,15 +299,29 @@ static int rotation_thread_function(void *data)
 
 int s5k83a_start(struct sd *sd)
 {
+	int i, err = 0;
 	struct s5k83a_priv *sens_priv = sd->sensor_priv;
 
 	/* Create another thread, polling the GPIO ports of the camera to check
 	   if it got rotated. This is how the windows driver does it so we have
 	   to assume that there is no better way of accomplishing this */
 	sens_priv->rotation_thread = kthread_create(rotation_thread_function,
-							sd, "rotation thread");
+						    sd, "rotation thread");
 	wake_up_process(sens_priv->rotation_thread);
 
+	/* Preinit the sensor */
+	for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
+		u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
+		if (start_s5k83a[i][0] == SENSOR)
+			err = m5602_write_sensor(sd, start_s5k83a[i][1],
+				data, 2);
+		else
+			err = m5602_write_bridge(sd, start_s5k83a[i][1],
+				data[0]);
+	}
+	if (err < 0)
+		return err;
+
 	return s5k83a_set_led_indication(sd, 1);
 }
 
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 47c0bb4731d..7814b078acd 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -164,7 +164,10 @@ static const unsigned char init_s5k83a[][4] =
 	/* normal colors
 	(this is value after boot, but after tries can be different) */
 	{SENSOR, 0x00, 0x06, 0x00},
+};
 
+static const unsigned char start_s5k83a[][4] =
+{
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-- 
cgit v1.2.3-70-g09d2


From c41507ba06c2fbe5a1de908ef5bd1b2c4d9b13c0 Mon Sep 17 00:00:00 2001
From: Lukas Karas <lukas.karas@centrum.cz>
Date: Wed, 21 Jan 2009 13:14:07 -0300
Subject: V4L/DVB (11634): gspca - m5602-s5k83a: Set the sensor_settings
 pointer correctly
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Lukas Karas <lukas.karas@centrum.cz>
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k83a.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 118ec8f8cbd..942030fd0cf 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -199,7 +199,8 @@ sensor_found:
 int s5k83a_init(struct sd *sd)
 {
 	int i, err = 0;
-	s32 *sensor_settings = sd->sensor_priv;
+	s32 *sensor_settings =
+			((struct s5k83a_priv *) sd->sensor_priv)->settings;
 
 	for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
 		u8 data[2] = {0x00, 0x00};
-- 
cgit v1.2.3-70-g09d2


From 4763fa84d9942137b011629be2e7547a23cdfbc6 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 13:28:31 -0300
Subject: V4L/DVB (11635): gspca - m5602-ov7660: Initial checkin of sensor
 skeleton code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/Makefile       |   1 +
 drivers/media/video/gspca/m5602/m5602_ov7660.c |  92 +++++++
 drivers/media/video/gspca/m5602/m5602_ov7660.h | 367 +++++++++++++++++++++++++
 3 files changed, 460 insertions(+)
 create mode 100644 drivers/media/video/gspca/m5602/m5602_ov7660.c
 create mode 100644 drivers/media/video/gspca/m5602/m5602_ov7660.h

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 9fa3644f486..c819d785b3f 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o
 
 gspca_m5602-objs := m5602_core.o \
 		    m5602_ov9650.o \
+		    m5602_ov7660.o \
 		    m5602_mt9m111.o \
 		    m5602_po1030.o \
 		    m5602_s5k83a.o \
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
new file mode 100644
index 00000000000..466de667a60
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -0,0 +1,92 @@
+/*
+ * Driver for the ov7660 sensor
+ *
+ * Copyright (C) 2009 Erik Andrén
+ * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
+ * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
+ *
+ * Portions of code to USB interface and ALi driver software,
+ * Copyright (c) 2006 Willem Duinker
+ * v4l2 interface modeled after the V4L2 driver
+ * for SN9C10x PC Camera Controllers
+ *
+ * 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.
+ *
+ */
+
+#include "m5602_ov7660.h"
+
+const static struct ctrl ov7660_ctrls[] = {};
+
+static struct v4l2_pix_format ov7660_modes[] = {
+	{
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+static void ov7660_dump_registers(struct sd *sd);
+
+int ov7660_probe(struct sd *sd)
+{
+	return -ENODEV;
+}
+
+int ov7660_init(struct sd *sd)
+{
+	return 0;
+}
+
+int ov7660_start(struct sd *sd)
+{
+	return 0;
+}
+
+int ov7660_stop(struct sd *sd)
+{
+	return 0;
+}
+
+void ov7660_disconnect(struct sd *sd) {}
+
+static void ov7660_dump_registers(struct sd *sd)
+{
+	int address;
+	info("Dumping the ov7660 register state");
+	for (address = 0; address < 0xa9; address++) {
+		u8 value;
+		m5602_read_sensor(sd, address, &value, 1);
+		info("register 0x%x contains 0x%x",
+		     address, value);
+	}
+
+	info("ov7660 register state dump complete");
+
+	info("Probing for which registers that are read/write");
+	for (address = 0; address < 0xff; address++) {
+		u8 old_value, ctrl_value;
+		u8 test_value[2] = {0xff, 0xff};
+
+		m5602_read_sensor(sd, address, &old_value, 1);
+		m5602_write_sensor(sd, address, test_value, 1);
+		m5602_read_sensor(sd, address, &ctrl_value, 1);
+
+		if (ctrl_value == test_value[0])
+			info("register 0x%x is writeable", address);
+		else
+			info("register 0x%x is read only", address);
+
+		/* Restore original value */
+		m5602_write_sensor(sd, address, &old_value, 1);
+	}
+}
+
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
new file mode 100644
index 00000000000..67bde9bb28c
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -0,0 +1,367 @@
+/*
+ * Driver for the ov7660 sensor
+ *
+ * Copyright (C) 2009 Erik Andrén
+ * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
+ * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
+ *
+ * Portions of code to USB interface and ALi driver software,
+ * Copyright (c) 2006 Willem Duinker
+ * v4l2 interface modeled after the V4L2 driver
+ * for SN9C10x PC Camera Controllers
+ *
+ * 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.
+ *
+ */
+
+#ifndef M5602_OV7660_H_
+#define M5602_OV7660_H_
+
+#include "m5602_sensor.h"
+
+#define OV7660_GAIN		0x00
+#define OV7660_BLUE_GAIN	0x01
+#define OV7660_RED_GAIN		0x02
+#define OV7660_VREF		0x03
+#define OV7660_COM1		0x04
+#define OV7660_BAVE		0x05
+#define OV7660_GEAVE		0x06
+#define OV7660_AECHH		0x07
+#define OV7660_RAVE		0x08
+#define OV7660_COM2		0x09
+#define OV7660_PID		0x0a
+#define OV7660_VER		0x0b
+#define OV7660_COM3		0x0c
+#define OV7660_COM4		0x0d
+#define OV7660_COM5		0x0e
+#define OV7660_COM6		0x0f
+#define OV7660_AECH		0x10
+#define OV7660_CLKRC		0x11
+#define OV7660_COM7		0x12
+#define OV7660_COM8		0x13
+#define OV7660_COM9		0x14
+#define OV7660_COM10		0x15
+#define OV7660_RSVD16		0x16
+#define OV7660_HSTART		0x17
+#define OV7660_HSTOP		0x18
+#define OV7660_VSTART		0x19
+#define OV7660_VSTOP		0x1a
+#define OV7660_PSHFT		0x1b
+#define OV7660_MIDH		0x1c
+#define OV7660_MIDL		0x1d
+#define OV7660_MVFP		0x1e
+#define OV7660_LAEC		0x1f
+#define OV7660_BOS		0x20
+#define OV7660_GBOS		0x21
+#define OV7660_GROS		0x22
+#define OV7660_ROS		0x23
+#define OV7660_AEW		0x24
+#define OV7660_AEB		0x25
+#define OV7660_VPT		0x26
+#define OV7660_BBIAS		0x27
+#define OV7660_GbBIAS		0x28
+#define OV7660_RSVD29		0x29
+#define OV7660_RBIAS		0x2c
+#define OV7660_HREF		0x32
+#define OV7660_ADC		0x37
+#define OV7660_OFON 		0x39
+#define OV7660_TSLB 		0x3a
+#define OV7660_COM12 		0x3c
+#define OV7660_COM13 		0x3d
+#define OV7660_LCC1		0x62
+#define OV7660_LCC2		0x63
+#define OV7660_LCC3		0x64
+#define OV7660_LCC4		0x65
+#define OV7660_LCC5		0x66
+#define OV7660_HV 		0x69
+#define OV7660_RSVDA1 		0xa1
+
+#define DEFAULT_GAIN		0x0e
+#define DEFAULT_RED_GAIN	0x80
+#define DEFAULT_BLUE_GAIN 	0x80
+#define DEFAULT_SATURATION	0x00
+#define DEFAULT_EXPOSURE	0x20
+
+int ov7660_probe(struct sd *sd);
+int ov7660_init(struct sd *sd);
+int ov7660_start(struct sd *sd);
+int ov7660_stop(struct sd *sd);
+void ov7660_disconnect(struct sd *sd);
+
+const static struct m5602_sensor ov7660 = {
+	.name = "ov7660",
+	.i2c_slave_id = 0x42,
+	.i2c_regW = 1,
+	.probe = ov7660_probe,
+	.init = ov7660_init,
+	.start = ov7660_start,
+	.stop = ov7660_stop,
+	.disconnect = ov7660_disconnect,
+};
+
+static const unsigned char preinit_ov7660[][4] =
+{
+	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
+	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
+	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
+};
+
+static const unsigned char init_ov7660[][4] =
+{
+	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
+	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
+	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
+	{SENSOR, OV7660_COM7, 0x80},
+	{SENSOR, OV7660_CLKRC, 0x80},
+	{SENSOR, OV7660_BLUE_GAIN, 0x80},
+	{SENSOR, OV7660_RED_GAIN, 0x80},
+	{SENSOR, OV7660_COM9, 0x4c},
+	{SENSOR, OV7660_OFON, 0x43},
+	{SENSOR, OV7660_COM12, 0x28},
+	{SENSOR, OV7660_COM8, 0x00},
+	{SENSOR, OV7660_COM10, 0x40},
+	{SENSOR, OV7660_HSTART, 0x0c},
+	{SENSOR, OV7660_HSTOP, 0x61},
+	{SENSOR, OV7660_HREF, 0xa4},
+	{SENSOR, OV7660_PSHFT, 0x0b},
+	{SENSOR, OV7660_VSTART, 0x01},
+	{SENSOR, OV7660_VSTOP, 0x7a},
+	{SENSOR, OV7660_VREF, 0x00},
+	{SENSOR, OV7660_COM7, 0x05},
+	{SENSOR, OV7660_COM6, 0x4b},
+	{SENSOR, OV7660_BBIAS, 0x98},
+	{SENSOR, OV7660_GbBIAS, 0x98},
+	{SENSOR, OV7660_RSVD29, 0x98},
+	{SENSOR, OV7660_RBIAS, 0x98},
+	{SENSOR, OV7660_COM1, 0x00},
+	{SENSOR, OV7660_AECH, 0x00},
+	{SENSOR, OV7660_AECHH, 0x00},
+	{SENSOR, OV7660_ADC, 0x04},
+	{SENSOR, OV7660_COM13, 0x00},
+	{SENSOR, OV7660_RSVDA1, 0x23},
+	{SENSOR, OV7660_TSLB, 0x0d},
+	{SENSOR, OV7660_HV, 0x80},
+	{SENSOR, OV7660_LCC1, 0x00},
+	{SENSOR, OV7660_LCC2, 0x00},
+	{SENSOR, OV7660_LCC3, 0x10},
+	{SENSOR, OV7660_LCC4, 0x40},
+	{SENSOR, OV7660_LCC5, 0x01},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x02},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0xae},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+
+	{SENSOR, OV7660_BLUE_GAIN, 0x80},
+	{SENSOR, OV7660_RED_GAIN, 0x80},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+	{SENSOR, OV7660_AECH, DEFAULT_EXPOSURE},
+	{SENSOR, OV7660_COM1, 0x00},
+	{SENSOR, OV7660_GAIN, DEFAULT_GAIN},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x02},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0xae},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
+	{SENSOR, OV7660_COM7, 0x80},
+	{SENSOR, OV7660_CLKRC, 0x80},
+	{SENSOR, OV7660_BLUE_GAIN, 0x80},
+	{SENSOR, OV7660_RED_GAIN, 0x80},
+	{SENSOR, OV7660_COM9, 0x4c},
+	{SENSOR, OV7660_OFON, 0x43},
+	{SENSOR, OV7660_COM12, 0x28},
+	{SENSOR, OV7660_COM8, 0x00},
+	{SENSOR, OV7660_COM10, 0x40},
+	{SENSOR, OV7660_HSTART, 0x0c},
+	{SENSOR, OV7660_HSTOP, 0x61},
+	{SENSOR, OV7660_HREF, 0xa4},
+	{SENSOR, OV7660_PSHFT, 0x0b},
+	{SENSOR, OV7660_VSTART, 0x01},
+	{SENSOR, OV7660_VSTOP, 0x7a},
+	{SENSOR, OV7660_VREF, 0x00},
+	{SENSOR, OV7660_COM7, 0x05},
+	{SENSOR, OV7660_COM6, 0x4b},
+	{SENSOR, OV7660_BBIAS, 0x98},
+	{SENSOR, OV7660_GbBIAS, 0x98},
+	{SENSOR, OV7660_RSVD29, 0x98},
+	{SENSOR, OV7660_RBIAS, 0x98},
+	{SENSOR, OV7660_COM1, 0x00},
+	{SENSOR, OV7660_AECH, 0x00},
+	{SENSOR, OV7660_AECHH, 0x00},
+	{SENSOR, OV7660_ADC, 0x04},
+	{SENSOR, OV7660_COM13, 0x00},
+	{SENSOR, OV7660_RSVDA1, 0x23},
+	{SENSOR, OV7660_TSLB, 0x0d},
+	{SENSOR, OV7660_HV, 0x80},
+	{SENSOR, OV7660_LCC1, 0x00},
+	{SENSOR, OV7660_LCC2, 0x00},
+	{SENSOR, OV7660_LCC3, 0x10},
+	{SENSOR, OV7660_LCC4, 0x40},
+	{SENSOR, OV7660_LCC5, 0x01},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, /* 492 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x02},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xae}, /* 686 */
+	{BRIDGE, M5602_XB_SIG_INI, 0x00},
+
+	{SENSOR, OV7660_BLUE_GAIN, 0x80},
+	{SENSOR, OV7660_RED_GAIN, 0x80},
+
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+
+	{SENSOR, OV7660_AECH, 0x20},
+	{SENSOR, OV7660_COM1, 0x00},
+	{SENSOR, OV7660_GAIN, DEFAULT_GAIN},
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
+};
+
+#endif
-- 
cgit v1.2.3-70-g09d2


From ea8f74b168aa4d725c6d1ab98ef4eb4f6f3f3358 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 13:39:17 -0300
Subject: V4L/DVB (11636): gspca - m5602-ov7660: Design probe function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov7660.c | 61 ++++++++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_ov7660.h |  4 ++
 drivers/media/video/gspca/m5602/m5602_sensor.h |  3 +-
 3 files changed, 67 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 466de667a60..a5953d82838 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -38,7 +38,68 @@ static void ov7660_dump_registers(struct sd *sd);
 
 int ov7660_probe(struct sd *sd)
 {
+	int err = 0, i;
+	u8 prod_id = 0, ver_id = 0;
+
+	s32 *sensor_settings;
+
+	if (force_sensor) {
+		if (force_sensor == OV7660_SENSOR) {
+			info("Forcing an %s sensor", ov7660.name);
+			goto sensor_found;
+		}
+		/* If we want to force another sensor,
+		don't try to probe this one */
+		return -ENODEV;
+	}
+
+	/* Do the preinit */
+	for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
+		u8 data[2];
+
+		if (preinit_ov7660[i][0] == BRIDGE) {
+			err = m5602_write_bridge(sd,
+				preinit_ov7660[i][1],
+				preinit_ov7660[i][2]);
+		} else {
+			data[0] = preinit_ov7660[i][2];
+			err = m5602_write_sensor(sd,
+				preinit_ov7660[i][1], data, 1);
+		}
+	}
+	if (err < 0)
+		return err;
+
+	if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
+		return -ENODEV;
+
+	if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
+		return -ENODEV;
+
+	info("Sensor reported 0x%x%x", prod_id, ver_id);
+
+	if ((prod_id == 0x76) && (ver_id == 0x60)) {
+		info("Detected a ov7660 sensor");
+		goto sensor_found;
+	}
 	return -ENODEV;
+
+sensor_found:
+	sensor_settings = kmalloc(
+		ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
+	sd->gspca_dev.cam.cam_mode = ov7660_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
+	sd->desc->ctrls = ov7660_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
+
+	for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
+		sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
+	sd->sensor_priv = sensor_settings;
+
+	return 0;
 }
 
 int ov7660_init(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 67bde9bb28c..71103ede885 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -84,6 +84,10 @@
 #define DEFAULT_SATURATION	0x00
 #define DEFAULT_EXPOSURE	0x20
 
+/* Kernel module parameters */
+extern int force_sensor;
+extern int dump_sensor;
+
 int ov7660_probe(struct sd *sd);
 int ov7660_init(struct sd *sd);
 int ov7660_start(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index c3a72117b39..edff4f1f586 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -30,7 +30,8 @@ enum sensors {
 	S5K83A_SENSOR	= 2,
 	S5K4AA_SENSOR	= 3,
 	MT9M111_SENSOR	= 4,
-	PO1030_SENSOR	= 5
+	PO1030_SENSOR	= 5,
+	OV7660_SENSOR   = 6,
 };
 
 /* Enumerates all possible instruction types */
-- 
cgit v1.2.3-70-g09d2


From 0364c4ca345175daa36c3c672fdecafd469e05a8 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 13:43:20 -0300
Subject: V4L/DVB (11637): gspca - m5602-ov7660: Design init function.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov7660.c | 27 ++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index a5953d82838..1c20a3bfaaf 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -85,11 +85,6 @@ int ov7660_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
-	sensor_settings = kmalloc(
-		ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
-	if (!sensor_settings)
-		return -ENOMEM;
-
 	sd->gspca_dev.cam.cam_mode = ov7660_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
 	sd->desc->ctrls = ov7660_ctrls;
@@ -104,7 +99,27 @@ sensor_found:
 
 int ov7660_init(struct sd *sd)
 {
-	return 0;
+	int i, err = 0;
+
+	/* Init the sensor */
+	for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
+		u8 data[2];
+
+		if (init_ov7660[i][0] == BRIDGE) {
+			err = m5602_write_bridge(sd,
+				init_ov7660[i][1],
+				init_ov7660[i][2]);
+		} else {
+			data[0] = init_ov7660[i][2];
+			err = m5602_write_sensor(sd,
+					init_ov7660[i][1], data, 1);
+		}
+	}
+
+	if (dump_sensor)
+		ov7660_dump_registers(sd);
+
+	return err;
 }
 
 int ov7660_start(struct sd *sd)
-- 
cgit v1.2.3-70-g09d2


From 81b4293ae62b81b0b434f10c694f11fff93be8ca Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 21 Jan 2009 13:46:58 -0300
Subject: V4L/DVB (11638): gspca - m5602-ov7660: Make an educated guess on the
 proper hsync/vsync
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Based on how the ov9650 is configured, make an educated guess on the hsync/vsync setup for the ov7660

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov7660.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 71103ede885..34652bcdfd4 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -335,7 +335,7 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, /* 492 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
@@ -343,7 +343,7 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xae}, /* 686 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 
 	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-- 
cgit v1.2.3-70-g09d2


From c731e271afa85233a2e7f3c2be826a2729d1100c Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 22 Jan 2009 03:32:32 -0300
Subject: V4L/DVB (11639): gspca - m5602-mt9m111: Correct the hflip/vflip
 semantics
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

mt9m111: Hflip and vflip shall always be 0 at start and the image shall be correctly aligned.
The mt9m111 is hflipped and vflipped by default. Correct the semantics to make this happen.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 241108c786c..ade7264d4dc 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -67,7 +67,7 @@ const static struct ctrl mt9m111_ctrls[] = {
 			.minimum        = 0,
 			.maximum        = 1,
 			.step           = 1,
-			.default_value  = 1
+			.default_value  = 0
 		},
 		.set = mt9m111_set_vflip,
 		.get = mt9m111_get_vflip
@@ -81,7 +81,7 @@ const static struct ctrl mt9m111_ctrls[] = {
 			.minimum        = 0,
 			.maximum        = 1,
 			.step           = 1,
-			.default_value  = 1
+			.default_value  = 0
 		},
 		.set = mt9m111_set_hflip,
 		.get = mt9m111_get_hflip
@@ -391,6 +391,9 @@ static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 
 	sensor_settings[VFLIP_IDX] = val;
 
+	/* The mt9m111 is flipped by default */
+	val = !val;
+
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
@@ -427,6 +430,10 @@ static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 
 	sensor_settings[HFLIP_IDX] = val;
+
+	/* The mt9m111 is flipped by default */
+	val = !val;
+
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From 2f17e1a1f0e545a80cb012cd10cef381acb07574 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 22 Jan 2009 03:51:40 -0300
Subject: V4L/DVB (11640): gspca - m5602-s5k4aa: Flip hflip and vflip together
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 28 ++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 404439fa4bb..aa4d3fdaaee 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -418,18 +418,21 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	if (dmi_check_system(s5k4aa_vflip_dmi_table))
+	if (dmi_check_system(s5k4aa_vflip_dmi_table)) {
 		val = !val;
+		data = (data & 0x3f) |
+		       (!sensor_settings[HFLIP_IDX] << 6) |
+		       ((val & 0x01) << 7);
+	} else {
+		data = (data & 0x3f) |
+		(sensor_settings[HFLIP_IDX] << 6) |
+		((val & 0x01) << 7);
+	}
 
-	data = ((data & ~S5K4AA_RM_V_FLIP)
-			| ((val & 0x01) << 7));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
 		return err;
 
-	if (dmi_check_system(s5k4aa_vflip_dmi_table))
-		val = !val;
-
 	if (val) {
 		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 		if (err < 0)
@@ -445,7 +448,6 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 		data--;
 		err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	}
-
 	return err;
 }
 
@@ -481,6 +483,17 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
+	if (dmi_check_system(s5k4aa_vflip_dmi_table)) {
+		val = !val;
+		data = (data & 0x3f) |
+		       (!sensor_settings[VFLIP_IDX] << 7) |
+		       ((val & 0x01) << 6);
+	} else {
+		data = (data & 0x3f) |
+		       (sensor_settings[VFLIP_IDX] << 7) |
+		       ((val & 0x01) << 6);
+	}
+
 	data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
@@ -501,7 +514,6 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 		data--;
 		err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 	}
-
 	return err;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 2b622e2d0022fd9220d6f712ab59bff768c098e7 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 22 Jan 2009 03:57:30 -0300
Subject: V4L/DVB (11641): gspca - m5602-ov7660: Remove useless init data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov7660.h | 94 +-------------------------
 1 file changed, 2 insertions(+), 92 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 34652bcdfd4..15ab706d5dd 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -174,68 +174,6 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
 
-	{SENSOR, OV7660_COM7, 0x80},
-	{SENSOR, OV7660_CLKRC, 0x80},
-	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-	{SENSOR, OV7660_RED_GAIN, 0x80},
-	{SENSOR, OV7660_COM9, 0x4c},
-	{SENSOR, OV7660_OFON, 0x43},
-	{SENSOR, OV7660_COM12, 0x28},
-	{SENSOR, OV7660_COM8, 0x00},
-	{SENSOR, OV7660_COM10, 0x40},
-	{SENSOR, OV7660_HSTART, 0x0c},
-	{SENSOR, OV7660_HSTOP, 0x61},
-	{SENSOR, OV7660_HREF, 0xa4},
-	{SENSOR, OV7660_PSHFT, 0x0b},
-	{SENSOR, OV7660_VSTART, 0x01},
-	{SENSOR, OV7660_VSTOP, 0x7a},
-	{SENSOR, OV7660_VREF, 0x00},
-	{SENSOR, OV7660_COM7, 0x05},
-	{SENSOR, OV7660_COM6, 0x4b},
-	{SENSOR, OV7660_BBIAS, 0x98},
-	{SENSOR, OV7660_GbBIAS, 0x98},
-	{SENSOR, OV7660_RSVD29, 0x98},
-	{SENSOR, OV7660_RBIAS, 0x98},
-	{SENSOR, OV7660_COM1, 0x00},
-	{SENSOR, OV7660_AECH, 0x00},
-	{SENSOR, OV7660_AECHH, 0x00},
-	{SENSOR, OV7660_ADC, 0x04},
-	{SENSOR, OV7660_COM13, 0x00},
-	{SENSOR, OV7660_RSVDA1, 0x23},
-	{SENSOR, OV7660_TSLB, 0x0d},
-	{SENSOR, OV7660_HV, 0x80},
-	{SENSOR, OV7660_LCC1, 0x00},
-	{SENSOR, OV7660_LCC2, 0x00},
-	{SENSOR, OV7660_LCC3, 0x10},
-	{SENSOR, OV7660_LCC4, 0x40},
-	{SENSOR, OV7660_LCC5, 0x01},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0xae},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-
-	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-	{SENSOR, OV7660_RED_GAIN, 0x80},
-
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 
@@ -243,33 +181,6 @@ static const unsigned char init_ov7660[][4] =
 	{SENSOR, OV7660_COM1, 0x00},
 	{SENSOR, OV7660_GAIN, DEFAULT_GAIN},
 
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0xae},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-
-	{SENSOR, OV7660_OFON, 0x0c},
-	{SENSOR, OV7660_COM2, 0x11},
-	{SENSOR, OV7660_COM7, 0x05},
-
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
@@ -346,9 +257,6 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 
-	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-	{SENSOR, OV7660_RED_GAIN, 0x80},
-
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 
@@ -358,6 +266,8 @@ static const unsigned char init_ov7660[][4] =
 	{SENSOR, OV7660_OFON, 0x0c},
 	{SENSOR, OV7660_COM2, 0x11},
 	{SENSOR, OV7660_COM7, 0x05},
+	{SENSOR, OV7660_BLUE_GAIN, 0x80},
+	{SENSOR, OV7660_RED_GAIN, 0x80},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-- 
cgit v1.2.3-70-g09d2


From c9304e43fb71ad790c5fc995de55e7c95abe5b4a Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 22 Jan 2009 04:04:59 -0300
Subject: V4L/DVB (11642): gspca - m5602-ov7660: Add a gain ctrl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov7660.c | 65 ++++++++++++++++++++++++--
 drivers/media/video/gspca/m5602/m5602_ov7660.h |  2 -
 2 files changed, 62 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 1c20a3bfaaf..bfa28de6cbb 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -18,7 +18,26 @@
 
 #include "m5602_ov7660.h"
 
-const static struct ctrl ov7660_ctrls[] = {};
+static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+
+const static struct ctrl ov7660_ctrls[] = {
+#define GAIN_IDX 1
+	{
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "gain",
+			.minimum	= 0x00,
+			.maximum	= 0xff,
+			.step		= 0x1,
+			.default_value	= DEFAULT_GAIN,
+			.flags		= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = ov7660_set_gain,
+		.get = ov7660_get_gain
+	},
+};
 
 static struct v4l2_pix_format ov7660_modes[] = {
 	{
@@ -85,6 +104,11 @@ int ov7660_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
+	sensor_settings = kmalloc(
+		ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
 	sd->gspca_dev.cam.cam_mode = ov7660_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
 	sd->desc->ctrls = ov7660_ctrls;
@@ -100,6 +124,7 @@ sensor_found:
 int ov7660_init(struct sd *sd)
 {
 	int i, err = 0;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	/* Init the sensor */
 	for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
@@ -119,6 +144,10 @@ int ov7660_init(struct sd *sd)
 	if (dump_sensor)
 		ov7660_dump_registers(sd);
 
+	err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
 	return err;
 }
 
@@ -132,7 +161,38 @@ int ov7660_stop(struct sd *sd)
 	return 0;
 }
 
-void ov7660_disconnect(struct sd *sd) {}
+void ov7660_disconnect(struct sd *sd)
+{
+	ov7660_stop(sd);
+
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
+static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[GAIN_IDX];
+	PDEBUG(D_V4L2, "Read gain %d", *val);
+	return 0;
+}
+
+static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Setting gain to %d", val);
+
+	sensor_settings[GAIN_IDX] = val;
+
+	err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
+	return err;
+}
 
 static void ov7660_dump_registers(struct sd *sd)
 {
@@ -165,4 +225,3 @@ static void ov7660_dump_registers(struct sd *sd)
 		m5602_write_sensor(sd, address, &old_value, 1);
 	}
 }
-
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 15ab706d5dd..570715fff76 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -179,7 +179,6 @@ static const unsigned char init_ov7660[][4] =
 
 	{SENSOR, OV7660_AECH, DEFAULT_EXPOSURE},
 	{SENSOR, OV7660_COM1, 0x00},
-	{SENSOR, OV7660_GAIN, DEFAULT_GAIN},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
@@ -262,7 +261,6 @@ static const unsigned char init_ov7660[][4] =
 
 	{SENSOR, OV7660_AECH, 0x20},
 	{SENSOR, OV7660_COM1, 0x00},
-	{SENSOR, OV7660_GAIN, DEFAULT_GAIN},
 	{SENSOR, OV7660_OFON, 0x0c},
 	{SENSOR, OV7660_COM2, 0x11},
 	{SENSOR, OV7660_COM7, 0x05},
-- 
cgit v1.2.3-70-g09d2


From 56513ed50cc8a5c184a3f347e81d74c850cc14fa Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Sun, 25 Jan 2009 10:19:26 -0300
Subject: V4L/DVB (11643): gspca - m5602: Add the ov7660 to the module
 parameter description.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 9147e39271c..ca77dab9075 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -422,8 +422,9 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 module_param(force_sensor, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(force_sensor,
-		"force detection of sensor, "
-		"1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030");
+		"forces detection of a sensor, "
+		"1 = OV9650, 2 = S5K83A, 3 = S5K4AA, "
+		"4 = MT9M111, 5 = PO1030, 6 = OV7660");
 
 module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
-- 
cgit v1.2.3-70-g09d2


From d33762d2015d251db840f002fc88daec04107df7 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Sun, 25 Jan 2009 11:45:35 -0300
Subject: V4L/DVB (11644): gspca - m5602-s5k4aa: Remove some unneeded init
 code.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Remove some redundant init from the s5k4aa. All these registers are programmed again later in the init phase

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h | 71 --------------------------
 1 file changed, 71 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 2349174ad66..c8d909a1fec 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -175,79 +175,8 @@ static const unsigned char init_s5k4aa[][4] =
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, 0x0c, 0x05, 0x00},
 	{SENSOR, 0x02, 0x0e, 0x00},
-	{SENSOR, 0x11, 0x00, 0x00},
-	{SENSOR, 0x12, 0x00, 0x00},
-	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
 	{SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
 	{SENSOR, 0x37, 0x00, 0x00},
-	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
-	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
-	{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
-	{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00},
-	{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
-	{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00},
-	{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
-	{SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00},
-	{SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00},
-	{SENSOR, 0x11, 0x04, 0x00},
-	{SENSOR, 0x12, 0xc3, 0x00},
-	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
-	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
-	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	/* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
-	/* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
-	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
-
-	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
-	{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
-		| S5K4AA_RM_COL_SKIP_2X, 0x00},
-	/* 0x37 : Fix image stability when light is too bright and improves
-	 * image quality in 640x480, but worsens it in 1280x1024 */
-	{SENSOR, 0x37, 0x01, 0x00},
-	/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
-	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
-	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
-	/* window_height_hi, window_height_lo : 960 = 0x03c0 */
-	{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
-	{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
-	/* window_width_hi, window_width_lo : 1280 = 0x0500 */
-	{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
-	{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
-	{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
-	{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
-	{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
-	{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
-	{SENSOR, 0x11, 0x04, 0x00},
-	{SENSOR, 0x12, 0xc3, 0x00},
-	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
-	{SENSOR, 0x02, 0x0e, 0x00},
 };
 
 static const unsigned char VGA_s5k4aa[][4] =
-- 
cgit v1.2.3-70-g09d2


From 201a8a6c3f2b948dadee0d835db30e5f287c7e86 Mon Sep 17 00:00:00 2001
From: Johannes Klug <jklug@joyware.de>
Date: Sun, 25 Jan 2009 15:25:44 -0300
Subject: V4L/DVB (11645): gspca - m5602-ov9650: Add image flip quirk for the
 ASUS A6VA
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Johannes Klug <jklug@joyware.de>
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index d77ec9791bf..d8f776684b6 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -45,6 +45,14 @@ static
     const
 	struct dmi_system_id ov9650_flip_dmi_table[] = {
 	{
+		.ident = "ASUS A6VA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
+		}
+	},
+	{
+
 		.ident = "ASUS A6VC",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-- 
cgit v1.2.3-70-g09d2


From 489a8c37841969613572a8eca90c5a60a0236f1d Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 28 Jan 2009 03:29:51 -0300
Subject: V4L/DVB (11646): gspca - m5602-mt9m111: Disable QVGA until it has
 been verified to work
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The QVGA resolution currently hasn't been verified to work. Disable it for now.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 9 ---------
 1 file changed, 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index ade7264d4dc..5e8d8183bb5 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -37,15 +37,6 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct v4l2_pix_format mt9m111_modes[] = {
 	{
-		320,
-		240,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage = 320 * 240,
-		.bytesperline = 320,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	}, {
 		640,
 		480,
 		V4L2_PIX_FMT_SBGGR8,
-- 
cgit v1.2.3-70-g09d2


From 934f78c3069943cf0654a6f809adf0375b078c38 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 28 Jan 2009 03:34:02 -0300
Subject: V4L/DVB (11647): gspca - m5602-po1030: Disable QVGA for now
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Getting QVGA to be supported on the po1030 seems harder than I first thought. I need access to the proper hardware in order to fix it up.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_po1030.c | 9 ---------
 1 file changed, 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 840a3ca5320..270167bbcc3 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -43,15 +43,6 @@ static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
 
 static struct v4l2_pix_format po1030_modes[] = {
 	{
-		320,
-		240,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage = 320 * 240,
-		.bytesperline = 320,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 2
-	}, {
 		640,
 		480,
 		V4L2_PIX_FMT_SBGGR8,
-- 
cgit v1.2.3-70-g09d2


From 52fa70b7f448da8b763e8c2f566d309d7399a20b Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 28 Jan 2009 04:02:49 -0300
Subject: V4L/DVB (11648): gspca - m5602: Remove some needless error checking
 and add comments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index ca77dab9075..8ca5643f2c7 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -112,18 +112,16 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
 	if (err < 0)
 		return err;
 
+	/* Sensors with registers that only are one byte width are differently read */
+	/* FIXME: This works with the ov9650, but has issues with the po1030 */
 	if (sd->sensor->i2c_regW == 1) {
-		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
+		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
 		if (err < 0)
 			return err;
 
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
-		if (err < 0)
-			return err;
 	} else {
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
-		if (err < 0)
-			return err;
 	}
 
 	for (i = 0; (i < len) && !err; i++) {
-- 
cgit v1.2.3-70-g09d2


From 7b8265033d3ca5425e4fbdb77f9ccd3375f3f117 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 27 Apr 2009 15:41:45 -0300
Subject: V4L/DVB (11649): gspca - m5602: Probe the ov7660 sensor
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 8ca5643f2c7..36bdcda8417 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -17,6 +17,7 @@
  */
 
 #include "m5602_ov9650.h"
+#include "m5602_ov7660.h"
 #include "m5602_mt9m111.h"
 #include "m5602_po1030.h"
 #include "m5602_s5k83a.h"
@@ -217,6 +218,11 @@ static int m5602_probe_sensor(struct sd *sd)
 	if (!sd->sensor->probe(sd))
 		return 0;
 
+	/* Try the ov7660 */
+	sd->sensor = &ov7660;
+	if (!sd->sensor->probe(sd))
+		return 0;
+
 	/* Try the s5k83a */
 	sd->sensor = &s5k83a;
 	if (!sd->sensor->probe(sd))
-- 
cgit v1.2.3-70-g09d2


From 72b79747a88f1ffcb6689cedacc01235bb545cd6 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 28 Jan 2009 13:14:34 -0300
Subject: V4L/DVB (11650): gspca - m5602: Sort out macro conflict by adding a
 prefix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.c |  2 +-
 drivers/media/video/gspca/m5602/m5602_mt9m111.h |  2 +-
 drivers/media/video/gspca/m5602/m5602_ov7660.c  |  2 +-
 drivers/media/video/gspca/m5602/m5602_ov7660.h  | 12 ++++++------
 4 files changed, 9 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 5e8d8183bb5..0c9470e137e 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -86,7 +86,7 @@ const static struct ctrl mt9m111_ctrls[] = {
 			.minimum        = 0,
 			.maximum        = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
 			.step           = 1,
-			.default_value  = DEFAULT_GAIN,
+			.default_value  = MT9M111_DEFAULT_GAIN,
 			.flags          = V4L2_CTRL_FLAG_SLIDER
 		},
 		.set = mt9m111_set_gain,
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 716aba523a1..e71ddb78626 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -97,7 +97,7 @@
 #define MT9M111_2D_DEFECT_CORRECTION_ENABLE	(1 << 0)
 
 #define INITIAL_MAX_GAIN			64
-#define DEFAULT_GAIN 				283
+#define MT9M111_DEFAULT_GAIN 			283
 #define MT9M111_GREEN_GAIN_DEFAULT		0x20
 #define MT9M111_BLUE_GAIN_DEFAULT		0x20
 #define MT9M111_RED_GAIN_DEFAULT		0x20
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index bfa28de6cbb..7aafeb7cfa0 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -31,7 +31,7 @@ const static struct ctrl ov7660_ctrls[] = {
 			.minimum	= 0x00,
 			.maximum	= 0xff,
 			.step		= 0x1,
-			.default_value	= DEFAULT_GAIN,
+			.default_value	= OV7660_DEFAULT_GAIN,
 			.flags		= V4L2_CTRL_FLAG_SLIDER
 		},
 		.set = ov7660_set_gain,
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 570715fff76..3f2c169a93e 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -78,11 +78,11 @@
 #define OV7660_HV 		0x69
 #define OV7660_RSVDA1 		0xa1
 
-#define DEFAULT_GAIN		0x0e
-#define DEFAULT_RED_GAIN	0x80
-#define DEFAULT_BLUE_GAIN 	0x80
-#define DEFAULT_SATURATION	0x00
-#define DEFAULT_EXPOSURE	0x20
+#define OV7660_DEFAULT_GAIN		0x0e
+#define OV7660_DEFAULT_RED_GAIN	0x80
+#define OV7660_DEFAULT_BLUE_GAIN 	0x80
+#define OV7660_DEFAULT_SATURATION	0x00
+#define OV7660_DEFAULT_EXPOSURE	0x20
 
 /* Kernel module parameters */
 extern int force_sensor;
@@ -177,7 +177,7 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 
-	{SENSOR, OV7660_AECH, DEFAULT_EXPOSURE},
+	{SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
 	{SENSOR, OV7660_COM1, 0x00},
 
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
-- 
cgit v1.2.3-70-g09d2


From 2e03669d9da8c52f24ba44fdbd17c5df7be10585 Mon Sep 17 00:00:00 2001
From: Tobias Klauser <tklauser@distanz.ch>
Date: Sun, 26 Apr 2009 09:30:18 -0300
Subject: V4L/DVB (11654): gspca - m5602: Storage class should be before const
 qualifier
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The C99 specification states in section 6.11.5:

The placement of a storage-class specifier other than at the
beginning of the declaration specifiers in a declaration is an
obsolescent feature.

[mchehab@redhat.com: Fix a trivial merge conflict]
Cc: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_mt9m111.h | 2 +-
 drivers/media/video/gspca/m5602/m5602_ov9650.c  | 2 +-
 drivers/media/video/gspca/m5602/m5602_ov9650.h  | 2 +-
 drivers/media/video/gspca/m5602/m5602_po1030.c  | 2 +-
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c  | 2 +-
 drivers/media/video/gspca/m5602/m5602_s5k83a.c  | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index e71ddb78626..b3de7782309 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -113,7 +113,7 @@ int mt9m111_init(struct sd *sd);
 int mt9m111_start(struct sd *sd);
 void mt9m111_disconnect(struct sd *sd);
 
-const static struct m5602_sensor mt9m111 = {
+static const struct m5602_sensor mt9m111 = {
 	.name = "MT9M111",
 
 	.i2c_slave_id = 0xba,
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index d8f776684b6..3219e7c6485 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -97,7 +97,7 @@ static
 	{}
 };
 
-const static struct ctrl ov9650_ctrls[] = {
+static const struct ctrl ov9650_ctrls[] = {
 #define EXPOSURE_IDX 0
 	{
 		{
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 27fe54204c4..c98c40d69e0 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -143,7 +143,7 @@ int ov9650_start(struct sd *sd);
 int ov9650_stop(struct sd *sd);
 void ov9650_disconnect(struct sd *sd);
 
-const static struct m5602_sensor ov9650 = {
+static const struct m5602_sensor ov9650 = {
 	.name = "OV9650",
 	.i2c_slave_id = 0x60,
 	.i2c_regW = 1,
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 270167bbcc3..8d74d8065b7 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -54,7 +54,7 @@ static struct v4l2_pix_format po1030_modes[] = {
 	}
 };
 
-const static struct ctrl po1030_ctrls[] = {
+static const struct ctrl po1030_ctrls[] = {
 #define GAIN_IDX 0
 	{
 		{
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index aa4d3fdaaee..78ea95ba748 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -77,7 +77,7 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
 	}
 };
 
-const static struct ctrl s5k4aa_ctrls[] = {
+static const struct ctrl s5k4aa_ctrls[] = {
 #define VFLIP_IDX 0
 	{
 		{
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 942030fd0cf..df21ad19a94 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -44,7 +44,7 @@ static struct v4l2_pix_format s5k83a_modes[] = {
 	}
 };
 
-const static struct ctrl s5k83a_ctrls[] = {
+static const struct ctrl s5k83a_ctrls[] = {
 #define GAIN_IDX 0
 	{
 		{
-- 
cgit v1.2.3-70-g09d2


From efe018b315a780012d09af70b52a5747cb945e57 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Wed, 29 Apr 2009 18:03:27 -0300
Subject: V4L/DVB (11654a): Add a missing end of line at the end of
 gspca/m5602/Makefile

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index c819d785b3f..bf7a19a1e6d 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -8,4 +8,4 @@ gspca_m5602-objs := m5602_core.o \
 		    m5602_s5k83a.o \
 		    m5602_s5k4aa.o
 
-EXTRA_CFLAGS += -Idrivers/media/video/gspca
\ No newline at end of file
+EXTRA_CFLAGS += -Idrivers/media/video/gspca
-- 
cgit v1.2.3-70-g09d2


From 501d8cd4e248feebd465b016a7d5b7bc084f5f1f Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@linuxtv.org>
Date: Sat, 28 Mar 2009 14:22:21 -0300
Subject: V4L/DVB (11665): cx88: Add support for the Hauppauge IROnly board.

cx88: Add support for the Hauppauge IROnly board.

Signed-off-by: Steven Toth <stoth@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx88 |  1 +
 drivers/media/video/cx88/cx88-cards.c   | 13 +++++++++++++
 drivers/media/video/cx88/cx88-input.c   |  2 ++
 drivers/media/video/cx88/cx88.h         |  1 +
 4 files changed, 17 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 71e9db0b26f..80527b292dd 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -78,3 +78,4 @@
  77 -> TBS 8910 DVB-S                                      [8910:8888]
  78 -> Prof 6200 DVB-S                                     [b022:3022]
  79 -> Terratec Cinergy HT PCI MKII                        [153b:1177]
+ 80 -> Hauppauge WinTV-IR Only                             [0070:9290]
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6bbbfc66bb4..1039757e2c4 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1969,6 +1969,13 @@ static const struct cx88_board cx88_boards[] = {
 		},
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	[CX88_BOARD_HAUPPAUGE_IRONLY] = {
+		.name           = "Hauppauge WinTV-IR Only",
+		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+	},
 };
 
 /* ------------------------------------------------------------------ */
@@ -2382,6 +2389,10 @@ static const struct cx88_subid cx88_subids[] = {
 		.subvendor = 0x153b,
 		.subdevice = 0x1177,
 		.card      = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x9290,
+		.card      = CX88_BOARD_HAUPPAUGE_IRONLY,
 	},
 };
 
@@ -2448,6 +2459,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
 	case 90500: /* Nova-T-PCI (oem) */
 	case 90501: /* Nova-T-PCI (oem/IR) */
 	case 92000: /* Nova-SE2 (OEM, No Video or IR) */
+	case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */
 	case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
 	case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
 	case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
@@ -2907,6 +2919,7 @@ static void cx88_card_setup(struct cx88_core *core)
 	case CX88_BOARD_HAUPPAUGE_HVR1300:
 	case CX88_BOARD_HAUPPAUGE_HVR4000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+	case CX88_BOARD_HAUPPAUGE_IRONLY:
 		if (0 == core->i2c_rc)
 			hauppauge_eeprom(core, eeprom);
 		break;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index ec05312a9b6..bd2baa76203 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -217,6 +217,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
 	case CX88_BOARD_PCHDTV_HD3000:
 	case CX88_BOARD_PCHDTV_HD5500:
+	case CX88_BOARD_HAUPPAUGE_IRONLY:
 		ir_codes = ir_codes_hauppauge_new;
 		ir_type = IR_TYPE_RC5;
 		ir->sampling = 1;
@@ -459,6 +460,7 @@ void cx88_ir_irq(struct cx88_core *core)
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
 	case CX88_BOARD_PCHDTV_HD3000:
 	case CX88_BOARD_PCHDTV_HD5500:
+	case CX88_BOARD_HAUPPAUGE_IRONLY:
 		ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		/*
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 7724d168fc0..2190b600e2e 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -232,6 +232,7 @@ extern struct sram_channel cx88_sram_channels[];
 #define CX88_BOARD_TBS_8910                77
 #define CX88_BOARD_PROF_6200               78
 #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
+#define CX88_BOARD_HAUPPAUGE_IRONLY        80
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
-- 
cgit v1.2.3-70-g09d2


From a26ccc9d76a16580c6800ef0758556c4406a31e0 Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@linuxtv.org>
Date: Wed, 29 Apr 2009 20:49:12 -0300
Subject: V4L/DVB (11666): cx23885: Don't assume GPIO interrupts are cam
 related.

cx23885: Don't assume GPIO interrupts are cam related.

Signed-off-by: Steven Toth <stoth@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-core.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index beda42925ce..9e4d37eb918 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
 	}
 
 	if (cx23885_boards[dev->board].cimax > 0 &&
-		((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
-		/* handled += cx23885_irq_gpio(dev, pci_status); */
-		handled += netup_ci_slot_status(dev, pci_status);
+		((pci_status & PCI_MSK_GPIO0) ||
+			(pci_status & PCI_MSK_GPIO1))) {
+
+		if (cx23885_boards[dev->board].cimax > 0)
+			handled += netup_ci_slot_status(dev, pci_status);
+
+	}
 
 	if (ts1_status) {
 		if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
-- 
cgit v1.2.3-70-g09d2


From 416a7aa88300601d6630736836f9798c4079bc16 Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 2 May 2009 09:42:57 -0300
Subject: V4L/DVB (11670): tuner: remove tuner_i2c_address_check

Support for tuners with i2c addresses >= 0x65 is dropped since no tuners
with addresses in the range 0x65-0x6f have been found.

This patch removes addresses 0x65-0x6f from the list of tuner probe addresses,
it removes the kernel warning that warned if addresses in this range appeared,
and it removed a hack for the cx88 that is no longer needed now that the
tuner address range is reduced.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tuner-core.c  | 27 ---------------------------
 drivers/media/video/v4l2-common.c |  3 +--
 2 files changed, 1 insertion(+), 29 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 78c377a399c..1dac524fc8f 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -309,32 +309,6 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
 	}
 }
 
-static void tuner_i2c_address_check(struct tuner *t)
-{
-	if ((t->type == UNSET || t->type == TUNER_ABSENT) ||
-	    ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f)))
-		return;
-
-	/* We already know that the XC5000 can only be located at
-	 * i2c address 0x61, 0x62, 0x63 or 0x64 */
-	if ((t->type == TUNER_XC5000) &&
-	    ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61))
-		return;
-
-	tuner_warn("====================== WARNING! ======================\n");
-	tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n");
-	tuner_warn("will soon be dropped. This message indicates that your\n");
-	tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n",
-		   t->name, t->i2c->addr);
-	tuner_warn("To ensure continued support for your device, please\n");
-	tuner_warn("send a copy of this message, along with full dmesg\n");
-	tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n");
-	tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n");
-	tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n",
-		   t->i2c->adapter->name, t->i2c->addr, t->type, t->name);
-	tuner_warn("====================== WARNING! ======================\n");
-}
-
 static struct xc5000_config xc5000_cfg;
 
 static void set_type(struct i2c_client *c, unsigned int type,
@@ -490,7 +464,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
 	tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
 		  c->adapter->name, c->driver->driver.name, c->addr << 1, type,
 		  t->mode_mask);
-	tuner_i2c_address_check(t);
 	return;
 
 attach_failed:
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f576ef66b80..e32de9e9b0f 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -897,8 +897,7 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
 	};
 	static const unsigned short tv_addrs[] = {
 		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
-		0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-		0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+		0x60, 0x61, 0x62, 0x63, 0x64,
 		I2C_CLIENT_END
 	};
 
-- 
cgit v1.2.3-70-g09d2


From 102e78136446faca7d7d241b628c5bd0e0d61d5d Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 2 May 2009 10:12:50 -0300
Subject: V4L/DVB (11671): v4l2: add v4l2_device_set_name()

Add a utility function that can be used to setup the v4l2_device's name
field in a standard manner.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/v4l2-framework.txt |  5 +++++
 drivers/media/video/v4l2-device.c            | 16 ++++++++++++++++
 include/media/v4l2-device.h                  | 21 +++++++++++++++++++++
 3 files changed, 42 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 854808b67fa..d54c1e4c6a9 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -89,6 +89,11 @@ from dev (driver name followed by the bus_id, to be precise). If you set it
 up before calling v4l2_device_register then it will be untouched. If dev is
 NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
 
+You can use v4l2_device_set_name() to set the name based on a driver name and
+a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
+etc. If the name ends with a digit, then it will insert a dash: cx18-0,
+cx18-1, etc. This function returns the instance number.
+
 The first 'dev' argument is normally the struct device pointer of a pci_dev,
 usb_interface or platform_device. It is rare for dev to be NULL, but it happens
 with ISA devices or when one device creates multiple PCI devices, thus making
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 94aa485ade5..ffb425f7c24 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -49,6 +49,22 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register);
 
+int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+						atomic_t *instance)
+{
+	int num = atomic_inc_return(instance) - 1;
+	int len = strlen(basename);
+
+	if (basename[len - 1] >= '0' && basename[len - 1] <= '9')
+		snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
+				"%s-%d", basename, num);
+	else
+		snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
+				"%s%d", basename, num);
+	return num;
+}
+EXPORT_SYMBOL_GPL(v4l2_device_set_name);
+
 void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
 {
 	if (v4l2_dev->dev) {
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 9afd39fb2cf..5d5d550e63a 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -53,10 +53,31 @@ struct v4l2_device {
    dev may be NULL in rare cases (ISA devices). In that case you
    must fill in the v4l2_dev->name field before calling this function. */
 int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
+
+/* Optional function to initialize the name field of struct v4l2_device using
+   the driver name and a driver-global atomic_t instance.
+   This function will increment the instance counter and returns the instance
+   value used in the name.
+
+   Example:
+
+   static atomic_t drv_instance = ATOMIC_INIT(0);
+
+   ...
+
+   instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance);
+
+   The first time this is called the name field will be set to foo0 and
+   this function returns 0. If the name ends with a digit (e.g. cx18),
+   then the name will be set to cx18-0 since cx180 looks really odd. */
+int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+						atomic_t *instance);
+
 /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
    Since the parent disappears this ensures that v4l2_dev doesn't have an
    invalid parent pointer. */
 void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
 /* Unregister all sub-devices and any other resources related to v4l2_dev. */
 void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
 
-- 
cgit v1.2.3-70-g09d2


From a79b11c025a5757a5129e716e7e66dc36a2dfe21 Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 2 May 2009 10:15:17 -0300
Subject: V4L/DVB (11672): ivtv: use v4l2_device_set_name.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ivtv/ivtv-driver.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index db2ac9a99ac..e9ca9a064ae 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -946,17 +946,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
 	if (itv == NULL)
 		return -ENOMEM;
 	itv->pdev = pdev;
-	itv->instance = atomic_inc_return(&ivtv_instance) - 1;
+	itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv",
+						&ivtv_instance);
 
 	retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
 	if (retval) {
 		kfree(itv);
 		return retval;
 	}
-	/* "ivtv + PCI ID" is a bit of a mouthful, so use
-	   "ivtv + instance" instead. */
-	snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
-			"ivtv%d", itv->instance);
 	IVTV_INFO("Initializing card %d\n", itv->instance);
 
 	ivtv_process_options(itv);
-- 
cgit v1.2.3-70-g09d2


From b5b2b7ed569cedac4f5da38e08b01c88443187bd Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 2 May 2009 10:58:51 -0300
Subject: V4L/DVB (11673): v4l2-device: unregister i2c_clients when
 unregistering the v4l2_device.

Until now I relied on i2c_del_adapter to unregister the i2c_clients for
me, however, if the i2c bus is a platform bus then it is never deleted.

So instead I need to unregister i2c clients when unregistering the
v4l2_device.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-common.c |  1 +
 drivers/media/video/v4l2-device.c | 13 ++++++++++++-
 include/media/v4l2-subdev.h       |  5 +++++
 3 files changed, 18 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index e32de9e9b0f..f96475626da 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -746,6 +746,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 		const struct v4l2_subdev_ops *ops)
 {
 	v4l2_subdev_init(sd, ops);
+	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
 	/* the owner is the same as the i2c_client's driver owner */
 	sd->owner = client->driver->driver.owner;
 	/* i2c_client and v4l2_subdev point to one another */
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index ffb425f7c24..e1520bc84f7 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -83,8 +83,19 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
 	v4l2_device_disconnect(v4l2_dev);
 
 	/* Unregister subdevs */
-	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
+	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
 		v4l2_device_unregister_subdev(sd);
+		if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
+			struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+			/* We need to unregister the i2c client explicitly.
+			   We cannot rely on i2c_del_adapter to always
+			   unregister clients for us, since if the i2c bus
+			   is a platform bus, then it is never deleted. */
+			if (client)
+				i2c_unregister_device(client);
+		}
+	}
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister);
 
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 17856081c80..a503e1cee78 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -230,12 +230,16 @@ struct v4l2_subdev_ops {
 
 #define V4L2_SUBDEV_NAME_SIZE 32
 
+/* Set this flag if this subdev is a i2c device. */
+#define V4L2_SUBDEV_FL_IS_I2C (1U << 0)
+
 /* Each instance of a subdev driver should create this struct, either
    stand-alone or embedded in a larger struct.
  */
 struct v4l2_subdev {
 	struct list_head list;
 	struct module *owner;
+	u32 flags;
 	struct v4l2_device *v4l2_dev;
 	const struct v4l2_subdev_ops *ops;
 	/* name must be unique */
@@ -264,6 +268,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd,
 	BUG_ON(!ops || !ops->core);
 	sd->ops = ops;
 	sd->v4l2_dev = NULL;
+	sd->flags = 0;
 	sd->name[0] = '\0';
 	sd->grp_id = 0;
 	sd->priv = NULL;
-- 
cgit v1.2.3-70-g09d2


From 4fcec145e9eaae26864731fd6a3120d34abcaffe Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 29 Jan 2009 13:34:41 -0300
Subject: V4L/DVB (11684): gspca - m5602-s5k4aa: Add experimental SXGA support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 43 +++++++++++++++++++++
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h | 52 ++++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 78ea95ba748..b045b08ac13 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -64,6 +64,17 @@ static
 };
 
 static struct v4l2_pix_format s5k4aa_modes[] = {
+	{
+		1280,
+		1024,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			1280 * 1024,
+		.bytesperline = 1280,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
 	{
 		640,
 		480,
@@ -257,6 +268,38 @@ int s5k4aa_start(struct sd *sd)
 	struct cam *cam = &sd->gspca_dev.cam;
 
 	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
+	case 1280:
+		PDEBUG(D_V4L2, "Configuring camera for SXGA mode");
+
+		for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
+			switch (SXGA_s5k4aa[i][0]) {
+			case BRIDGE:
+				err = m5602_write_bridge(sd,
+						 SXGA_s5k4aa[i][1],
+						 SXGA_s5k4aa[i][2]);
+			break;
+
+			case SENSOR:
+				data[0] = SXGA_s5k4aa[i][2];
+				err = m5602_write_sensor(sd,
+						 SXGA_s5k4aa[i][1],
+						 data, 1);
+			break;
+
+			case SENSOR_LONG:
+				data[0] = SXGA_s5k4aa[i][2];
+				data[1] = SXGA_s5k4aa[i][3];
+				err = m5602_write_sensor(sd,
+						  SXGA_s5k4aa[i][1],
+						  data, 2);
+			break;
+
+			default:
+				err("Invalid stream command, exiting init");
+				return -EINVAL;
+			}
+		}
+
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
 
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index c8d909a1fec..e0709a55eb4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -235,4 +235,56 @@ static const unsigned char VGA_s5k4aa[][4] =
 	{SENSOR, 0x02, 0x0e, 0x00},
 };
 
+static const unsigned char SXGA_s5k4aa[][4] =
+{
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	/* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+	/* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
+
+	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+	{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
+		| S5K4AA_RM_COL_SKIP_2X, 0x00},
+	{SENSOR, 0x37, 0x01, 0x00},
+	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
+	{SENSOR, S5K4AA_ROWSTART_LO, 0x0a, 0x00},
+	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
+	{SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
+	{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
+	{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
+	{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
+	{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
+	{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
+	{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
+	{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
+	{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
+	{SENSOR, 0x11, 0x04, 0x00},
+	{SENSOR, 0x12, 0xc3, 0x00},
+	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+	{SENSOR, 0x02, 0x0e, 0x00},
+};
+
+
 #endif
-- 
cgit v1.2.3-70-g09d2


From ff1e6a2155a42f99a9ded8362be2962b1089296b Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 2 Feb 2009 03:51:20 -0300
Subject: V4L/DVB (11685): gspca - gspca-m5602: Constify parameters of two
 functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

A number of parameters to some functions in the m5602 are constant and should be flagged as such.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_bridge.h | 4 ++--
 drivers/media/video/gspca/m5602/m5602_core.c   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 34515e54c1a..1127a405c9b 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -148,10 +148,10 @@ struct sd {
 };
 
 int m5602_read_bridge(
-	struct sd *sd, u8 address, u8 *i2c_data);
+	struct sd *sd, const u8 address, u8 *i2c_data);
 
 int m5602_write_bridge(
-	struct sd *sd, u8 address, u8 i2c_data);
+	struct sd *sd, const u8 address, const u8 i2c_data);
 
 int m5602_write_sensor(struct sd *sd, const u8 address,
 		       u8 *i2c_data, const u8 len);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 36bdcda8417..dd1024325fc 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -36,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = {
 MODULE_DEVICE_TABLE(usb, m5602_table);
 
 /* Reads a byte from the m5602 */
-int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
+int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
 {
 	int err;
 	struct usb_device *udev = sd->gspca_dev.dev;
@@ -57,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
 }
 
 /* Writes a byte to to the m5602 */
-int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
+int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
 {
 	int err;
 	struct usb_device *udev = sd->gspca_dev.dev;
-- 
cgit v1.2.3-70-g09d2


From 65bd761e9a8c9114febab4e554ec0800c59e8983 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 2 Feb 2009 15:56:39 -0300
Subject: V4L/DVB (11686): gspca - m5602-s5k4aa: Disable SXGA resolution for
 now
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

SXGA resolution needs more testing. Disable it for now

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 11 -----------
 1 file changed, 11 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index b045b08ac13..73b826a8ab0 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -64,17 +64,6 @@ static
 };
 
 static struct v4l2_pix_format s5k4aa_modes[] = {
-	{
-		1280,
-		1024,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			1280 * 1024,
-		.bytesperline = 1280,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	},
 	{
 		640,
 		480,
-- 
cgit v1.2.3-70-g09d2


From 4db120bc07b330cd7221fda85bbfea54053a83af Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 2 Feb 2009 16:08:06 -0300
Subject: V4L/DVB (11687): gspca - m5602-ov9650: Add missing v4l2 ctrl ids
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Red and blue balance missed their id fields

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 3219e7c6485..8dca1c57dcd 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -131,6 +131,7 @@ static const struct ctrl ov9650_ctrls[] = {
 #define RED_BALANCE_IDX 2
 	{
 		{
+			.id		= V4L2_CID_RED_BALANCE,
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
 			.name 		= "red balance",
 			.minimum 	= 0x00,
@@ -145,6 +146,7 @@ static const struct ctrl ov9650_ctrls[] = {
 #define BLUE_BALANCE_IDX 3
 	{
 		{
+			.id		= V4L2_CID_BLUE_BALANCE,
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
 			.name 		= "blue balance",
 			.minimum 	= 0x00,
-- 
cgit v1.2.3-70-g09d2


From 60d52cecedf7b55bed07d59ab6039ae066f01124 Mon Sep 17 00:00:00 2001
From: Grégory Lardière <spmf2004-m560x@yahoo.fr>
Date: Thu, 12 Feb 2009 03:32:52 -0300
Subject: V4L/DVB (11688): gspca - m5602-s5k4aa: Fixup SXGA resolution.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The SXGA resolution doesn't work unless you first force the VGA resolution.
More investigation is needed in order to fix this the "right" way.

Signed-off-by: Grégory Lardière <spmf2004-m560x@yahoo.fr>
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 23 +++++++++++++++++++----
 drivers/media/video/gspca/m5602/m5602_s5k4aa.h |  9 ++++-----
 2 files changed, 23 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 73b826a8ab0..b5a9ddb2d21 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -74,6 +74,17 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
 		.bytesperline = 640,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0
+	},
+	{
+		1280,
+		1024,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			1280 * 1024,
+		.bytesperline = 1280,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
 	}
 };
 
@@ -288,6 +299,10 @@ int s5k4aa_start(struct sd *sd)
 				return -EINVAL;
 			}
 		}
+		err = s5k4aa_set_noise(&sd->gspca_dev, 0);
+		if (err < 0)
+			return err;
+		break;
 
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
@@ -320,6 +335,10 @@ int s5k4aa_start(struct sd *sd)
 				return -EINVAL;
 			}
 		}
+		err = s5k4aa_set_noise(&sd->gspca_dev, 1);
+		if (err < 0)
+			return err;
+		break;
 	}
 	return err;
 }
@@ -374,10 +393,6 @@ int s5k4aa_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
-	if (err < 0)
-		return err;
-
 	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
 	if (err < 0)
 		return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index e0709a55eb4..4440da4e7f0 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -265,18 +265,17 @@ static const unsigned char SXGA_s5k4aa[][4] =
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
 
 	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
-	{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
-		| S5K4AA_RM_COL_SKIP_2X, 0x00},
+	{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
 	{SENSOR, 0x37, 0x01, 0x00},
 	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_ROWSTART_LO, 0x0a, 0x00},
+	{SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
 	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
-	{SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
+	{SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
 	{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
 	{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
 	{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
 	{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
-	{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
+	{SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
 	{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
 	{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
 	{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
-- 
cgit v1.2.3-70-g09d2


From 9bc738fb5392f0733529e26d9bb70c8b3d5637ff Mon Sep 17 00:00:00 2001
From: Grégory Lardière <spmf2004-m560x@yahoo.fr>
Date: Thu, 12 Feb 2009 03:40:29 -0300
Subject: V4L/DVB (11689): gspca - m5602-s5k4aa: Fixup the vflip/hflip
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Ensure that the hflip and vflip is consistent when the sensor needs to
be vflip quirked or not.

Signed-off-by: Grégory Lardière <spmf2004-m560x@yahoo.fr>
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 110 +++++++++----------------
 1 file changed, 41 insertions(+), 69 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index b5a9ddb2d21..31a8ba00623 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -266,6 +266,7 @@ int s5k4aa_start(struct sd *sd)
 	int i, err = 0;
 	u8 data[2];
 	struct cam *cam = &sd->gspca_dev.cam;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
 	case 1280:
@@ -340,13 +341,37 @@ int s5k4aa_start(struct sd *sd)
 			return err;
 		break;
 	}
-	return err;
+	if (err < 0)
+		return err;
+
+	err = s5k4aa_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k4aa_set_brightness(&sd->gspca_dev,
+				     sensor_settings[BRIGHTNESS_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
 }
 
 int s5k4aa_init(struct sd *sd)
 {
 	int i, err = 0;
-	s32 *sensor_settings = sd->sensor_priv;
 
 	for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
 		u8 data[2] = {0x00, 0x00};
@@ -379,25 +404,7 @@ int s5k4aa_init(struct sd *sd)
 	if (dump_sensor)
 		s5k4aa_dump_registers(sd);
 
-	err = s5k4aa_set_exposure(&sd->gspca_dev,
-				   sensor_settings[EXPOSURE_IDX]);
-	if (err < 0)
-		return err;
-
-	err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
-	if (err < 0)
-		return err;
-
-	err = s5k4aa_set_brightness(&sd->gspca_dev,
-				     sensor_settings[BRIGHTNESS_IDX]);
-	if (err < 0)
-		return err;
-
-	err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
-	if (err < 0)
-		return err;
-
-	return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	return err;
 }
 
 static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -465,36 +472,19 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	if (dmi_check_system(s5k4aa_vflip_dmi_table)) {
+	if (dmi_check_system(s5k4aa_vflip_dmi_table))
 		val = !val;
-		data = (data & 0x3f) |
-		       (!sensor_settings[HFLIP_IDX] << 6) |
-		       ((val & 0x01) << 7);
-	} else {
-		data = (data & 0x3f) |
-		(sensor_settings[HFLIP_IDX] << 6) |
-		((val & 0x01) << 7);
-	}
 
+	data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
 		return err;
 
-	if (val) {
-		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-		if (err < 0)
-			return err;
-
-		data++;
-		err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-	} else {
-		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-		if (err < 0)
-			return err;
-
-		data--;
-		err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
-	}
+	err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
+	if (err < 0)
+		return err;
+	data = (data & 0xfe) | !val;
+	err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	return err;
 }
 
@@ -530,37 +520,19 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	if (err < 0)
 		return err;
 
-	if (dmi_check_system(s5k4aa_vflip_dmi_table)) {
+	if (dmi_check_system(s5k4aa_vflip_dmi_table))
 		val = !val;
-		data = (data & 0x3f) |
-		       (!sensor_settings[VFLIP_IDX] << 7) |
-		       ((val & 0x01) << 6);
-	} else {
-		data = (data & 0x3f) |
-		       (sensor_settings[VFLIP_IDX] << 7) |
-		       ((val & 0x01) << 6);
-	}
 
 	data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
 		return err;
 
-	if (val) {
-		err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-		if (err < 0)
-			return err;
-		data++;
-		err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-		if (err < 0)
-			return err;
-	} else {
-		err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-		if (err < 0)
-			return err;
-		data--;
-		err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
-	}
+	err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
+	if (err < 0)
+		return err;
+	data = (data & 0xfe) | !val;
+	err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 	return err;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 79c3576a1938002c458ffc517668fcb944aff42e Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 12 Feb 2009 16:36:05 -0300
Subject: V4L/DVB (11690): gspca - m5602-s5k4aa: Add vflip quirk for the MSI
 L735
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 31a8ba00623..e5fed5b89ff 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -59,6 +59,12 @@ static
 			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
 		}
+	}, {
+		.ident = "MSI L735",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
+		}
 	},
 	{ }
 };
-- 
cgit v1.2.3-70-g09d2


From 951872a8198a5a336a49075320197ac5b2e5c6f1 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Tue, 10 Mar 2009 16:45:57 -0300
Subject: V4L/DVB (11691): gspca - m5602-ov9650: Add ASUS A6K vflip quirk
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The ASUS A6K needs the vflip quirk. Thanks to Marco Baldo for reporting
the issue.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 8dca1c57dcd..e0ec7a6ffa6 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -87,6 +87,13 @@ static
 			DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
 		}
 	},
+	{
+		.ident = "ASUS A6K",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
+		}
+	},
 	{
 		.ident = "Alienware Aurora m9700",
 		.matches = {
-- 
cgit v1.2.3-70-g09d2


From 1b844b536794163eb676b71e6e4c033f6d4b6b33 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Sun, 3 May 2009 15:31:55 -0300
Subject: V4L/DVB (11692): gspca - m5602: Checkpatch.pl fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_core.c    | 4 +++-
 drivers/media/video/gspca/m5602/m5602_mt9m111.c | 6 ++++--
 drivers/media/video/gspca/m5602/m5602_s5k83a.c  | 3 ++-
 3 files changed, 9 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index dd1024325fc..8a5bba16ff3 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -113,7 +113,9 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
 	if (err < 0)
 		return err;
 
-	/* Sensors with registers that only are one byte width are differently read */
+	/* Sensors with registers that are of only
+	   one byte width are differently read */
+
 	/* FIXME: This works with the ov9650, but has issues with the po1030 */
 	if (sd->sensor->i2c_regW == 1) {
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 0c9470e137e..8d071dff694 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -338,7 +338,8 @@ int mt9m111_start(struct sd *sd)
 			  (sensor_settings[VFLIP_IDX] << 0) |
 			  (sensor_settings[HFLIP_IDX] << 1);
 
-		err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
+		err = m5602_write_sensor(sd,
+					 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 		break;
 
 	case 320:
@@ -348,7 +349,8 @@ int mt9m111_start(struct sd *sd)
 				MT9M111_RMB_COLUMN_SKIP_4X |
 				(sensor_settings[VFLIP_IDX] << 0) |
 				(sensor_settings[HFLIP_IDX] << 1);
-		err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
+		err = m5602_write_sensor(sd,
+					 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 		break;
 	}
 	return err;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index df21ad19a94..7127321ace8 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -280,7 +280,8 @@ static int rotation_thread_function(void *data)
 				vflip = !vflip;
 				hflip = !hflip;
 			}
-			s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
+			s5k83a_set_flip_real((struct gspca_dev *) sd,
+					      vflip, hflip);
 		}
 
 		mutex_unlock(&sd->gspca_dev.usb_lock);
-- 
cgit v1.2.3-70-g09d2


From 1906d8d17e556510603a9281b4fa960f2d73cc37 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Sun, 3 May 2009 15:45:48 -0300
Subject: V4L/DVB (11693): gspca - stv06xx-vv6410: Add exposure ctrl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add the possibility to control the exposure on the vv6410 sensor

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | 69 +++++++++++++++++++++-
 drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h |  4 ++
 2 files changed, 72 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 69c77c932fc..f6603a9deab 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -84,8 +84,22 @@ static const struct ctrl vv6410_ctrl[] = {
 		},
 		.set = vv6410_set_analog_gain,
 		.get = vv6410_get_analog_gain
+	},
+#define EXPOSURE_IDX 3
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "exposure",
+			.minimum	= 0,
+			.maximum	= 32768,
+			.step		= 1,
+			.default_value  = 20000
+		},
+		.set = vv6410_set_exposure,
+		.get = vv6410_get_exposure
 	}
-};
+	};
 
 static int vv6410_probe(struct sd *sd)
 {
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd)
 static int vv6410_init(struct sd *sd)
 {
 	int err = 0, i;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
 		/* if NULL then len contains single value */
@@ -142,6 +157,11 @@ static int vv6410_init(struct sd *sd)
 
 	err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
 					 ARRAY_SIZE(vv6410_sensor_init));
+	if (err < 0)
+		return err;
+
+	err = vv6410_set_exposure(&sd->gspca_dev,
+				   sensor_settings[EXPOSURE_IDX]);
 
 	return (err < 0) ? err : 0;
 }
@@ -318,3 +338,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
 
 	return (err < 0) ? err : 0;
 }
+
+static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[EXPOSURE_IDX];
+
+	PDEBUG(D_V4L2, "Read exposure %d", *val);
+
+	return 0;
+}
+
+static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+	unsigned int fine, coarse;
+
+	sensor_settings[EXPOSURE_IDX] = val;
+
+	val = (val * val >> 14) + val / 4;
+
+	fine = val % VV6410_CIF_LINELENGTH;
+	coarse = min(512, val / VV6410_CIF_LINELENGTH);
+
+	PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
+	       coarse, fine);
+
+	err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
+	if (err < 0)
+		goto out;
+
+	err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
+	if (err < 0)
+		goto out;
+
+	err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
+	if (err < 0)
+		goto out;
+
+	err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
+
+out:
+	return err;
+}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 95ac55891bd..809f9226497 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -173,6 +173,8 @@
 #define VV6410_SUBSAMPLE		0x01
 #define VV6410_CROP_TO_QVGA		0x02
 
+#define VV6410_CIF_LINELENGTH		415
+
 static int vv6410_probe(struct sd *sd);
 static int vv6410_start(struct sd *sd);
 static int vv6410_init(struct sd *sd);
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
 
 const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
 	.name = "ST VV6410",
-- 
cgit v1.2.3-70-g09d2


From 28d7a20a7849e11173206db560aa76113ed4f62e Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Fri, 3 Apr 2009 17:16:42 -0300
Subject: V4L/DVB (11694): gspca - stv06xx-vv6410: No need to double set gain
 and exposure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 809f9226497..487d4055534 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -246,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = {
 	/* Pre-clock generator divide off */
 	{VV6410_DATAFORMAT,	BIT(7) | BIT(0)},
 
-	/* Exposure registers */
-	{VV6410_FINEH,		VV6410_FINE_EXPOSURE >> 8},
-	{VV6410_FINEL,		VV6410_FINE_EXPOSURE & 0xff},
-	{VV6410_COARSEH,	VV6410_COARSE_EXPOSURE >> 8},
-	{VV6410_COARSEL,	VV6410_COARSE_EXPOSURE & 0xff},
-	{VV6410_ANALOGGAIN,	0xf0 | VV6410_DEFAULT_GAIN},
 	{VV6410_CLKDIV,		VV6410_CLK_DIV_2},
 
 	/* System registers */
-- 
cgit v1.2.3-70-g09d2


From 17720e07b6ac573c8929c39f9036dbc460867b72 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Sun, 3 May 2009 15:51:36 -0300
Subject: V4L/DVB (11695): gspca - stv06xx-vv6410: Set analog gain at init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Set the analog gain at sensor init. Also set a sensible default value.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index f6603a9deab..11a0c002f5d 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -80,7 +80,7 @@ static const struct ctrl vv6410_ctrl[] = {
 			.minimum	= 0,
 			.maximum	= 15,
 			.step		= 1,
-			.default_value  = 0
+			.default_value  = 10
 		},
 		.set = vv6410_set_analog_gain,
 		.get = vv6410_get_analog_gain
@@ -162,6 +162,11 @@ static int vv6410_init(struct sd *sd)
 
 	err = vv6410_set_exposure(&sd->gspca_dev,
 				   sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = vv6410_set_analog_gain(&sd->gspca_dev,
+				      sensor_settings[GAIN_IDX]);
 
 	return (err < 0) ? err : 0;
 }
-- 
cgit v1.2.3-70-g09d2


From 484d9e0577c12f9c66a7eab799858ad9617da4bf Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@linuxtv.org>
Date: Sat, 2 May 2009 11:08:23 -0300
Subject: V4L/DVB (11698): cx23885: For tda10048 boards ensure we specify the
 I/F

Signed-off-by: Steven Toth <stoth@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 1dc070da865..07b76053a05 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -122,7 +122,9 @@ static struct tda10048_config hauppauge_hvr1200_config = {
 	.demod_address    = 0x10 >> 1,
 	.output_mode      = TDA10048_SERIAL_OUTPUT,
 	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
-	.inversion        = TDA10048_INVERSION_ON
+	.inversion        = TDA10048_INVERSION_ON,
+	.if_freq_khz      = TDA10048_IF_4300,
+	.clk_freq_khz     = TDA10048_CLK_16000,
 };
 
 static struct s5h1409_config hauppauge_ezqam_config = {
-- 
cgit v1.2.3-70-g09d2


From c7470206de9a879d8b90939a37a0d26ead114bd1 Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@linuxtv.org>
Date: Sat, 2 May 2009 11:09:08 -0300
Subject: V4L/DVB (11699): pvrusb2: Ensure we specify the I/F at attach time

Signed-off-by: Steven Toth <stoth@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-devattr.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 1cb6a260e8b..76d42d92e60 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -284,6 +284,8 @@ static struct tda10048_config hauppauge_tda10048_config = {
 	.output_mode    = TDA10048_PARALLEL_OUTPUT,
 	.fwbulkwritelen = TDA10048_BULKWRITE_50,
 	.inversion      = TDA10048_INVERSION_ON,
+	.if_freq_khz    = TDA10048_IF_4300,
+	.clk_freq_khz   = TDA10048_CLK_16000,
 };
 
 static struct tda829x_config tda829x_no_probe = {
-- 
cgit v1.2.3-70-g09d2


From f4672dffa126afe8c75bf45adc0f06c0a06d08e8 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 3 May 2009 18:01:57 -0300
Subject: V4L/DVB (11703): cx18: Have audio decoder drive SIF gain control, and
 rework AFE config

Ensure the variable gain amplifier gain for SIF is driven by the audio deocder
and not the video decoder.  This forced rework of the analog front end (AFE)
configuration to not rely on autoconfiguration, but instead set up the AFE mux,
AFE parameters, and ADC1 & ADC2 configurations explicitly.

Reported-by: Helen Buus <mythtv@hbuus.com>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-core.c | 234 ++++++++++++++++++++++----------
 1 file changed, 165 insertions(+), 69 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index cf2bd888a42..2b07b156340 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
 			     or_value);
 }
 
-static void cx18_av_initialize(struct cx18 *cx)
+static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
 {
-	struct cx18_av_state *state = &cx->av_state;
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	/*
+	 * The crystal freq used in calculations in this driver will be
+	 * 28.636360 MHz.
+	 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+	 */
+
+	/*
+	 * VDCLK  Integer = 0x0f, Post Divider = 0x04
+	 * AIMCLK Integer = 0x0e, Post Divider = 0x16
+	 */
+	cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+	/* VDCLK Fraction = 0x2be2fe */
+	/* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+	cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+	/* AIMCLK Fraction = 0x05227ad */
+	/* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+	cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+	return 0;
+}
+
+static void cx18_av_initialize(struct v4l2_subdev *sd)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
 	u32 v;
 
 	cx18_av_loadfw(cx);
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx)
 	cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
 	cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
 
+	/*
+	 * Disable Video Auto-config of the Analog Front End and Video PLL.
+	 *
+	 * Since we only use BT.656 pixel mode, which works for both 525 and 625
+	 * line systems, it's just easier for us to set registers
+	 * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
+	 * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
+	 * ourselves, than to run around cleaning up after the auto-config.
+	 *
+	 * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
+	 * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
+	 * autoconfig either.)
+	 *
+	 * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
+	 */
+	cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
+
+	/* Setup the Video and and Aux/Audio PLLs */
+	cx18_av_init(sd, 0);
+
 	/* set video to auto-detect */
 	/* Clear bits 11-12 to enable slow locking mode.  Set autodetect mode */
 	/* set the comb notch = 1 */
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx)
 	/* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
 	/* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
 
-	v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
-	v &= 0xFFFBFFFF;            /* turn OFF bit 18 for droop_comp_ch1 */
-	v &= 0xFFFF7FFF;            /* turn OFF bit 9 for clamp_sel_ch1 */
-	v &= 0xFFFFFFFE;            /* turn OFF bit 0 for 12db_ch1 */
-	/* v |= 0x00000001;*/            /* turn ON bit 0 for 12db_ch1 */
-	cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
+	/*
+	 * Analog Front End (AFE)
+	 * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
+	 *  bypass_ch[1-3]     use filter
+	 *  droop_comp_ch[1-3] disable
+	 *  clamp_en_ch[1-3]   disable
+	 *  aud_in_sel         ADC2
+	 *  luma_in_sel        ADC1
+	 *  chroma_in_sel      ADC2
+	 *  clamp_sel_ch[2-3]  midcode
+	 *  clamp_sel_ch1      video decoder
+	 *  vga_sel_ch3        audio decoder
+	 *  vga_sel_ch[1-2]    video decoder
+	 *  half_bw_ch[1-3]    disable
+	 *  +12db_ch[1-3]      disable
+	 */
+	cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
 
 /* 	if(dwEnable && dw3DCombAvailable) { */
 /*      	CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx)
 
 static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
 {
-	struct cx18 *cx = v4l2_get_subdevdata(sd);
-
-	cx18_av_initialize(cx);
-	return 0;
-}
-
-static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
-{
-	struct cx18 *cx = v4l2_get_subdevdata(sd);
-
-	/*
-	 * The crystal freq used in calculations in this driver will be
-	 * 28.636360 MHz.
-	 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
-	 */
-
-	/*
-	 * VDCLK  Integer = 0x0f, Post Divider = 0x04
-	 * AIMCLK Integer = 0x0e, Post Divider = 0x16
-	 */
-	cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
-	/* VDCLK Fraction = 0x2be2fe */
-	/* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
-	cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
-	/* AIMCLK Fraction = 0x05227ad */
-	/* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
-	cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
-	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
-	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+	cx18_av_initialize(sd);
 	return 0;
 }
 
 static int cx18_av_load_fw(struct v4l2_subdev *sd)
 {
 	struct cx18_av_state *state = to_cx18_av_state(sd);
-	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
 	if (!state->is_initialized) {
 		/* initialize on first use */
 		state->is_initialized = 1;
-		cx18_av_initialize(cx);
+		cx18_av_initialize(sd);
 	}
 	return 0;
 }
@@ -470,16 +499,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 {
 	struct cx18_av_state *state = &cx->av_state;
 	struct v4l2_subdev *sd = &state->sd;
-	u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
-			   vid_input <= CX18_AV_COMPOSITE8);
-	u8 reg;
-	u8 v;
+
+	enum analog_signal_type {
+		NONE, CVBS, Y, C, SIF, Pb, Pr
+	} ch[3] = {NONE, NONE, NONE};
+
+	u8 afe_mux_cfg;
+	u8 adc2_cfg;
+	u32 afe_cfg;
+	int i;
 
 	CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
 			    vid_input, aud_input);
 
-	if (is_composite) {
-		reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
+	if (vid_input >= CX18_AV_COMPOSITE1 &&
+	    vid_input <= CX18_AV_COMPOSITE8) {
+		afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
+		ch[0] = CVBS;
 	} else {
 		int luma = vid_input & 0xf0;
 		int chroma = vid_input & 0xf00;
@@ -493,26 +529,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 				     vid_input);
 			return -EINVAL;
 		}
-		reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
+		afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
+		ch[0] = Y;
 		if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
-			reg &= 0x3f;
-			reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
+			afe_mux_cfg &= 0x3f;
+			afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
+			ch[2] = C;
 		} else {
-			reg &= 0xcf;
-			reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
+			afe_mux_cfg &= 0xcf;
+			afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
+			ch[1] = C;
 		}
 	}
+	/* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */
 
 	switch (aud_input) {
 	case CX18_AV_AUDIO_SERIAL1:
 	case CX18_AV_AUDIO_SERIAL2:
 		/* do nothing, use serial audio input */
 		break;
-	case CX18_AV_AUDIO4: reg &= ~0x30; break;
-	case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
-	case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
-	case CX18_AV_AUDIO7: reg &= ~0xc0; break;
-	case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
+	case CX18_AV_AUDIO4:
+		afe_mux_cfg &= ~0x30;
+		ch[1] = SIF;
+		break;
+	case CX18_AV_AUDIO5:
+		afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
+		ch[1] = SIF;
+		break;
+	case CX18_AV_AUDIO6:
+		afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
+		ch[1] = SIF;
+		break;
+	case CX18_AV_AUDIO7:
+		afe_mux_cfg &= ~0xc0;
+		ch[2] = SIF;
+		break;
+	case CX18_AV_AUDIO8:
+		afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
+		ch[2] = SIF;
+		break;
 
 	default:
 		CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
@@ -520,24 +575,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 		return -EINVAL;
 	}
 
-	cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7);
+	/* Set up analog front end multiplexers */
+	cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
 	/* Set INPUT_MODE to Composite (0) or S-Video (1) */
-	cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
+	cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02);
 
 	/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
-	v = cx18_av_read(cx, 0x102);
-	if (reg & 0x80)
-		v &= ~0x2;
+	adc2_cfg = cx18_av_read(cx, 0x102);
+	if (ch[2] == NONE)
+		adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
 	else
-		v |= 0x2;
+		adc2_cfg |= 0x2;  /* Signal on CH3, set ADC2 to CH3 for input */
+
 	/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
-	if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
-		v |= 0x4;
+	if (ch[1] != NONE && ch[2] != NONE)
+		adc2_cfg |= 0x4; /* Set dual mode */
 	else
-		v &= ~0x4;
-	cx18_av_write_expect(cx, 0x102, v, v, 0x17);
+		adc2_cfg &= ~0x4; /* Clear dual mode */
+	cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
+
+	/* Configure the analog front end */
+	afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
+	afe_cfg &= 0xff000000;
+	afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
+	if (ch[1] != NONE && ch[2] != NONE)
+		afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
+
+	for (i = 0; i < 3; i++) {
+		switch (ch[i]) {
+		default:
+		case NONE:
+			/* CLAMP_SEL = Fixed to midcode clamp level */
+			afe_cfg |= (0x00000200 << i);
+			break;
+		case CVBS:
+		case Y:
+			if (i > 0)
+				afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
+			break;
+		case C:
+		case Pb:
+		case Pr:
+			/* CLAMP_SEL = Fixed to midcode clamp level */
+			afe_cfg |= (0x00000200 << i);
+			if (i == 0 && ch[i] == C)
+				afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
+			break;
+		case SIF:
+			/*
+			 * VGA_GAIN_SEL = Audio Decoder
+			 * CLAMP_SEL = Fixed to midcode clamp level
+			 */
+			afe_cfg |= (0x00000240 << i);
+			if (i == 0)
+				afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
+			break;
+		}
+	}
 
-	/*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
+	cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
 
 	state->vid_input = vid_input;
 	state->aud_input = aud_input;
-- 
cgit v1.2.3-70-g09d2


From 0fd327bd0d1b508eb64da3876098f6f43bfc1509 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Thu, 7 May 2009 13:25:32 -0300
Subject: V4L/DVB (11705): soc-camera: prepare for the platform driver
 conversion

Add a platform driver to soc_camera.c. This way we preserve backwards
compatibility with existing platforms and can start converting them one by one
to the new platform-device soc-camera interface.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/soc_camera.c | 71 +++++++++++++++++++++++++++++++++++++---
 include/media/soc_camera.h       |  5 +++
 2 files changed, 71 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 2d341f537d5..2014e9e32b3 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -16,19 +16,21 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/device.h>
-#include <linux/list.h>
 #include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/platform_device.h>
 #include <linux/vmalloc.h>
 
+#include <media/soc_camera.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
 #include <media/videobuf-core.h>
-#include <media/soc_camera.h>
 
 /* Default to VGA resolution */
 #define DEFAULT_WIDTH	640
@@ -1159,6 +1161,57 @@ void soc_camera_video_stop(struct soc_camera_device *icd)
 }
 EXPORT_SYMBOL(soc_camera_video_stop);
 
+static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
+{
+	struct soc_camera_link *icl = pdev->dev.platform_data;
+	struct i2c_adapter *adap;
+	struct i2c_client *client;
+
+	if (!icl)
+		return -EINVAL;
+
+	adap = i2c_get_adapter(icl->i2c_adapter_id);
+	if (!adap) {
+		dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
+			 icl->i2c_adapter_id);
+		/* -ENODEV and -ENXIO do not produce an error on probe()... */
+		return -ENOENT;
+	}
+
+	icl->board_info->platform_data = icl;
+	client = i2c_new_device(adap, icl->board_info);
+	if (!client) {
+		i2c_put_adapter(adap);
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, client);
+
+	return 0;
+}
+
+static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
+{
+	struct i2c_client *client = platform_get_drvdata(pdev);
+
+	if (!client)
+		return -ENODEV;
+
+	i2c_unregister_device(client);
+	i2c_put_adapter(client->adapter);
+
+	return 0;
+}
+
+static struct platform_driver __refdata soc_camera_pdrv = {
+	.probe	= soc_camera_pdrv_probe,
+	.remove	= __exit_p(soc_camera_pdrv_remove),
+	.driver	= {
+		.name = "soc-camera-pdrv",
+		.owner = THIS_MODULE,
+	},
+};
+
 static int __init soc_camera_init(void)
 {
 	int ret = bus_register(&soc_camera_bus_type);
@@ -1168,8 +1221,14 @@ static int __init soc_camera_init(void)
 	if (ret)
 		goto edrvr;
 
+	ret = platform_driver_register(&soc_camera_pdrv);
+	if (ret)
+		goto epdr;
+
 	return 0;
 
+epdr:
+	driver_unregister(&ic_drv);
 edrvr:
 	bus_unregister(&soc_camera_bus_type);
 	return ret;
@@ -1177,6 +1236,7 @@ edrvr:
 
 static void __exit soc_camera_exit(void)
 {
+	platform_driver_unregister(&soc_camera_pdrv);
 	driver_unregister(&ic_drv);
 	bus_unregister(&soc_camera_bus_type);
 }
@@ -1187,3 +1247,4 @@ module_exit(soc_camera_exit);
 MODULE_DESCRIPTION("Image capture bus driver");
 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:soc-camera-pdrv");
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index bef5e81d693..23ecead35e7 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -92,11 +92,16 @@ struct soc_camera_host_ops {
 #define SOCAM_SENSOR_INVERT_VSYNC	(1 << 3)
 #define SOCAM_SENSOR_INVERT_DATA	(1 << 4)
 
+struct i2c_board_info;
+
 struct soc_camera_link {
 	/* Camera bus id, used to match a camera and a bus */
 	int bus_id;
 	/* Per camera SOCAM_SENSOR_* bus flags */
 	unsigned long flags;
+	int i2c_adapter_id;
+	struct i2c_board_info *board_info;
+	const char *module_name;
 	/* Optional callbacks to power on or off and reset the sensor */
 	int (*power)(struct device *, int);
 	int (*reset)(struct device *);
-- 
cgit v1.2.3-70-g09d2


From 11bd199aa089e05316c487ba4d82dd7b3ac5d947 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 21 Apr 2009 04:17:59 -0300
Subject: V4L/DVB (11708): gspca - main: Version change.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 93902e828e7..e3f573041ef 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
 /*
  * Main USB camera driver
  *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
  *
  * 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
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 5, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 6, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
-- 
cgit v1.2.3-70-g09d2


From 0b119b7bf4612d6de6638a0babe93c1d8509a838 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 7 Apr 2009 05:30:31 -0300
Subject: V4L/DVB (11709): gspca - zc3xx: Bad debug level in i2c_read

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/zc3xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index c4684b9a412..08422d315e6 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
 	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)",
+	PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
 			reg, retval, retbyte);
 	return retval;
 }
-- 
cgit v1.2.3-70-g09d2


From 6929dc6b30dc3a6c9c411f677a11b866e8dd28aa Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 21 Apr 2009 13:45:56 -0300
Subject: V4L/DVB (11710): gspca - main: Webcams cannot do both isoc and bulk
 image transfers.

Let the subdrivers to set the 'image transfer by bulk' flag.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/finepix.c |  1 +
 drivers/media/video/gspca/gspca.c   | 31 +++++++++++--------------------
 drivers/media/video/gspca/gspca.h   |  2 +-
 drivers/media/video/gspca/ov534.c   |  7 +++++--
 drivers/media/video/gspca/sq905.c   |  1 +
 drivers/media/video/gspca/sq905c.c  |  1 +
 6 files changed, 20 insertions(+), 23 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 00e6863ed66..480ec5c87d0 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam->cam_mode = fpix_mode;
 	cam->nmodes = 1;
+	cam->bulk = 1;
 	cam->bulk_size = FPIX_MAX_TRANSFER;
 
 	INIT_WORK(&dev->work_struct, dostream);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e3f573041ef..873e9558040 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
  * look for an input transfer endpoint in an alternate setting
  */
 static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
-					  __u8 xfer)
+					  int xfer)
 {
 	struct usb_host_endpoint *ep;
 	int i, attr;
@@ -467,37 +467,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
 {
 	struct usb_interface *intf;
 	struct usb_host_endpoint *ep;
-	int i, ret;
+	int xfer, i, ret;
 
 	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
 	ep = NULL;
+	xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
+				   : USB_ENDPOINT_XFER_ISOC;
 	i = gspca_dev->alt;			/* previous alt setting */
-
-	/* try isoc */
 	while (--i >= 0) {
-		ep = alt_xfer(&intf->altsetting[i],
-				USB_ENDPOINT_XFER_ISOC);
+		ep = alt_xfer(&intf->altsetting[i], xfer);
 		if (ep)
 			break;
 	}
-
-	/* if no isoc, try bulk (alt 0 only) */
 	if (ep == NULL) {
-		ep = alt_xfer(&intf->altsetting[0],
-				USB_ENDPOINT_XFER_BULK);
-		if (ep == NULL) {
-			err("no transfer endpoint found");
-			return NULL;
-		}
-		i = 0;
-		gspca_dev->bulk = 1;
+		err("no transfer endpoint found");
+		return NULL;
 	}
 	PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
 			i, ep->desc.bEndpointAddress);
 	if (i > 0) {
 		ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
 		if (ret < 0) {
-			err("set interface err %d", ret);
+			err("set alt %d err %d", i, ret);
 			return NULL;
 		}
 	}
@@ -517,7 +508,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
 	/* calculate the packet size and the number of packets */
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize);
 
-	if (!gspca_dev->bulk) {			/* isoc */
+	if (!gspca_dev->cam.bulk) {		/* isoc */
 
 		/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
 		psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -617,7 +608,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 			goto out;
 
 		/* clear the bulk endpoint */
-		if (gspca_dev->bulk)
+		if (gspca_dev->cam.bulk)
 			usb_clear_halt(gspca_dev->dev,
 					gspca_dev->urb[0]->pipe);
 
@@ -630,7 +621,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 		gspca_dev->streaming = 1;
 
 		/* some bulk transfers are started by the subdriver */
-		if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
+		if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
 			break;
 
 		/* submit the URBs */
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 58e8ff02136..85bb0feddd1 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,6 +56,7 @@ struct cam {
 				 * - cannot be > MAX_NURBS
 				 * - when 0 and bulk_size != 0 means
 				 *   1 URB and submit done by subdriver */
+	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
 	u32 input_flags;	/* value for ENUM_INPUT status flags */
 };
 
@@ -168,7 +169,6 @@ struct gspca_dev {
 	__u8 iface;			/* USB interface number */
 	__u8 alt;			/* USB alternate setting */
 	__u8 nbalt;			/* number of USB alternate settings */
-	u8 bulk;			/* image transfer by 0:isoc / 1:bulk */
 };
 
 int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 19e0bc60de1..92ab92e4c79 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -708,8 +708,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
 
-	cam->bulk_size = 16384;
-	cam->bulk_nurbs = 2;
+	if (sd->sensor == SENSOR_OV772X) {
+		cam->bulk = 1;
+		cam->bulk_size = 16384;
+		cam->bulk_nurbs = 2;
+	}
 
 	return 0;
 }
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 2e1cdf068fd..715a68f0156 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct sd *dev = (struct sd *) gspca_dev;
 
 	/* We don't use the buffer gspca allocates so make it small. */
+	cam->bulk = 1;
 	cam->bulk_size = 64;
 
 	INIT_WORK(&dev->work_struct, sq905_dostream);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 0bcb74a1b14..91689250543 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		cam->nmodes = 1;
 	/* We don't use the buffer gspca allocates so make it small. */
 	cam->bulk_size = 32;
+	cam->bulk = 1;
 	INIT_WORK(&dev->work_struct, sq905c_dostream);
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2


From 30d35e49509345a3bee778e0cee8545cd70853e2 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 21 Apr 2009 13:57:31 -0300
Subject: V4L/DVB (11711): gspca - main: Fix a crash when no bandwidth
 available

When the bandwidth is not wide enough, the transfer endpoint may be set to
the one of the alternate setting 0. This one may be null and this causes a
divide by 0 oops.

Reported-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 873e9558040..efa4dd349f6 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
 	for (i = 0; i < alt->desc.bNumEndpoints; i++) {
 		ep = &alt->endpoint[i];
 		attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-		if (attr == xfer)
+		if (attr == xfer
+		    && ep->desc.wMaxPacketSize != 0)
 			return ep;
 	}
 	return NULL;
-- 
cgit v1.2.3-70-g09d2


From 8dd07ef1236356222207058ee6a83c24cc896e8d Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 21 Apr 2009 14:05:44 -0300
Subject: V4L/DVB (11712): gspca - main:  Set the current alternate setting
 only when needed

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index efa4dd349f6..ebeae6bdacc 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -486,7 +486,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
 	}
 	PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
 			i, ep->desc.bEndpointAddress);
-	if (i > 0) {
+	if (gspca_dev->nbalt > 1) {
 		ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
 		if (ret < 0) {
 			err("set alt %d err %d", i, ret);
@@ -653,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
 {
 	int ret;
 
+	if (gspca_dev->alt == 0)
+		return 0;
 	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
 	if (ret < 0)
 		PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
-- 
cgit v1.2.3-70-g09d2


From ed47119fb7c7890605379b23180d1b09717b6b5d Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Thu, 23 Apr 2009 13:52:27 -0300
Subject: V4L/DVB (11713): gspca - ov534: Don't discard the images when no UVC
 EOF

A new image may start without any UVC EOF in the last packet of the
previous image.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov534.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 92ab92e4c79..6d9b102be70 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -867,18 +867,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 
 		/* If PTS or FID has changed, start a new frame. */
 		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-					NULL, 0);
+			if (gspca_dev->last_packet_type == INTER_PACKET)
+				frame = gspca_frame_add(gspca_dev,
+							LAST_PACKET, frame,
+							NULL, 0);
 			sd->last_pts = this_pts;
 			sd->last_fid = this_fid;
-		}
-
-		/* Add the data from this payload */
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
 					data + 12, len - 12);
-
 		/* If this packet is marked as EOF, end the frame */
-		if (data[1] & UVC_STREAM_EOF) {
+		} else if (data[1] & UVC_STREAM_EOF) {
 			sd->last_pts = 0;
 
 			if (frame->data_end - frame->data !=
@@ -886,11 +884,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 				PDEBUG(D_PACK, "short frame");
 				goto discard;
 			}
-
 			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						NULL, 0);
+						data + 12, len - 12);
+		} else {
+
+			/* Add the data from this payload */
+			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+						data + 12, len - 12);
 		}
 
+
 		/* Done this payload */
 		goto scan_next;
 
-- 
cgit v1.2.3-70-g09d2


From 59746e1390835ce889e56fa4e792019462465623 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Thu, 23 Apr 2009 14:33:00 -0300
Subject: V4L/DVB (11714): gspca - spca500 and sunplus: Change the 0x00
 insertion mechanism.

The new mechanism does not use any temporary buffer.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca500.c | 33 +++++++++++++--------------------
 drivers/media/video/gspca/sunplus.c | 33 +++++++++++++--------------------
 2 files changed, 26 insertions(+), 40 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 6f38fa6d86b..8806b2ff82b 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	__u8 packet[ISO_MAX_SIZE + 128];
-				 /* !! no more than 128 ff in an ISO packet */
-
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	__u8 *s, *d;
 	static __u8 ffd9[] = {0xff, 0xd9};
 
 /* frames are jpeg 4.1.1 without 0xff escape */
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	}
 
 	/* add 0x00 after 0xff */
-	for (i = len; --i >= 0; )
-		if (data[i] == 0xff)
-			break;
-	if (i < 0) {			/* no 0xff */
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
-		return;
-	}
-	s = data;
-	d = sd->packet;
-	for (i = 0; i < len; i++) {
-		*d++ = *s++;
-		if (s[-1] == 0xff)
-			*d++ = 0x00;
-	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			sd->packet, d - sd->packet);
+	i = 0;
+	do {
+		if (data[i] == 0xff) {
+			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+					data, i + 1);
+			len -= i;
+			data += i;
+			*data = 0x00;
+			i = 0;
+		}
+		i++;
+	} while (i < len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index c2b8c10c075..9623f294bda 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	__u8 packet[ISO_MAX_SIZE + 128];
-				/* !! no more than 128 ff in an ISO packet */
-
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, sof = 0;
-	unsigned char *s, *d;
 	static unsigned char ffd9[] = {0xff, 0xd9};
 
 /* frames are jpeg 4.1.1 without 0xff escape */
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	}
 
 	/* add 0x00 after 0xff */
-	for (i = len; --i >= 0; )
-		if (data[i] == 0xff)
-			break;
-	if (i < 0) {			/* no 0xff */
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
-		return;
-	}
-	s = data;
-	d = sd->packet;
-	for (i = 0; i < len; i++) {
-		*d++ = *s++;
-		if (s[-1] == 0xff)
-			*d++ = 0x00;
-	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			sd->packet, d - sd->packet);
+	i = 0;
+	do {
+		if (data[i] == 0xff) {
+			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+					data, i + 1);
+			len -= i;
+			data += i;
+			*data = 0x00;
+			i = 0;
+		}
+		i++;
+	} while (i < len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
-- 
cgit v1.2.3-70-g09d2


From 49cb6b046da812d9c1d1f8c958b741126ee4eece Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Sat, 25 Apr 2009 13:29:01 -0300
Subject: V4L/DVB (11715): gspca - main: Set the number of packets per ISOC
 message.

The number of packets per isochronous message may now be set by the subdrivers
(default value 32).

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c  |  6 +++---
 drivers/media/video/gspca/gspca.h  |  4 ++--
 drivers/media/video/gspca/sonixb.c |  2 ++
 drivers/media/video/gspca/sonixj.c |  1 +
 drivers/media/video/gspca/vc032x.c | 14 +++++++++++++-
 5 files changed, 21 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index ebeae6bdacc..ae0e14033d6 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -513,9 +513,9 @@ static int create_urbs(struct gspca_dev *gspca_dev,
 
 		/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
 		psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-		npkt = ISO_MAX_SIZE / psize;
-		if (npkt > ISO_MAX_PKT)
-			npkt = ISO_MAX_PKT;
+		npkt = gspca_dev->cam.npkt;
+		if (npkt == 0)
+			npkt = 32;		/* default value */
 		bsize = psize * npkt;
 		PDEBUG(D_STREAM,
 			"isoc %d pkts size %d = bsize:%d",
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 85bb0feddd1..bd1faff8864 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -44,8 +44,6 @@ extern int gspca_debug;
 #define GSPCA_MAX_FRAMES 16	/* maximum number of video frame buffers */
 /* image transfers */
 #define MAX_NURBS 4		/* max number of URBs */
-#define ISO_MAX_PKT 32		/* max number of packets in an ISOC transfer */
-#define ISO_MAX_SIZE 0x8000	/* max size of one URB buffer (32 Kb) */
 
 /* device information - set at probe time */
 struct cam {
@@ -57,6 +55,8 @@ struct cam {
 				 * - when 0 and bulk_size != 0 means
 				 *   1 URB and submit done by subdriver */
 	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
+	u8 npkt;		/* number of packets in an ISOC message
+				 * 0 is the default value: 32 packets */
 	u32 input_flags;	/* value for ENUM_INPUT status flags */
 };
 
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 153d0a91d4b..cf3af8de6e9 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		cam->cam_mode = sif_mode;
 		cam->nmodes = ARRAY_SIZE(sif_mode);
 	}
+	cam->npkt = 36;			/* 36 packets per ISOC message */
+
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index c72e19d3ac3..e58ac891b20 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
+	cam->npkt = 24;			/* 24 packets per ISOC message */
 
 	sd->bridge = id->driver_info >> 16;
 	sd->sensor = id->driver_info >> 8;
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index e4e933c400b..30872cd047c 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -42,7 +42,7 @@ struct sd {
 	char bridge;
 #define BRIDGE_VC0321 0
 #define BRIDGE_VC0323 1
-	char sensor;
+	u8 sensor;
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
 #define SENSOR_MI1310_SOC 2
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct usb_device *dev = gspca_dev->dev;
 	struct cam *cam;
 	int sensor;
+	static u8 npkt[] = {	/* number of packets per ISOC message */
+		64,		/* HV7131R 0 */
+		32,		/* MI0360 1 */
+		32,		/* MI1310_SOC 2 */
+		64,		/* MI1320 3 */
+		128,		/* MI1320_SOC 4 */
+		32,		/* OV7660 5 */
+		64,		/* OV7670 6 */
+		128,		/* PO1200 7 */
+		128,		/* PO3130NC 8 */
+	};
 
 	cam = &gspca_dev->cam;
 	sd->bridge = id->driver_info;
@@ -2515,6 +2526,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 			break;
 		}
 	}
+	cam->npkt = npkt[sd->sensor];
 
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
-- 
cgit v1.2.3-70-g09d2


From c8b9b2cad435544177a2b7eed1c59438945de68b Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Sun, 26 Apr 2009 14:46:12 -0300
Subject: V4L/DVB (11716): gspca - sonixj: Adjust some exchanges according to
 traces

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 59 ++++++++++++++++++--------------------
 1 file changed, 28 insertions(+), 31 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index e58ac891b20..3f8a73e0aca 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -62,7 +62,6 @@ struct sd {
 #define BRIDGE_SN9C105 1
 #define BRIDGE_SN9C110 2
 #define BRIDGE_SN9C120 3
-#define BRIDGE_SN9C325 4
 	u8 sensor;			/* Type of image sensor chip */
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = {
 
 static const u8 sn_ov7660[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
-	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
+	0x00,	0x61,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x21,	0x07,	0x00,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x01,	0x01,	0x08,	0x28,	0x1e,	0x20,
 /*	reg18	reg19	reg1a	reg1b */
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = {
 	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
 	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
 	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
+	{0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
 /****** (some exchanges in the win trace) ******/
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
 						/* bits[3..0]reserved */
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 	const u8 *reg9a;
 	static const u8 reg9a_def[] =
-		{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
-	static const u8 reg9a_sn9c325[] =
-		{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
+		{0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
+	static const u8 reg9a_spec[] =
+		{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
 	static const u8 regd4[] = {0x60, 0x00, 0x00};
 
 	reg_w1(gspca_dev, 0xf1, 0x00);
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 	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 len was 3 */
-	switch (sd->bridge) {
-	case BRIDGE_SN9C325:
-		reg9a = reg9a_sn9c325;
+	switch (sd->sensor) {
+	case SENSOR_OV7660:
+	case SENSOR_SP80708:
+		reg9a = reg9a_spec;
 		break;
 	default:
 		reg9a = reg9a_def;
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 		reg_w1(gspca_dev, 0x17, 0x64);
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
-/*jfm: from win trace */
 	case SENSOR_OV7630:
 		reg_w1(gspca_dev, 0x01, 0x61);
 		reg_w1(gspca_dev, 0x17, 0xe2);
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x01, 0x63);
 		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x62);
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
-/*jfm: from win trace */
 	case SENSOR_OV7660:
-		if (sd->bridge == BRIDGE_SN9C120) {
-			reg_w1(gspca_dev, 0x01, 0x61);
-			reg_w1(gspca_dev, 0x17, 0x20);
-			reg_w1(gspca_dev, 0x01, 0x60);
-			reg_w1(gspca_dev, 0x01, 0x40);
-			break;
-		}
-		/* fall thru */
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x01, 0x63);
 		reg_w1(gspca_dev, 0x17, 0x20);
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 		mdelay(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
+/*	case SENSOR_HV7131R: */
+/*	case SENSOR_MI0360: */
+/*	case SENSOR_MO4000: */
 	default:
 		reg_w1(gspca_dev, 0x01, 0x43);
 		reg_w1(gspca_dev, 0x17, 0x61);
@@ -1684,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	case SENSOR_OV7648:
 		reg17 = 0x20;
 		break;
-/*jfm: from win trace */
 	case SENSOR_OV7660:
-		if (sd->bridge == BRIDGE_SN9C120) {
-			reg17 = 0xa0;
-			break;
-		}
-		/* fall thru */
+		reg17 = 0xa0;
+		break;
 	default:
 		reg17 = 0x60;
 		break;
@@ -1715,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w1(gspca_dev, 0x9a, 0x0a);
 		reg_w1(gspca_dev, 0x99, 0x60);
 		break;
+	case SENSOR_OV7660:
+		reg_w1(gspca_dev, 0x9a, 0x05);
+		if (sd->bridge == BRIDGE_SN9C105)
+			reg_w1(gspca_dev, 0x99, 0xff);
+		else
+			reg_w1(gspca_dev, 0x99, 0x5b);
+		break;
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x9a, 0x05);
 		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
-	case SENSOR_OV7660:
-		if (sd->bridge == BRIDGE_SN9C120) {
-			reg_w1(gspca_dev, 0x9a, 0x05);
-			break;
-		}
-		/* fall thru */
 	default:
 		reg_w1(gspca_dev, 0x9a, 0x08);
 		reg_w1(gspca_dev, 0x99, 0x59);
-- 
cgit v1.2.3-70-g09d2


From ceec80e5a52580bd7b257c14c6c8355be58c971f Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Sat, 9 May 2009 06:21:35 -0300
Subject: V4L/DVB (11717): gspca - sonixj: Webcams with bridge sn9c128 added

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/gspca.txt | 5 +++++
 drivers/media/video/gspca/sonixj.c  | 5 +++++
 2 files changed, 10 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index e418a8fb9c6..fd07d331f4e 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -266,6 +266,11 @@ sonixj		0c45:60ec	SN9C105+MO4000
 sonixj		0c45:60fb	Surfer NoName
 sonixj		0c45:60fc	LG-LIC300
 sonixj		0c45:60fe	Microdia Audio
+sonixj		0c45:6100	PC Camera (SN9C128)
+sonixj		0c45:610a	PC Camera (SN9C128)
+sonixj		0c45:610b	PC Camera (SN9C128)
+sonixj		0c45:610c	PC Camera (SN9C128)
+sonixj		0c45:610e	PC Camera (SN9C128)
 sonixj		0c45:6128	Microdia/Sonix SNP325
 sonixj		0c45:612a	Avant Camera
 sonixj		0c45:612c	Typhoon Rasy Cam 1.3MPix
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3f8a73e0aca..77be80d18a7 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -2209,7 +2209,12 @@ static const __devinitdata struct usb_device_id device_table[] = {
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
 #endif
+	{USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
 /*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
 /*	{USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
 /*	{USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
 	{USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
-- 
cgit v1.2.3-70-g09d2


From 2c9561088b14c19ce9d970d2b67b48e103cf2dd7 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 5 May 2009 04:59:45 -0300
Subject: V4L/DVB (11718): gspca - vc032x: Bad pixelformat for mi1320_soc

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/vc032x.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 30872cd047c..460ce3dad7c 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = {
 		.priv = 2},
 };
 static const struct v4l2_pix_format bi_mode[] = {
-	{320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 		.bytesperline = 320,
 		.sizeimage = 320 * 240 * 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 2},
-	{640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 		.bytesperline = 640,
 		.sizeimage = 640 * 480 * 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
-	{1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+	{1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 		.bytesperline = 1280,
 		.sizeimage = 1280 * 1024 * 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
-- 
cgit v1.2.3-70-g09d2


From d1ba6f15c87d64791da7c21d852b62dfbcc472b7 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Tue, 5 May 2009 05:01:11 -0300
Subject: V4L/DVB (11719): gspca - vc032x: mi1320_soc images are upside-down

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/vc032x.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 460ce3dad7c..26dd155efcc 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2519,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		case SENSOR_MI1320_SOC:
 			cam->cam_mode = bi_mode;
 			cam->nmodes = ARRAY_SIZE(bi_mode);
+			cam->input_flags = V4L2_IN_ST_VFLIP |
+					   V4L2_IN_ST_HFLIP;
 			break;
 		default:
 			cam->cam_mode = vc0323_mode;
-- 
cgit v1.2.3-70-g09d2


From f8eaaf4f2a2810d6e486da2916ef07f7e00665c9 Mon Sep 17 00:00:00 2001
From: Jani Monoses <jani@ubuntu.com>
Date: Thu, 7 May 2009 03:32:27 -0300
Subject: V4L/DVB (11720): gspca - sonixj: Webcam 06f8:3008 added

Signed-off-by: Jani Monoses <jani@ubuntu.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/gspca.txt | 1 +
 drivers/media/video/gspca/sonixj.c  | 1 +
 2 files changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index fd07d331f4e..1bb103fe9b8 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -178,6 +178,7 @@ spca506		06e1:a190	ADS Instant VCD
 ov534		06f8:3002	Hercules Blog Webcam
 ov534		06f8:3003	Hercules Dualpix HD Weblog
 sonixj		06f8:3004	Hercules Classic Silver
+sonixj		06f8:3008	Hercules Deluxe Optical Glass
 spca508		0733:0110	ViewQuest VQ110
 spca508		0130:0130	Clone Digital Webcam 11043
 spca501		0733:0401	Intel Create and Share
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 77be80d18a7..dc6a6f11354 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -2191,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
 	{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
 	{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
 	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
 /* bw600.inf:
 	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
-- 
cgit v1.2.3-70-g09d2


From 7b5cb558381607d7e0d04f49d16dd3825ca5261a Mon Sep 17 00:00:00 2001
From: Roel Kluin <roel.kluin@gmail.com>
Date: Sun, 26 Apr 2009 12:31:26 -0300
Subject: V4L/DVB: cx23885/cymax2: binary/logical &/&& typo

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cimax2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 9a6536998d9..08582e58bdb 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -312,7 +312,7 @@ static void netup_read_ci_status(struct work_struct *work)
 		"TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
 		buf[32]);
 
-	if (buf[0] && 1)
+	if (buf[0] & 1)
 		state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
 			DVB_CA_EN50221_POLL_CAM_READY;
 	else
-- 
cgit v1.2.3-70-g09d2


From c9adb4314f0cd2be9304cef8342d71464becb40e Mon Sep 17 00:00:00 2001
From: Magnus Damm <damm@igel.co.jp>
Date: Tue, 28 Apr 2009 05:45:39 -0300
Subject: V4L/DVB (11731): buf-dma-contig: remove sync operation

Remove the videobuf-dma-contig sync operation. Sync is only needed
for noncoherent buffers, and since videobuf-dma-contig is built on
coherent memory allocators the memory is by definition always in sync.

Reported-by: Matthieu CASTET <matthieu.castet@parrot.com>
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Reviewed-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/videobuf-dma-contig.c | 14 --------------
 1 file changed, 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 6109fb5f34e..08d3e17c450 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -182,19 +182,6 @@ static int __videobuf_iolock(struct videobuf_queue *q,
 	return 0;
 }
 
-static int __videobuf_sync(struct videobuf_queue *q,
-			   struct videobuf_buffer *buf)
-{
-	struct videobuf_dma_contig_memory *mem = buf->priv;
-
-	BUG_ON(!mem);
-	MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
-	dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
-				DMA_FROM_DEVICE);
-	return 0;
-}
-
 static int __videobuf_mmap_free(struct videobuf_queue *q)
 {
 	unsigned int i;
@@ -356,7 +343,6 @@ static struct videobuf_qtype_ops qops = {
 
 	.alloc        = __videobuf_alloc,
 	.iolock       = __videobuf_iolock,
-	.sync         = __videobuf_sync,
 	.mmap_free    = __videobuf_mmap_free,
 	.mmap_mapper  = __videobuf_mmap_mapper,
 	.video_copy_to_user = __videobuf_copy_to_user,
-- 
cgit v1.2.3-70-g09d2


From be4a1a2209b5c6e6895e0b828a24df04ecb9d40f Mon Sep 17 00:00:00 2001
From: hermann pitton <hermann-pitton@arcor.de>
Date: Tue, 28 Apr 2009 19:44:05 -0300
Subject: V4L/DVB (11732): saa7134: disable not yet existing IR and DVB support
 on the Compro T750

The Compro VideoMate T750 has no support for IR and DVB-T yet.
Disable both to avoid fall through and confusing printouts.

Signed-off-by: Hermann Pitton <hermann-pitton@arcor.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-cards.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 40e620284f5..0eced41443e 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4787,7 +4787,6 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs = {{
 			.name   = name_tv,
 			.vmux   = 3,
@@ -6481,7 +6480,6 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
-	case SAA7134_BOARD_VIDEOMATE_T750:
 	case SAA7134_BOARD_MANLI_MTV001:
 	case SAA7134_BOARD_MANLI_MTV002:
 	case SAA7134_BOARD_BEHOLD_409FM:
-- 
cgit v1.2.3-70-g09d2


From 82aa98fd9279dfe3e36679b7529f7b962939150e Mon Sep 17 00:00:00 2001
From: Dmitri Belimov <d.belimov@gmail.com>
Date: Tue, 28 Apr 2009 06:41:08 -0300
Subject: V4L/DVB (11733): increase MPEG encoder timout

If video has a lot of changes in frame, MPEG encoder need more time for
coding process. Add new bigger timeout for encoder.

This is patch from our customer. I checked this.

Signed-off-by: Alexey Osipov <lion-simba@pridelands.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-ts.c | 2 +-
 drivers/media/video/saa7134/saa7134.h    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index cc8b923afbc..b8ff459d0d3 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -65,7 +65,7 @@ static int buffer_activate(struct saa7134_dev *dev,
 	/* start DMA */
 	saa7134_set_dmabits(dev);
 
-	mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
+	mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
 
 	if (dev->ts_state == SAA7134_TS_BUFF_DONE) {
 		/* Clear TS cache */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 1d190e5e1ac..8229ab21322 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -376,6 +376,7 @@ struct saa7134_board {
 #define INTERLACE_OFF          2
 
 #define BUFFER_TIMEOUT     msecs_to_jiffies(500)  /* 0.5 seconds */
+#define TS_BUFFER_TIMEOUT  msecs_to_jiffies(1000)  /* 1 second */
 
 struct saa7134_dev;
 struct saa7134_dma;
-- 
cgit v1.2.3-70-g09d2


From 2ec3475609aa70cd0d9ea218c5d4e915a3caef49 Mon Sep 17 00:00:00 2001
From: Dmitri Belimov <d.belimov@gmail.com>
Date: Tue, 28 Apr 2009 06:46:15 -0300
Subject: V4L/DVB (11734): remove hw reset of MPEG encoder when lost/found seq.

When we capture signal from composite input offen lost and found syncro
sequence. In this case the MPEG coder hardware reset after each
lost/found event. The image has a lot of artefactes. This patch remove
hardware reset of MPEG encoder.

This is patch from our customer. I checked this.

With my best regards, Dmitry.

Signed-off-by: Alexey Osipov <lion-simba@pridelands.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-empress.c | 3 ---
 1 file changed, 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 9db3472667e..097c2dfebd2 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -491,11 +491,8 @@ static void empress_signal_update(struct work_struct *work)
 
 	if (dev->nosignal) {
 		dprintk("no video signal\n");
-		ts_reset_encoder(dev);
 	} else {
 		dprintk("video signal acquired\n");
-		if (atomic_read(&dev->empress_users))
-			ts_init_encoder(dev);
 	}
 }
 
-- 
cgit v1.2.3-70-g09d2


From 3e9a489743ea87663e9ff638cb9b8fe13805a327 Mon Sep 17 00:00:00 2001
From: Pieter Van Schaik <vansterpc@gmail.com>
Date: Wed, 29 Apr 2009 03:55:31 -0300
Subject: V4L/DVB (11735): Enables the Winfast TV2000 XP Global TV IR

Adds support to the remote control of the Winfast TV2000 XP Global TV
capture card. A case statement was added in order to initialize the
GPIO data structures as well as a case statement for handling the keys
correctly when pressed.

Thanks to Hermann and Mauro for all the help

Signed-off-by: Pieter C van Schaik <vansterpc@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-input.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index bd2baa76203..8a7c2bc457a 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -91,6 +91,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
 		gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
 		break;
 	case CX88_BOARD_WINFAST_DTV1000:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 		gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
 		auxgpio = gpio;
 		break;
@@ -231,6 +232,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 		break;
 	case CX88_BOARD_WINFAST2000XP_EXPERT:
 	case CX88_BOARD_WINFAST_DTV1000:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 		ir_codes = ir_codes_winfast;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
-- 
cgit v1.2.3-70-g09d2


From 925d74ae717c9a12d3618eb4b36b9fb632e2cef3 Mon Sep 17 00:00:00 2001
From: Németh Márton <nm127@freemail.hu>
Date: Wed, 29 Apr 2009 15:57:24 -0300
Subject: V4L/DVB (11736): videobuf: modify return value of VIDIOC_REQBUFS
 ioctl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The V4L2 ioctls usually return 0 when the operation was successful
and -1 in case of error. Currently VIDIOC_REQBUFS returns the
number of buffers which is redundant because this information is
available in count field of struct v4l2_requestbuffers. The
V4L2 API specification, revision 0.24 [1] explicitly specifies for
VIDIOC_REQBUFS that the return value shall be 0 on success.

The patch was tested with v4l-test 0.13 [2] with vivi driver.

References:
[1] V4L2 API specification, revision 0.24
    http://v4l2spec.bytesex.org/spec/r13696.htm

[2] v4l-test: Test environment for Video For Linux Two API
    http://v4l-test.sourceforge.net/

Signed-off-by: Márton Németh <nm127@freemail.hu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/videobuf-core.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index b7b05842cf2..29b3c693a8e 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -439,6 +439,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
 	}
 
 	req->count = retval;
+	retval = 0;
 
  done:
 	mutex_unlock(&q->vb_lock);
-- 
cgit v1.2.3-70-g09d2


From 413ef8a20ae4c12f2462385ac2eebf51a6feabea Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Thu, 30 Apr 2009 05:40:07 -0300
Subject: V4L/DVB (11737): Drop stray references to i2c_probe

The new i2c binding model doesn't use i2c_probe.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tea6415c.c | 1 -
 drivers/media/video/tea6420.c  | 1 -
 2 files changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index d4a9ed45764..1585839bd0b 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -141,7 +141,6 @@ static const struct v4l2_subdev_ops tea6415c_ops = {
 	.video = &tea6415c_video_ops,
 };
 
-/* this function is called by i2c_probe */
 static int tea6415c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index ced6eadf347..0446524d354 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -112,7 +112,6 @@ static const struct v4l2_subdev_ops tea6420_ops = {
 	.audio = &tea6420_audio_ops,
 };
 
-/* this function is called by i2c_probe */
 static int tea6420_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-- 
cgit v1.2.3-70-g09d2


From ca19d84295c2579229c5478db8b0f9cd7e821685 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@suse.de>
Date: Thu, 30 Apr 2009 19:18:08 -0300
Subject: V4L/DVB (11739): remove driver_data direct access of struct device

In the near future, the driver core is going to not allow direct access
to the driver_data pointer in struct device.  Instead, the functions
dev_get_drvdata() and dev_set_drvdata() should be used.  These functions
have been around since the beginning, so are backwards compatible with
all older kernel versions.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/dvb/firewire/firedtv-1394.c   |  4 ++--
 drivers/media/dvb/firewire/firedtv-dvb.c    |  2 +-
 drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 22 +++++++++++-----------
 3 files changed, 14 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 4e207658c5d..2b6eeeab5b2 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -225,7 +225,7 @@ fail_free:
 
 static int node_remove(struct device *dev)
 {
-	struct firedtv *fdtv = dev->driver_data;
+	struct firedtv *fdtv = dev_get_drvdata(dev);
 
 	fdtv_dvb_unregister(fdtv);
 
@@ -242,7 +242,7 @@ static int node_remove(struct device *dev)
 
 static int node_update(struct unit_directory *ud)
 {
-	struct firedtv *fdtv = ud->device.driver_data;
+	struct firedtv *fdtv = dev_get_drvdata(&ud->device);
 
 	if (fdtv->isochannel >= 0)
 		cmp_establish_pp_connection(fdtv, fdtv->subunit,
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 9d308dd32a5..5742fde79d9 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -268,7 +268,7 @@ struct firedtv *fdtv_alloc(struct device *dev,
 	if (!fdtv)
 		return NULL;
 
-	dev->driver_data	= fdtv;
+	dev_set_drvdata(dev, fdtv);
 	fdtv->device		= dev;
 	fdtv->isochannel	= -1;
 	fdtv->voltage		= 0xff;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 299c1cbc383..6c23456e0bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -539,7 +539,7 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
 					 &sfp->attr_unit_number);
 	}
 	pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
-	sfp->class_dev->driver_data = NULL;
+	dev_set_drvdata(sfp->class_dev, NULL);
 	device_unregister(sfp->class_dev);
 	sfp->class_dev = NULL;
 }
@@ -549,7 +549,7 @@ static ssize_t v4l_minor_number_show(struct device *class_dev,
 				     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -561,7 +561,7 @@ static ssize_t bus_info_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_bus_info(sfp->channel.hdw));
@@ -572,7 +572,7 @@ static ssize_t hdw_name_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_type(sfp->channel.hdw));
@@ -583,7 +583,7 @@ static ssize_t hdw_desc_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%s\n",
 			 pvr2_hdw_get_desc(sfp->channel.hdw));
@@ -595,7 +595,7 @@ static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
 					   char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -607,7 +607,7 @@ static ssize_t unit_number_show(struct device *class_dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return scnprintf(buf,PAGE_SIZE,"%d\n",
 			 pvr2_hdw_get_unit_number(sfp->channel.hdw));
@@ -635,7 +635,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
 	class_dev->parent = &usb_dev->dev;
 
 	sfp->class_dev = class_dev;
-	class_dev->driver_data = sfp;
+	dev_set_drvdata(class_dev, sfp);
 	ret = device_register(class_dev);
 	if (ret) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -792,7 +792,7 @@ static ssize_t debuginfo_show(struct device *class_dev,
 			      struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	pvr2_hdw_trigger_module_log(sfp->channel.hdw);
 	return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
@@ -803,7 +803,7 @@ static ssize_t debugcmd_show(struct device *class_dev,
 			     struct device_attribute *attr, char *buf)
 {
 	struct pvr2_sysfs *sfp;
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 	return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
 }
@@ -816,7 +816,7 @@ static ssize_t debugcmd_store(struct device *class_dev,
 	struct pvr2_sysfs *sfp;
 	int ret;
 
-	sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+	sfp = dev_get_drvdata(class_dev);
 	if (!sfp) return -EINVAL;
 
 	ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
-- 
cgit v1.2.3-70-g09d2


From 223ffe5f8270ba9d069f1cbff9acec095a6f58b1 Mon Sep 17 00:00:00 2001
From: Roel Kluin <roel.kluin@gmail.com>
Date: Sat, 2 May 2009 16:38:47 -0300
Subject: V4L/DVB: cleanup redundant tests on unsigned

Remove redundant tests on unsigned.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/dvb/ttpci/av7110_v4l.c            | 2 +-
 drivers/media/dvb/ttpci/budget-av.c             | 2 +-
 drivers/media/video/cpia2/cpia2_v4l.c           | 6 +++---
 drivers/media/video/hexium_gemini.c             | 2 +-
 drivers/media/video/hexium_orion.c              | 2 +-
 drivers/media/video/ivtv/ivtv-ioctl.c           | 2 +-
 drivers/media/video/mxb.c                       | 4 ++--
 drivers/media/video/pvrusb2/pvrusb2-v4l2.c      | 4 ++--
 drivers/media/video/pwc/pwc-v4l.c               | 2 +-
 drivers/media/video/stk-webcam.c                | 4 ++--
 drivers/media/video/usbvision/usbvision-video.c | 2 +-
 drivers/media/video/videobuf-core.c             | 4 ++--
 12 files changed, 18 insertions(+), 18 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index 2210cff738e..ce64c6214cc 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -458,7 +458,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 	dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
 
 	if (av7110->analog_tuner_flags) {
-		if (i->index < 0 || i->index >= 4)
+		if (i->index >= 4)
 			return -EINVAL;
 	} else {
 		if (i->index != 0)
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 855fe74b640..8ea91522767 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1413,7 +1413,7 @@ static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 {
 	dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
-	if (i->index < 0 || i->index >= KNC1_INPUTS)
+	if (i->index >= KNC1_INPUTS)
 		return -EINVAL;
 	memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
 	return 0;
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index d4099f5312a..0b4a8f309cf 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1064,7 +1064,7 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
 
 	switch(m->id) {
 	case CPIA2_CID_FLICKER_MODE:
-		if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS)
+		if (m->index >= NUM_FLICKER_CONTROLS)
 			return -EINVAL;
 
 		strcpy(m->name, flicker_controls[m->index].name);
@@ -1082,14 +1082,14 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
 					maximum = i;
 			}
 		}
-		if(m->index < 0 || m->index > maximum)
+		if (m->index > maximum)
 			return -EINVAL;
 
 		strcpy(m->name, framerate_controls[m->index].name);
 		break;
 	    }
 	case CPIA2_CID_LIGHTS:
-		if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS)
+		if (m->index >= NUM_LIGHTS_CONTROLS)
 			return -EINVAL;
 
 		strcpy(m->name, lights_controls[m->index].name);
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 8e1463ee1b6..71c211402eb 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -224,7 +224,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 {
 	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
 
-	if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+	if (i->index >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 2bc39f62845..39d65ca41c6 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -325,7 +325,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 {
 	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
 
-	if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+	if (i->index >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c342a9fe983..99f3c39a118 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -709,7 +709,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
 	else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
 			regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
 		reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
-	else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
+	else if (regs->reg < IVTV_ENCODER_SIZE)
 		reg_start = itv->enc_mem;
 	else
 		return -EINVAL;
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 3be5a71bdac..35890e8b243 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -453,7 +453,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 {
 	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-	if (i->index < 0 || i->index >= MXB_INPUTS)
+	if (i->index >= MXB_INPUTS)
 		return -EINVAL;
 	memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
 	return 0;
@@ -616,7 +616,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 
-	if (a->index < 0 || a->index > MXB_INPUTS) {
+	if (a->index > MXB_INPUTS) {
 		DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 9e0f2b07b93..24b3c1d9498 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -267,7 +267,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(&tmp,0,sizeof(tmp));
 		tmp.index = vi->index;
 		ret = 0;
-		if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+		if (vi->index >= fh->input_cnt) {
 			ret = -EINVAL;
 			break;
 		}
@@ -331,7 +331,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	case VIDIOC_S_INPUT:
 	{
 		struct v4l2_input *vi = (struct v4l2_input *)arg;
-		if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+		if (vi->index >= fh->input_cnt) {
 			ret = -ERANGE;
 			break;
 		}
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index bc0a464295c..2876ce08451 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1107,7 +1107,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 				return -EINVAL;
 			if (buf->memory != V4L2_MEMORY_MMAP)
 				return -EINVAL;
-			if (buf->index < 0 || buf->index >= pwc_mbufs)
+			if (buf->index >= pwc_mbufs)
 				return -EINVAL;
 
 			buf->flags |= V4L2_BUF_FLAG_QUEUED;
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 1a6d39cbd6f..2e593704727 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -1137,7 +1137,7 @@ static int stk_vidioc_querybuf(struct file *filp,
 	struct stk_camera *dev = priv;
 	struct stk_sio_buffer *sbuf;
 
-	if (buf->index < 0 || buf->index >= dev->n_sbufs)
+	if (buf->index >= dev->n_sbufs)
 		return -EINVAL;
 	sbuf = dev->sio_bufs + buf->index;
 	*buf = sbuf->v4lbuf;
@@ -1154,7 +1154,7 @@ static int stk_vidioc_qbuf(struct file *filp,
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
-	if (buf->index < 0 || buf->index >= dev->n_sbufs)
+	if (buf->index >= dev->n_sbufs)
 		return -EINVAL;
 	sbuf = dev->sio_bufs + buf->index;
 	if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED)
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d7056a5b7f9..d03e5922d3b 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -541,7 +541,7 @@ static int vidioc_enum_input (struct file *file, void *priv,
 	struct usb_usbvision *usbvision = video_drvdata(file);
 	int chan;
 
-	if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) )
+	if (vi->index >= usbvision->video_inputs)
 		return -EINVAL;
 	if (usbvision->have_tuner) {
 		chan = vi->index;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 29b3c693a8e..48c3ebdb415 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -455,7 +455,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 		dprintk(1, "querybuf: Wrong type.\n");
 		goto done;
 	}
-	if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) {
+	if (unlikely(b->index >= VIDEO_MAX_FRAME)) {
 		dprintk(1, "querybuf: index out of range.\n");
 		goto done;
 	}
@@ -496,7 +496,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
 		dprintk(1, "qbuf: Wrong type.\n");
 		goto done;
 	}
-	if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) {
+	if (b->index >= VIDEO_MAX_FRAME) {
 		dprintk(1, "qbuf: index out of range.\n");
 		goto done;
 	}
-- 
cgit v1.2.3-70-g09d2


From b475f4eeda1da16e995b2302f6eebdfb08ce18cd Mon Sep 17 00:00:00 2001
From: Roel Kluin <roel.kluin@gmail.com>
Date: Sat, 2 May 2009 17:52:52 -0300
Subject: V4L/DVB (11741): zoran: Fix &&/|| typo

Fix &&/|| typo. `default_norm' can be 0 (PAL), 1 (NTSC) or 2 (SECAM),
the condition tested was impossible.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/zoran/zoran_card.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index ea6c577b0eb..ea9de8b47db 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1022,7 +1022,7 @@ zr36057_init (struct zoran *zr)
 	zr->vbuf_bytesperline = 0;
 
 	/* Avoid nonsense settings from user for default input/norm */
-	if (default_norm < 0 && default_norm > 2)
+	if (default_norm < 0 || default_norm > 2)
 		default_norm = 0;
 	if (default_norm == 0) {
 		zr->norm = V4L2_STD_PAL;
-- 
cgit v1.2.3-70-g09d2


From 40199c50b891d24d1a8f1d480f886680a3ac9b74 Mon Sep 17 00:00:00 2001
From: Chaithrika U S <chaithrika@ti.com>
Date: Thu, 7 May 2009 09:29:25 -0300
Subject: V4L/DVB (11742): TI THS7303 video amplifier driver code

This patch adds driver for TI THS7303 video amplifier. This driver is
implemented as a v4l2 sub device. Tested on TI DM646x EVM.

This version has updates based on review comments by Mauro Chehab.

Signed-off-by: Chaithrika U S <chaithrika@ti.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Kconfig     |   9 +++
 drivers/media/video/Makefile    |   1 +
 drivers/media/video/ths7303.c   | 151 ++++++++++++++++++++++++++++++++++++++++
 include/media/v4l2-chip-ident.h |   3 +
 4 files changed, 164 insertions(+)
 create mode 100644 drivers/media/video/ths7303.c

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 57835f5715f..3308462a835 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -440,6 +440,15 @@ config VIDEO_ADV7175
 	  To compile this driver as a module, choose M here: the
 	  module will be called adv7175.
 
+config VIDEO_THS7303
+	tristate "THS7303 Video Amplifier"
+	depends on I2C
+	help
+	  Support for TI THS7303 video amplifier
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ths7303.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 7aefac64330..352dd6d3200 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_VIDEO_BT819) += bt819.o
 obj-$(CONFIG_VIDEO_BT856) += bt856.o
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
 
 obj-$(CONFIG_VIDEO_ZORAN) += zoran/
 
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c
new file mode 100644
index 00000000000..21781f8a0e8
--- /dev/null
+++ b/drivers/media/video/ths7303.c
@@ -0,0 +1,151 @@
+/*
+ * ths7303- THS7303 Video Amplifier driver
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-chip-ident.h>
+
+MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
+MODULE_AUTHOR("Chaithrika U S");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+/* following function is used to set ths7303 */
+static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	int err = 0;
+	u8 val;
+	struct i2c_client *client;
+
+	client = v4l2_get_subdevdata(sd);
+
+	if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
+		val = 0x02;
+		v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
+	} else {
+		val = 0x00;
+		v4l2_dbg(1, debug, sd, "disabling all channels\n");
+	}
+
+	err |= i2c_smbus_write_byte_data(client, 0x01, val);
+	err |= i2c_smbus_write_byte_data(client, 0x02, val);
+	err |= i2c_smbus_write_byte_data(client, 0x03, val);
+
+	if (err)
+		v4l2_err(sd, "write failed\n");
+
+	return err;
+}
+
+static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	return ths7303_setvalue(sd, norm);
+}
+
+static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0);
+}
+
+static const struct v4l2_subdev_video_ops ths7303_video_ops = {
+	.s_std_output	= ths7303_s_std_output,
+};
+
+static const struct v4l2_subdev_core_ops ths7303_core_ops = {
+	.g_chip_ident = ths7303_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops ths7303_ops = {
+	.core	= &ths7303_core_ops,
+	.video 	= &ths7303_video_ops,
+};
+
+static int ths7303_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct v4l2_subdev *sd;
+	v4l2_std_id std_id = V4L2_STD_NTSC;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (sd == NULL)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
+
+	return ths7303_setvalue(sd, std_id);
+}
+
+static int ths7303_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(sd);
+
+	return 0;
+}
+
+static const struct i2c_device_id ths7303_id[] = {
+	{"ths7303", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, ths7303_id);
+
+static struct i2c_driver ths7303_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "ths7303",
+	},
+	.probe		= ths7303_probe,
+	.remove		= ths7303_remove,
+	.id_table	= ths7303_id,
+};
+
+static int __init ths7303_init(void)
+{
+	return i2c_add_driver(&ths7303_driver);
+}
+
+static void __exit ths7303_exit(void)
+{
+	i2c_del_driver(&ths7303_driver);
+}
+
+module_init(ths7303_init);
+module_exit(ths7303_exit);
+
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 1be461a2907..fbeb98f8ee2 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -137,6 +137,9 @@ enum {
 	/* module saa7191: just ident 7191 */
 	V4L2_IDENT_SAA7191 = 7191,
 
+	/* module ths7303: just ident 7303 */
+	V4L2_IDENT_THS7303 = 7303,
+
 	/* module wm8739: just ident 8739 */
 	V4L2_IDENT_WM8739 = 8739,
 
-- 
cgit v1.2.3-70-g09d2


From 06e61f8d5f5df68104168ac20d0527ecee13638a Mon Sep 17 00:00:00 2001
From: Chaithrika U S <chaithrika@ti.com>
Date: Thu, 7 May 2009 09:30:01 -0300
Subject: V4L/DVB (11743): Analog Devices ADV7343 video encoder driver

Add ADV7343 I2C based video encoder driver. This follows the
v4l2-subdev framework. This driver has been tested on TI DM646x EVM. It
has been tested for Composite and Component outputs.

Updates as per review by Mauro Chehab, added support for more standards
supported by the encoder. Also adding the missed out signed-offs.Tested
only NTSC and PAL standards.

[hverkuil@xs4all.nl: s_routing API changed, updated driver to use new API]
Signed-off-by: Manjunath Hadli <mrh@ti.com>
Signed-off-by: Brijesh Jadav <brijesh.j@ti.com>
Signed-off-by: Chaithrika U S <chaithrika@ti.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Kconfig        |   9 +
 drivers/media/video/Makefile       |   1 +
 drivers/media/video/adv7343.c      | 534 +++++++++++++++++++++++++++++++++++++
 drivers/media/video/adv7343_regs.h | 185 +++++++++++++
 include/media/adv7343.h            |  23 ++
 include/media/v4l2-chip-ident.h    |   3 +
 6 files changed, 755 insertions(+)
 create mode 100644 drivers/media/video/adv7343.c
 create mode 100644 drivers/media/video/adv7343_regs.h
 create mode 100644 include/media/adv7343.h

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 3308462a835..af576eaeab7 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -449,6 +449,15 @@ config VIDEO_THS7303
 	  To compile this driver as a module, choose M here: the
 	  module will be called ths7303.
 
+config VIDEO_ADV7343
+	tristate "ADV7343 video encoder"
+	depends on I2C
+	help
+	  Support for Analog Devices I2C bus based ADV7343 encoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called adv7343.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 352dd6d3200..f7d9a4c6f45 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
 obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
+obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
 obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
 obj-$(CONFIG_VIDEO_BT819) += bt819.o
 obj-$(CONFIG_VIDEO_BT856) += bt856.o
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
new file mode 100644
index 00000000000..30f5caf5dda
--- /dev/null
+++ b/drivers/media/video/adv7343.c
@@ -0,0 +1,534 @@
+/*
+ * adv7343 - ADV7343 Video Encoder Driver
+ *
+ * The encoder hardware does not support SECAM.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+
+#include <media/adv7343.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "adv7343_regs.h"
+
+MODULE_DESCRIPTION("ADV7343 video encoder driver");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+struct adv7343_state {
+	struct v4l2_subdev sd;
+	u8 reg00;
+	u8 reg01;
+	u8 reg02;
+	u8 reg35;
+	u8 reg80;
+	u8 reg82;
+	int bright;
+	int hue;
+	int gain;
+	u32 output;
+	v4l2_std_id std;
+};
+
+static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct adv7343_state, sd);
+}
+
+static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static const u8 adv7343_init_reg_val[] = {
+	ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT,
+	ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT,
+
+	ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT,
+	ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT,
+	ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT,
+	ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT,
+	ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT,
+	ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT,
+	ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT,
+
+	ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT,
+	ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT,
+	ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT,
+	ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT,
+	ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT,
+	ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT,
+	ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT,
+	ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT,
+
+	ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT,
+	ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT,
+	ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT,
+};
+
+/*
+ * 			    2^32
+ * FSC(reg) =  FSC (HZ) * --------
+ *			  27000000
+ */
+static const struct adv7343_std_info stdinfo[] = {
+	{
+		/* FSC(Hz) = 3,579,545.45 Hz */
+		SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
+	}, {
+		/* FSC(Hz) = 3,575,611.00 Hz */
+		SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
+	}, {
+		/* FSC(Hz) = 3,582,056.00 */
+		SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
+	}, {
+		/* FSC(Hz) = 4,433,618.75 Hz */
+		SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
+	}, {
+		/* FSC(Hz) = 4,433,618.75 Hz */
+		SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
+	}, {
+		/* FSC(Hz) = 4,433,618.75 Hz */
+		SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
+	}, {
+		/* FSC(Hz) = 4,433,618.75 Hz */
+		SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
+	},
+};
+
+static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct adv7343_state *state = to_state(sd);
+	struct adv7343_std_info *std_info;
+	int output_idx, num_std;
+	char *fsc_ptr;
+	u8 reg, val;
+	int err = 0;
+	int i = 0;
+
+	output_idx = state->output;
+
+	std_info = (struct adv7343_std_info *)stdinfo;
+	num_std = ARRAY_SIZE(stdinfo);
+
+	for (i = 0; i < num_std; i++) {
+		if (std_info[i].stdid & std)
+			break;
+	}
+
+	if (i == num_std) {
+		v4l2_dbg(1, debug, sd,
+				"Invalid std or std is not supported: %llx\n",
+						(unsigned long long)std);
+		return -EINVAL;
+	}
+
+	/* Set the standard */
+	val = state->reg80 & (~(SD_STD_MASK));
+	val |= std_info[i].standard_val3;
+	err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
+	if (err < 0)
+		goto setstd_exit;
+
+	state->reg80 = val;
+
+	/* Configure the input mode register */
+	val = state->reg01 & (~((u8) INPUT_MODE_MASK));
+	val |= SD_INPUT_MODE;
+	err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val);
+	if (err < 0)
+		goto setstd_exit;
+
+	state->reg01 = val;
+
+	/* Program the sub carrier frequency registers */
+	fsc_ptr = (unsigned char *)&std_info[i].fsc_val;
+	reg = ADV7343_FSC_REG0;
+	for (i = 0; i < 4; i++, reg++, fsc_ptr++) {
+		err = adv7343_write(sd, reg, *fsc_ptr);
+		if (err < 0)
+			goto setstd_exit;
+	}
+
+	val = state->reg80;
+
+	/* Filter settings */
+	if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
+		val &= 0x03;
+	else if (std & ~V4L2_STD_SECAM)
+		val |= 0x04;
+
+	err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
+	if (err < 0)
+		goto setstd_exit;
+
+	state->reg80 = val;
+
+setstd_exit:
+	if (err != 0)
+		v4l2_err(sd, "Error setting std, write failed\n");
+
+	return err;
+}
+
+static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
+{
+	struct adv7343_state *state = to_state(sd);
+	unsigned char val;
+	int err = 0;
+
+	if (output_type > ADV7343_SVIDEO_ID) {
+		v4l2_dbg(1, debug, sd,
+			"Invalid output type or output type not supported:%d\n",
+								output_type);
+		return -EINVAL;
+	}
+
+	/* Enable Appropriate DAC */
+	val = state->reg00 & 0x03;
+
+	if (output_type == ADV7343_COMPOSITE_ID)
+		val |= ADV7343_COMPOSITE_POWER_VALUE;
+	else if (output_type == ADV7343_COMPONENT_ID)
+		val |= ADV7343_COMPONENT_POWER_VALUE;
+	else
+		val |= ADV7343_SVIDEO_POWER_VALUE;
+
+	err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
+	if (err < 0)
+		goto setoutput_exit;
+
+	state->reg00 = val;
+
+	/* Enable YUV output */
+	val = state->reg02 | YUV_OUTPUT_SELECT;
+	err = adv7343_write(sd, ADV7343_MODE_REG0, val);
+	if (err < 0)
+		goto setoutput_exit;
+
+	state->reg02 = val;
+
+	/* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
+	val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
+	err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
+	if (err < 0)
+		goto setoutput_exit;
+
+	state->reg82 = val;
+
+	/* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to
+	 * zero */
+	val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI);
+	err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val);
+	if (err < 0)
+		goto setoutput_exit;
+
+	state->reg35 = val;
+
+setoutput_exit:
+	if (err != 0)
+		v4l2_err(sd, "Error setting output, write failed\n");
+
+	return err;
+}
+
+static int adv7343_log_status(struct v4l2_subdev *sd)
+{
+	struct adv7343_state *state = to_state(sd);
+
+	v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
+	v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
+			((state->output == 1) ? "Component" : "S-Video"));
+	return 0;
+}
+
+static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
+						ADV7343_BRIGHTNESS_MAX, 1,
+						ADV7343_BRIGHTNESS_DEF);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
+						ADV7343_HUE_MAX, 1 ,
+						ADV7343_HUE_DEF);
+	case V4L2_CID_GAIN:
+		return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
+						ADV7343_GAIN_MAX, 1,
+						ADV7343_GAIN_DEF);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct adv7343_state *state = to_state(sd);
+	int err = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
+					ctrl->value > ADV7343_BRIGHTNESS_MAX) {
+			v4l2_dbg(1, debug, sd,
+					"invalid brightness settings %d\n",
+								ctrl->value);
+			return -ERANGE;
+		}
+
+		state->bright = ctrl->value;
+		err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
+					state->bright);
+		break;
+
+	case V4L2_CID_HUE:
+		if (ctrl->value < ADV7343_HUE_MIN ||
+					ctrl->value > ADV7343_HUE_MAX) {
+			v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
+								ctrl->value);
+			return -ERANGE;
+		}
+
+		state->hue = ctrl->value;
+		err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
+		break;
+
+	case V4L2_CID_GAIN:
+		if (ctrl->value < ADV7343_GAIN_MIN ||
+					ctrl->value > ADV7343_GAIN_MAX) {
+			v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
+								ctrl->value);
+			return -ERANGE;
+		}
+
+		if ((ctrl->value > POSITIVE_GAIN_MAX) &&
+			(ctrl->value < NEGATIVE_GAIN_MIN)) {
+			v4l2_dbg(1, debug, sd,
+				"gain settings not within the specified range\n");
+			return -ERANGE;
+		}
+
+		state->gain = ctrl->value;
+		err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (err < 0)
+		v4l2_err(sd, "Failed to set the encoder controls\n");
+
+	return err;
+}
+
+static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct adv7343_state *state = to_state(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = state->bright;
+		break;
+
+	case V4L2_CID_HUE:
+		ctrl->value = state->hue;
+		break;
+
+	case V4L2_CID_GAIN:
+		ctrl->value = state->gain;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
+}
+
+static const struct v4l2_subdev_core_ops adv7343_core_ops = {
+	.log_status	= adv7343_log_status,
+	.g_chip_ident	= adv7343_g_chip_ident,
+	.g_ctrl		= adv7343_g_ctrl,
+	.s_ctrl		= adv7343_s_ctrl,
+	.queryctrl	= adv7343_queryctrl,
+};
+
+static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct adv7343_state *state = to_state(sd);
+	int err = 0;
+
+	if (state->std == std)
+		return 0;
+
+	err = adv7343_setstd(sd, std);
+	if (!err)
+		state->std = std;
+
+	return err;
+}
+
+static int adv7343_s_routing(struct v4l2_subdev *sd,
+		u32 input, u32 output, u32 config)
+{
+	struct adv7343_state *state = to_state(sd);
+	int err = 0;
+
+	if (state->output == output)
+		return 0;
+
+	err = adv7343_setoutput(sd, output);
+	if (!err)
+		state->output = output;
+
+	return err;
+}
+
+static const struct v4l2_subdev_video_ops adv7343_video_ops = {
+	.s_std_output	= adv7343_s_std_output,
+	.s_routing	= adv7343_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7343_ops = {
+	.core	= &adv7343_core_ops,
+	.video	= &adv7343_video_ops,
+};
+
+static int adv7343_initialize(struct v4l2_subdev *sd)
+{
+	struct adv7343_state *state = to_state(sd);
+	int err = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) {
+
+		err = adv7343_write(sd, adv7343_init_reg_val[i],
+					adv7343_init_reg_val[i+1]);
+		if (err) {
+			v4l2_err(sd, "Error initializing\n");
+			return err;
+		}
+	}
+
+	/* Configure for default video standard */
+	err = adv7343_setoutput(sd, state->output);
+	if (err < 0) {
+		v4l2_err(sd, "Error setting output during init\n");
+		return -EINVAL;
+	}
+
+	err = adv7343_setstd(sd, state->std);
+	if (err < 0) {
+		v4l2_err(sd, "Error setting std during init\n");
+		return -EINVAL;
+	}
+
+	return err;
+}
+
+static int adv7343_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct adv7343_state *state;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+
+	state->reg00	= 0x80;
+	state->reg01	= 0x00;
+	state->reg02	= 0x20;
+	state->reg35	= 0x00;
+	state->reg80	= ADV7343_SD_MODE_REG1_DEFAULT;
+	state->reg82	= ADV7343_SD_MODE_REG2_DEFAULT;
+
+	state->output = ADV7343_COMPOSITE_ID;
+	state->std = V4L2_STD_NTSC;
+
+	v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
+	return adv7343_initialize(&state->sd);
+}
+
+static int adv7343_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+
+	return 0;
+}
+
+static const struct i2c_device_id adv7343_id[] = {
+	{"adv7343", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, adv7343_id);
+
+static struct i2c_driver adv7343_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "adv7343",
+	},
+	.probe		= adv7343_probe,
+	.remove		= adv7343_remove,
+	.id_table	= adv7343_id,
+};
+
+static __init int init_adv7343(void)
+{
+	return i2c_add_driver(&adv7343_driver);
+}
+
+static __exit void exit_adv7343(void)
+{
+	i2c_del_driver(&adv7343_driver);
+}
+
+module_init(init_adv7343);
+module_exit(exit_adv7343);
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h
new file mode 100644
index 00000000000..3431045b33d
--- /dev/null
+++ b/drivers/media/video/adv7343_regs.h
@@ -0,0 +1,185 @@
+/*
+ * ADV7343 encoder related structure and register definitions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef ADV7343_REG_H
+#define ADV7343_REGS_H
+
+struct adv7343_std_info {
+	u32 standard_val3;
+	u32 fsc_val;
+	v4l2_std_id stdid;
+};
+
+/* Register offset macros */
+#define ADV7343_POWER_MODE_REG		(0x00)
+#define ADV7343_MODE_SELECT_REG		(0x01)
+#define ADV7343_MODE_REG0		(0x02)
+
+#define ADV7343_DAC2_OUTPUT_LEVEL	(0x0b)
+
+#define ADV7343_SOFT_RESET		(0x17)
+
+#define ADV7343_HD_MODE_REG1		(0x30)
+#define ADV7343_HD_MODE_REG2		(0x31)
+#define ADV7343_HD_MODE_REG3		(0x32)
+#define ADV7343_HD_MODE_REG4		(0x33)
+#define ADV7343_HD_MODE_REG5		(0x34)
+#define ADV7343_HD_MODE_REG6		(0x35)
+
+#define ADV7343_HD_MODE_REG7		(0x39)
+
+#define ADV7343_SD_MODE_REG1		(0x80)
+#define ADV7343_SD_MODE_REG2		(0x82)
+#define ADV7343_SD_MODE_REG3		(0x83)
+#define ADV7343_SD_MODE_REG4		(0x84)
+#define ADV7343_SD_MODE_REG5		(0x86)
+#define ADV7343_SD_MODE_REG6		(0x87)
+#define ADV7343_SD_MODE_REG7		(0x88)
+#define ADV7343_SD_MODE_REG8		(0x89)
+
+#define ADV7343_FSC_REG0		(0x8C)
+#define ADV7343_FSC_REG1		(0x8D)
+#define ADV7343_FSC_REG2		(0x8E)
+#define ADV7343_FSC_REG3		(0x8F)
+
+#define ADV7343_SD_CGMS_WSS0		(0x99)
+
+#define ADV7343_SD_HUE_REG		(0xA0)
+#define ADV7343_SD_BRIGHTNESS_WSS	(0xA1)
+
+/* Default values for the registers */
+#define ADV7343_POWER_MODE_REG_DEFAULT		(0x10)
+#define ADV7343_HD_MODE_REG1_DEFAULT		(0x3C)	/* Changed Default
+							   720p EAVSAV code*/
+#define ADV7343_HD_MODE_REG2_DEFAULT		(0x01)	/* Changed Pixel data
+							   valid */
+#define ADV7343_HD_MODE_REG3_DEFAULT		(0x00)	/* Color delay 0 clks */
+#define ADV7343_HD_MODE_REG4_DEFAULT		(0xE8)	/* Changed */
+#define ADV7343_HD_MODE_REG5_DEFAULT		(0x08)
+#define ADV7343_HD_MODE_REG6_DEFAULT		(0x00)
+#define ADV7343_HD_MODE_REG7_DEFAULT		(0x00)
+#define ADV7343_SD_MODE_REG8_DEFAULT		(0x00)
+#define ADV7343_SOFT_RESET_DEFAULT		(0x02)
+#define ADV7343_COMPOSITE_POWER_VALUE		(0x80)
+#define ADV7343_COMPONENT_POWER_VALUE		(0x1C)
+#define ADV7343_SVIDEO_POWER_VALUE		(0x60)
+#define ADV7343_SD_HUE_REG_DEFAULT		(127)
+#define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT	(0x03)
+
+#define ADV7343_SD_CGMS_WSS0_DEFAULT		(0x10)
+
+#define ADV7343_SD_MODE_REG1_DEFAULT		(0x00)
+#define ADV7343_SD_MODE_REG2_DEFAULT		(0xC9)
+#define ADV7343_SD_MODE_REG3_DEFAULT		(0x10)
+#define ADV7343_SD_MODE_REG4_DEFAULT		(0x01)
+#define ADV7343_SD_MODE_REG5_DEFAULT		(0x02)
+#define ADV7343_SD_MODE_REG6_DEFAULT		(0x0C)
+#define ADV7343_SD_MODE_REG7_DEFAULT		(0x04)
+#define ADV7343_SD_MODE_REG8_DEFAULT		(0x00)
+
+/* Bit masks for Mode Select Register */
+#define INPUT_MODE_MASK			(0x70)
+#define SD_INPUT_MODE			(0x00)
+#define HD_720P_INPUT_MODE		(0x10)
+#define HD_1080I_INPUT_MODE		(0x10)
+
+/* Bit masks for Mode Register 0 */
+#define TEST_PATTERN_BLACK_BAR_EN	(0x04)
+#define YUV_OUTPUT_SELECT		(0x20)
+#define RGB_OUTPUT_SELECT		(0xDF)
+
+/* Bit masks for DAC output levels */
+#define DAC_OUTPUT_LEVEL_MASK		(0xFF)
+#define POSITIVE_GAIN_MAX		(0x40)
+#define POSITIVE_GAIN_MIN		(0x00)
+#define NEGATIVE_GAIN_MAX		(0xFF)
+#define NEGATIVE_GAIN_MIN		(0xC0)
+
+/* Bit masks for soft reset register */
+#define SOFT_RESET			(0x02)
+
+/* Bit masks for HD Mode Register 1 */
+#define OUTPUT_STD_MASK		(0x03)
+#define OUTPUT_STD_SHIFT	(0)
+#define OUTPUT_STD_EIA0_2	(0x00)
+#define OUTPUT_STD_EIA0_1	(0x01)
+#define OUTPUT_STD_FULL		(0x02)
+#define EMBEDDED_SYNC		(0x04)
+#define EXTERNAL_SYNC		(0xFB)
+#define STD_MODE_SHIFT		(3)
+#define STD_MODE_MASK		(0x1F)
+#define STD_MODE_720P		(0x05)
+#define STD_MODE_720P_25	(0x08)
+#define STD_MODE_720P_30	(0x07)
+#define STD_MODE_720P_50	(0x06)
+#define STD_MODE_1080I		(0x0D)
+#define STD_MODE_1080I_25fps	(0x0E)
+#define STD_MODE_1080P_24	(0x12)
+#define STD_MODE_1080P_25	(0x10)
+#define STD_MODE_1080P_30	(0x0F)
+#define STD_MODE_525P		(0x00)
+#define STD_MODE_625P		(0x03)
+
+/* Bit masks for SD Mode Register 1 */
+#define SD_STD_MASK		(0x03)
+#define SD_STD_NTSC		(0x00)
+#define SD_STD_PAL_BDGHI	(0x01)
+#define SD_STD_PAL_M		(0x02)
+#define SD_STD_PAL_N		(0x03)
+#define SD_LUMA_FLTR_MASK	(0x7)
+#define SD_LUMA_FLTR_SHIFT	(0x2)
+#define SD_CHROMA_FLTR_MASK	(0x7)
+#define SD_CHROMA_FLTR_SHIFT	(0x5)
+
+/* Bit masks for SD Mode Register 2 */
+#define SD_PBPR_SSAF_EN		(0x01)
+#define SD_PBPR_SSAF_DI		(0xFE)
+#define SD_DAC_1_DI		(0xFD)
+#define SD_DAC_2_DI		(0xFB)
+#define SD_PEDESTAL_EN		(0x08)
+#define SD_PEDESTAL_DI		(0xF7)
+#define SD_SQUARE_PIXEL_EN	(0x10)
+#define SD_SQUARE_PIXEL_DI	(0xEF)
+#define SD_PIXEL_DATA_VALID	(0x40)
+#define SD_ACTIVE_EDGE_EN	(0x80)
+#define SD_ACTIVE_EDGE_DI	(0x7F)
+
+/* Bit masks for HD Mode Register 6 */
+#define HD_RGB_INPUT_EN		(0x02)
+#define HD_RGB_INPUT_DI		(0xFD)
+#define HD_PBPR_SYNC_EN		(0x04)
+#define HD_PBPR_SYNC_DI		(0xFB)
+#define HD_DAC_SWAP_EN		(0x08)
+#define HD_DAC_SWAP_DI		(0xF7)
+#define HD_GAMMA_CURVE_A	(0xEF)
+#define HD_GAMMA_CURVE_B	(0x10)
+#define HD_GAMMA_EN		(0x20)
+#define HD_GAMMA_DI		(0xDF)
+#define HD_ADPT_FLTR_MODEB	(0x40)
+#define HD_ADPT_FLTR_MODEA	(0xBF)
+#define HD_ADPT_FLTR_EN		(0x80)
+#define HD_ADPT_FLTR_DI		(0x7F)
+
+#define ADV7343_BRIGHTNESS_MAX	(127)
+#define ADV7343_BRIGHTNESS_MIN	(0)
+#define ADV7343_BRIGHTNESS_DEF	(3)
+#define ADV7343_HUE_MAX		(255)
+#define ADV7343_HUE_MIN		(0)
+#define ADV7343_HUE_DEF		(127)
+#define ADV7343_GAIN_MAX	(255)
+#define ADV7343_GAIN_MIN	(0)
+#define ADV7343_GAIN_DEF	(0)
+
+#endif
diff --git a/include/media/adv7343.h b/include/media/adv7343.h
new file mode 100644
index 00000000000..d6f8a4e1a1f
--- /dev/null
+++ b/include/media/adv7343.h
@@ -0,0 +1,23 @@
+/*
+ * ADV7343 header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef ADV7343_H
+#define ADV7343_H
+
+#define ADV7343_COMPOSITE_ID	(0)
+#define ADV7343_COMPONENT_ID	(1)
+#define ADV7343_SVIDEO_ID	(2)
+
+#endif				/* End of #ifndef ADV7343_H */
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index fbeb98f8ee2..4d7e2272c42 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -140,6 +140,9 @@ enum {
 	/* module ths7303: just ident 7303 */
 	V4L2_IDENT_THS7303 = 7303,
 
+	/* module adv7343: just ident 7343 */
+	V4L2_IDENT_ADV7343 = 7343,
+
 	/* module wm8739: just ident 8739 */
 	V4L2_IDENT_WM8739 = 8739,
 
-- 
cgit v1.2.3-70-g09d2


From 27eab3840baaee469eb6377607520ca2128b66f7 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Mon, 6 Apr 2009 01:51:38 -0300
Subject: V4L/DVB (11744): pvrusb2: Select, track, and report IR scheme in use
 with the device

This change defines all possible "IR schemes" related to the pvrusb2
driver, on a per-device basis.  That information is then set according
to the hardware in use.  The idea here is to make possible a more
intelligent future decision on which, if any, IR receiver driver might
be loaded during initialization.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-devattr.c      |  1 +
 drivers/media/video/pvrusb2/pvrusb2-devattr.h      | 22 +++++++---------------
 drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h |  3 +++
 drivers/media/video/pvrusb2/pvrusb2-hdw.c          | 18 +++++++++++++++++-
 drivers/media/video/pvrusb2/pvrusb2-i2c-core.c     | 12 ++++++++++--
 5 files changed, 38 insertions(+), 18 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 76d42d92e60..a0688c005b8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -71,6 +71,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
 		.flag_has_svideo = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_29XXX,
 };
 
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index 3e553389cbc..73e0e0ba004 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -78,8 +78,10 @@ struct pvr2_string_table {
 #define PVR2_LED_SCHEME_HAUPPAUGE 1
 
 #define PVR2_IR_SCHEME_NONE 0
-#define PVR2_IR_SCHEME_24XXX 1
-#define PVR2_IR_SCHEME_ZILOG 2
+#define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */
+#define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */
+#define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */
+#define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */
 
 /* This describes a particular hardware type (except for the USB device ID
    which must live in a separate structure due to environmental
@@ -162,19 +164,9 @@ struct pvr2_device_desc {
 	   ensure that it is found. */
 	unsigned int flag_has_wm8775: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;
+	/* Indicate IR scheme of hardware.  If not set, then it is assumed
+	   that IR can work without any help from the driver. */
+	unsigned int ir_scheme:3;
 
 	/* 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-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5d75eb5211b..5b152ff20bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -200,6 +200,9 @@ struct pvr2_hdw {
 	int i2c_cx25840_hack_state;
 	int i2c_linked;
 
+	/* IR related */
+	unsigned int ir_scheme_active; /* IR scheme as seen from the outside */
+
 	/* Frequency table */
 	unsigned int freqTable[FREQTABLE_SIZE];
 	unsigned int freqProgSlot;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index add3395d324..686df1afbba 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -142,6 +142,15 @@ static const unsigned char *module_i2c_addresses[] = {
 };
 
 
+static const char *ir_scheme_names[] = {
+	[PVR2_IR_SCHEME_NONE] = "none",
+	[PVR2_IR_SCHEME_29XXX] = "29xxx",
+	[PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)",
+	[PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)",
+	[PVR2_IR_SCHEME_ZILOG] = "Zilog",
+};
+
+
 /* Define the list of additional controls we'll dynamically construct based
    on query of the cx2341x module. */
 struct pvr2_mpeg_ids {
@@ -2170,7 +2179,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 	}
 
 	/* Take the IR chip out of reset, if appropriate */
-	if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) {
+	if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) {
 		pvr2_issue_simple_cmd(hdw,
 				      FX2CMD_HCW_ZILOG_RESET |
 				      (1 << 8) |
@@ -2451,6 +2460,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
 				GFP_KERNEL);
 	if (!hdw->controls) goto fail;
 	hdw->hdw_desc = hdw_desc;
+	hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme;
 	for (idx = 0; idx < hdw->control_cnt; idx++) {
 		cptr = hdw->controls + idx;
 		cptr->hdw = hdw;
@@ -4809,6 +4819,12 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
 			stats.buffers_processed,
 			stats.buffers_failed);
 	}
+	case 6: {
+		unsigned int id = hdw->ir_scheme_active;
+		return scnprintf(buf, acnt, "ir scheme: id=%d %s", id,
+				 (id >= ARRAY_SIZE(ir_scheme_names) ?
+				  "?" : ir_scheme_names[id]));
+	}
 	default: break;
 	}
 	return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9af282f9e76..838d01c9d02 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -574,7 +574,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 		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->ir_scheme == PVR2_IR_SCHEME_24XXX) {
+		if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
+			/* Set up translation so that our IR looks like a
+			   29xxx device */
 			hdw->i2c_func[0x18] = i2c_24xxx_ir;
 		}
 	}
@@ -597,12 +599,18 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 	i2c_add_adapter(&hdw->i2c_adap);
 	if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
 		/* Probe for a different type of IR receiver on this
-		   device.  If present, disable the emulated IR receiver. */
+		   device.  This is really the only way to differentiate
+		   older 24xxx devices from 24xxx variants that include an
+		   IR blaster.  If the IR blaster is present, the IR
+		   receiver is part of that chip and thus we must disable
+		   the emulated IR receiver. */
 		if (do_i2c_probe(hdw, 0x71)) {
 			pvr2_trace(PVR2_TRACE_INFO,
 				   "Device has newer IR hardware;"
 				   " disabling unneeded virtual IR device");
 			hdw->i2c_func[0x18] = NULL;
+			/* Remember that this is a different device... */
+			hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
 		}
 	}
 	if (i2c_scan) do_i2c_scan(hdw);
-- 
cgit v1.2.3-70-g09d2


From cd85b7afe1b76e899c387a5d1fd727021aff4a51 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Fri, 1 May 2009 22:23:39 -0300
Subject: V4L/DVB (11745): pvrusb2: Update to work with upcoming ir_video
 changes in v4l-dvb core

The ir-kbd-i2c module is about to be updated to match the new style
i2c binding model.  These pvrusb2 changes maintain compatibility with
that change.  Note that this does not actually break anything even
without the expected ir-kbd-i2c changes yet because previously the
pvrusb2 didn't autoload ir-kbd-i2c anyway.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 838d01c9d02..610bd848df2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -42,6 +42,18 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
 module_param_array(ir_mode, int, NULL, 0444);
 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
 
+static int pvr2_disable_ir_video;
+module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
+		   int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(disable_autoload_ir_video,
+		 "1=do not try to autoload ir_video IR receiver");
+
+/* Mapping of IR schemes to known I2C addresses - if any */
+static const unsigned char ir_video_addresses[] = {
+	[PVR2_IR_SCHEME_29XXX] = 0x18,
+	[PVR2_IR_SCHEME_24XXX] = 0x18,
+};
+
 static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
 			  u8 i2c_addr,      /* I2C address we're talking to */
 			  u8 *data,         /* Data to write */
@@ -559,6 +571,31 @@ static void do_i2c_scan(struct pvr2_hdw *hdw)
 	printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
 }
 
+static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
+{
+	struct i2c_board_info info;
+	unsigned char addr = 0;
+	if (pvr2_disable_ir_video) {
+		pvr2_trace(PVR2_TRACE_INFO,
+			   "Automatic binding of ir_video has been disabled.");
+		return;
+	}
+	if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) {
+		addr = ir_video_addresses[hdw->ir_scheme_active];
+	}
+	if (!addr) {
+		/* The device either doesn't support I2C-based IR or we
+		   don't know (yet) how to operate IR on the device. */
+		return;
+	}
+	pvr2_trace(PVR2_TRACE_INFO,
+		   "Binding ir_video to i2c address 0x%02x.", addr);
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	info.addr = addr;
+	i2c_new_device(&hdw->i2c_adap, &info);
+}
+
 void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 {
 	unsigned int idx;
@@ -614,6 +651,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 		}
 	}
 	if (i2c_scan) do_i2c_scan(hdw);
+
+	pvr2_i2c_register_ir(hdw);
 }
 
 void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
-- 
cgit v1.2.3-70-g09d2


From 96e56c1ac45ac2c1df4ab355057e5866b92f030f Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Fri, 1 May 2009 22:33:16 -0300
Subject: V4L/DVB (11746): pvrusb2: Set ir_video autoloading to default
 disabled

This sets the disable_autoload_ir_video module option to being set,
which disables any attempt by the driver to autoload IR support.  This
changes preserves previous behavior, for now.  This change can be set
back concurrent with other changes that finally update i2c-kbd-i2c to
use the new i2c binding model.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 610bd848df2..b88a61df177 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -42,7 +42,7 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
 module_param_array(ir_mode, int, NULL, 0444);
 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
 
-static int pvr2_disable_ir_video;
+static int pvr2_disable_ir_video = 1;
 module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
 		   int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(disable_autoload_ir_video,
-- 
cgit v1.2.3-70-g09d2


From 48c5b0dfd74f6380aa5fc500fe8d8256f0662592 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 2 May 2009 00:04:35 -0300
Subject: V4L/DVB (11747): pvrusb2: Bump up version advertised through v4l
 interface

Kick up the pvrusb2 version number advertised through the v4l
interface.  This value really has almost no meaning because I don't
make a serious attempt to version the driver in this manner (otherwise
this one line becomes a nasty hotspot of changes and merge
conflicts).  The value that is here is really a historical thing.
However Hans Verkuil thought it might be a good idea to bump up the
number anyway right now since the driver's mechanism for communicating
with the v4l core has pretty much completely changed.  Sending out a

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 24b3c1d9498..2d8825e5b1b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -90,7 +90,7 @@ static struct v4l2_capability pvr_capability ={
 	.driver         = "pvrusb2",
 	.card           = "Hauppauge WinTV pvr-usb2",
 	.bus_info       = "usb",
-	.version        = KERNEL_VERSION(0,8,0),
+	.version        = KERNEL_VERSION(0, 9, 0),
 	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
 			   V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
 			   V4L2_CAP_READWRITE),
-- 
cgit v1.2.3-70-g09d2


From fa7ce76428e7ee61dfccf336505da7e1b79966b0 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Sat, 2 May 2009 00:22:27 -0300
Subject: V4L/DVB (11748): pvrusb2: Don't use the internal i2c client list

The i2c core used to maintain a list of client for each adapter. This
is a duplication of what the driver core already does, so this list
will be removed as part of a future cleanup. Anyone using this list
must stop doing so.

For pvrusb2, I propose the following change, which should lead to an
equally informative output. The only difference is that i2c clients
which are not a v4l2 subdev won't show up, but I guess this case is
not supposed to happen anyway.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-hdw.c | 56 +++++++------------------------
 1 file changed, 13 insertions(+), 43 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 686df1afbba..0c745b142fb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -4841,65 +4841,35 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
 	unsigned int tcnt = 0;
 	unsigned int ccnt;
 	struct i2c_client *client;
-	struct list_head *item;
-	void *cd;
 	const char *p;
 	unsigned int id;
 
-	ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
+	ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n");
 	tcnt += ccnt;
 	v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
 		id = sd->grp_id;
 		p = NULL;
 		if (id < ARRAY_SIZE(module_names)) p = module_names[id];
 		if (p) {
-			ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
+			ccnt = scnprintf(buf + tcnt, acnt - tcnt, "  %s:", p);
 			tcnt += ccnt;
 		} else {
 			ccnt = scnprintf(buf + tcnt, acnt - tcnt,
-					 " (unknown id=%u)", id);
+					 "  (unknown id=%u):", id);
 			tcnt += ccnt;
 		}
-	}
-	ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
-	tcnt += ccnt;
-
-	ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
-	tcnt += ccnt;
-
-	mutex_lock(&hdw->i2c_adap.clist_lock);
-	list_for_each(item, &hdw->i2c_adap.clients) {
-		client = list_entry(item, struct i2c_client, list);
-		ccnt = scnprintf(buf + tcnt, acnt - tcnt,
-				 "  %s: i2c=%02x", client->name, client->addr);
-		tcnt += ccnt;
-		cd = i2c_get_clientdata(client);
-		v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
-			if (cd == sd) {
-				id = sd->grp_id;
-				p = NULL;
-				if (id < ARRAY_SIZE(module_names)) {
-					p = module_names[id];
-				}
-				if (p) {
-					ccnt = scnprintf(buf + tcnt,
-							 acnt - tcnt,
-							 " subdev=%s", p);
-					tcnt += ccnt;
-				} else {
-					ccnt = scnprintf(buf + tcnt,
-							 acnt - tcnt,
-							 " subdev= id %u)",
-							 id);
-					tcnt += ccnt;
-				}
-				break;
-			}
+		client = v4l2_get_subdevdata(sd);
+		if (client) {
+			ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+					 " %s @ %02x\n", client->name,
+					 client->addr);
+			tcnt += ccnt;
+		} else {
+			ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+					 " no i2c client\n");
+			tcnt += ccnt;
 		}
-		ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
-		tcnt += ccnt;
 	}
-	mutex_unlock(&hdw->i2c_adap.clist_lock);
 	return tcnt;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 008b6c5f76fd447ba0d49b6ca958a06ee4786085 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 9 May 2009 18:00:23 -0300
Subject: V4L/DVB (11750): pvrusb2: Allocate a routing ID for future support of
 Terratec Grabster AV400

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-devattr.h | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index 73e0e0ba004..ea04ecf8aa3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -69,6 +69,7 @@ struct pvr2_string_table {
 #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
 #define PVR2_ROUTING_SCHEME_ONAIR 2
+#define PVR2_ROUTING_SCHEME_AV400 3
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
-- 
cgit v1.2.3-70-g09d2


From 4442ee8bddf0a412c566e638345860b187849692 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sat, 9 May 2009 00:34:31 -0300
Subject: V4L/DVB (11752): cx18: Add missing newline to tuner detection error
 message

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index f0006edc635..bc6a8f9abd3 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -313,7 +313,7 @@ static void cx18_process_eeprom(struct cx18 *cx)
 	CX18_INFO("Autodetected %s\n", cx->card_name);
 
 	if (tv.tuner_type == TUNER_ABSENT)
-		CX18_ERR("tveeprom cannot autodetect tuner!");
+		CX18_ERR("tveeprom cannot autodetect tuner!\n");
 
 	if (cx->options.tuner == -1)
 		cx->options.tuner = tv.tuner_type;
-- 
cgit v1.2.3-70-g09d2


From 5d24a037f16d6663761d32ea2a0b6acf60cd632c Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sat, 9 May 2009 00:43:40 -0300
Subject: V4L/DVB (11753): tveeprom: Point the TCL MNM05-4 tuner entry to an
 actual tuner definition

The TCL MNM05-04 is used on some HVR-1600 models.  It appears to be
similar to the TCL MFMN05-4 but without FM radio.  The
TUNER_PHILIPS_FM1236_MK3 tuner definition appears to be the proper existing
tuner definition to use for this tuner.

Reported-by: Matt Beadon <matt.beadon@gmail.com>
Tested-by: Matt Beadon <matt.beadon@gmail.com>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tveeprom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index e24a38c7fa4..d0de03c6e68 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -210,7 +210,7 @@ hauppauge_tuner[] =
 	{ TUNER_TEA5767,       		"Philips TEA5768HL FM Radio"},
 	{ TUNER_ABSENT,        		"Panasonic ENV57H12D5"},
 	{ TUNER_PHILIPS_FM1236_MK3, 	"TCL MFNM05-4"},
-	{ TUNER_ABSENT,        		"TCL MNM05-4"},
+	{ TUNER_PHILIPS_FM1236_MK3,	"TCL MNM05-4"},
 	{ TUNER_PHILIPS_FM1216ME_MK3, 	"TCL MPE05-2"},
 	{ TUNER_ABSENT,        		"TCL MQNM05-4"},
 	{ TUNER_ABSENT,        		"LG TAPC-W701D"},
-- 
cgit v1.2.3-70-g09d2


From 9d6f7f603f8c362eec321e8dacb1cb54d74fa004 Mon Sep 17 00:00:00 2001
From: Randy Dunlap <randy.dunlap@oracle.com>
Date: Mon, 11 May 2009 14:51:32 -0300
Subject: V4L/DVB (11756): soc_camera: depends on I2C

soc_camera uses i2c_*() functions and has build errors when CONFIG_I2C=n:

ERROR: "i2c_new_device" [drivers/media/video/soc_camera.ko] undefined!
ERROR: "i2c_get_adapter" [drivers/media/video/soc_camera.ko] undefined!
ERROR: "i2c_put_adapter" [drivers/media/video/soc_camera.ko] undefined!
ERROR: "i2c_unregister_device" [drivers/media/video/soc_camera.ko] undefined!

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index af576eaeab7..94f440535c6 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -712,7 +712,7 @@ config VIDEO_CAFE_CCIC
 
 config SOC_CAMERA
 	tristate "SoC camera support"
-	depends on VIDEO_V4L2 && HAS_DMA
+	depends on VIDEO_V4L2 && HAS_DMA && I2C
 	select VIDEOBUF_GEN
 	help
 	  SoC Camera is a common API to several cameras, not connecting
-- 
cgit v1.2.3-70-g09d2


From 507a34f450e3bac2940da4549ca56bcba25184e7 Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@linuxtv.org>
Date: Tue, 5 May 2009 19:31:42 -0300
Subject: V4L/DVB (11701): pvrusb2: Ensure the PVRUSB2 disabled the i2c gate on
 the tda10048.

... else DVB-T tuning will not work.

Signed-off-by: Steven Toth <stoth@linuxtv.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-devattr.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index a0688c005b8..341af4355c0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -287,6 +287,7 @@ static struct tda10048_config hauppauge_tda10048_config = {
 	.inversion      = TDA10048_INVERSION_ON,
 	.if_freq_khz    = TDA10048_IF_4300,
 	.clk_freq_khz   = TDA10048_CLK_16000,
+	.disable_gate_access = 1,
 };
 
 static struct tda829x_config tda829x_no_probe = {
-- 
cgit v1.2.3-70-g09d2


From b7fd6067143181becb5b14765f4ad25857846491 Mon Sep 17 00:00:00 2001
From: Randy Dunlap <randy.dunlap@oracle.com>
Date: Mon, 11 May 2009 13:37:41 -0300
Subject: V4L/DVB (11758): 2: handle unregister for non-I2C builds

Build fails when CONFIG_I2C=n, so handle that case in the if block:

drivers/built-in.o: In function `v4l2_device_unregister':
(.text+0x157821): undefined reference to `i2c_unregister_device'

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-device.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index e1520bc84f7..772833b69bb 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -85,6 +85,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
 	/* Unregister subdevs */
 	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
 		v4l2_device_unregister_subdev(sd);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 		if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
 			struct i2c_client *client = v4l2_get_subdevdata(sd);
 
@@ -95,6 +96,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
 			if (client)
 				i2c_unregister_device(client);
 		}
+#endif
 	}
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister);
-- 
cgit v1.2.3-70-g09d2


From 6f8bee9b104465a881f7e8acd5cbd3e6a0730759 Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@kernellabs.com>
Date: Sat, 2 May 2009 11:29:50 -0300
Subject: V4L/DVB (11765): cx23885: Add generic functions for driving GPIO's

The GPIO's on the product can be in one of three places. To date we've
mainly used the GPIO's on the bridge itself, and once on the encoder.
Rather than having the complexity of multiple GPIO writes/reads from
isolated placed in the driver we'll route them through this function,
so we can make intelligent decisions about 1) Where the GPIO lives
and 2) Whether it conflicts (based on board) with some other function
to avoid bugs.

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-core.c | 82 ++++++++++++++++++++++++++++++
 drivers/media/video/cx23885/cx23885.h      | 16 ++++++
 2 files changed, 98 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 9e4d37eb918..eb5e3412d39 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1733,6 +1733,88 @@ out:
 	return IRQ_RETVAL(handled);
 }
 
+int encoder_on_portb(struct cx23885_dev *dev)
+{
+	return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
+}
+
+int encoder_on_portc(struct cx23885_dev *dev)
+{
+	return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
+}
+
+/* Mask represents 32 different GPIOs, GPIO's are split into multiple
+ * registers depending on the board configuration (and whether the
+ * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will
+ * be pushed into the correct hardware register, regardless of the
+ * physical location. Certain registers are shared so we sanity check
+ * and report errors if we think we're tampering with a GPIo that might
+ * be assigned to the encoder (and used for the host bus).
+ *
+ * GPIO  2 thru  0 - On the cx23885 bridge
+ * GPIO 18 thru  3 - On the cx23417 host bus interface
+ * GPIO 23 thru 19 - On the cx25840 a/v core
+ */
+void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask)
+{
+	if (mask & 0x7)
+		cx_set(GP0_IO, mask & 0x7);
+
+	if (mask & 0x0007fff8) {
+		if (encoder_on_portb(dev) || encoder_on_portc(dev))
+			printk(KERN_ERR
+				"%s: Setting GPIO on encoder ports\n",
+				dev->name);
+		cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3);
+	}
+
+	/* TODO: 23-19 */
+	if (mask & 0x00f80000)
+		printk(KERN_INFO "%s: Unsupported\n", dev->name);
+}
+
+void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
+{
+	if (mask & 0x00000007)
+		cx_clear(GP0_IO, mask & 0x7);
+
+	if (mask & 0x0007fff8) {
+		if (encoder_on_portb(dev) || encoder_on_portc(dev))
+			printk(KERN_ERR
+				"%s: Clearing GPIO moving on encoder ports\n",
+				dev->name);
+		cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3);
+	}
+
+	/* TODO: 23-19 */
+	if (mask & 0x00f80000)
+		printk(KERN_INFO "%s: Unsupported\n", dev->name);
+}
+
+void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
+{
+	if ((mask & 0x00000007) && asoutput)
+		cx_set(GP0_IO, (mask & 0x7) << 16);
+	else if ((mask & 0x00000007) && !asoutput)
+		cx_clear(GP0_IO, (mask & 0x7) << 16);
+
+	if (mask & 0x0007fff8) {
+		if (encoder_on_portb(dev) || encoder_on_portc(dev))
+			printk(KERN_ERR
+				"%s: Enabling GPIO on encoder ports\n",
+				dev->name);
+	}
+
+	/* MC417_OEN is active low for output, write 1 for an input */
+	if ((mask & 0x0007fff8) && asoutput)
+		cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3);
+
+	else if ((mask & 0x0007fff8) && !asoutput)
+		cx_set(MC417_OEN, (mask & 0x7fff8) >> 3);
+
+	/* TODO: 23-19 */
+}
+
 static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
 				     const struct pci_device_id *pci_id)
 {
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 85642831ea8..d9b03f83fa3 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -72,6 +72,17 @@
 #define CX23885_BOARD_DVBWORLD_2005            16
 #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI      17
 
+#define GPIO_0 0x00000001
+#define GPIO_1 0x00000002
+#define GPIO_2 0x00000004
+#define GPIO_3 0x00000008
+#define GPIO_4 0x00000010
+#define GPIO_5 0x00000020
+#define GPIO_6 0x00000040
+#define GPIO_7 0x00000080
+#define GPIO_8 0x00000100
+#define GPIO_9 0x00000200
+
 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
 #define CX23885_NORMS (\
 	V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_443 | \
@@ -422,6 +433,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port,
 extern void cx23885_wakeup(struct cx23885_tsport *port,
 			   struct cx23885_dmaqueue *q, u32 count);
 
+extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
+extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
+	int asoutput);
+
 
 /* ----------------------------------------------------------- */
 /* cx23885-cards.c                                             */
-- 
cgit v1.2.3-70-g09d2


From 6de72bd6453003ef14acc3bac4159f7fffff7064 Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Mon, 11 May 2009 13:37:26 -0300
Subject: V4L/DVB (11766): cx23885: mark functions encoder_on_port[bc] as
 static inline

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index eb5e3412d39..bf7bb1c412f 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1733,12 +1733,12 @@ out:
 	return IRQ_RETVAL(handled);
 }
 
-int encoder_on_portb(struct cx23885_dev *dev)
+static inline int encoder_on_portb(struct cx23885_dev *dev)
 {
 	return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
 }
 
-int encoder_on_portc(struct cx23885_dev *dev)
+static inline int encoder_on_portc(struct cx23885_dev *dev)
 {
 	return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
 }
-- 
cgit v1.2.3-70-g09d2


From 2074dffaedebbf5a8468fd37855d6d94ba34041c Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@kernellabs.com>
Date: Sat, 2 May 2009 11:39:46 -0300
Subject: V4L/DVB (11767): cx23885: Add preliminary support for the HVR1270

The patch means the board will be recognised, and the parts brought
out of reset correctly. This patches depends on the centralized GPIO
patch to be merged. What's missing before the HVR-1270 will function
for DTV? The model# needs to be added to avoid 'unknown model'
output and the LG3305/Tuner need to be attached in cx23885-dvb.c

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx23885  |  1 +
 drivers/media/video/cx23885/cx23885-cards.c | 21 +++++++++++++++++++++
 drivers/media/video/cx23885/cx23885.h       |  1 +
 3 files changed, 23 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 91aa3c0f0dd..9f07a6a3458 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -16,3 +16,4 @@
  15 -> TeVii S470                                          [d470:9022]
  16 -> DVBWorld DVB-S2 2005                                [0001:2005]
  17 -> NetUP Dual DVB-S2 CI                                [1b55:2a2c]
+ 18 -> Hauppauge WinTV-HVR1270                             [0070:2211]
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 6d6293f7d42..49c6634c632 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -181,6 +181,9 @@ struct cx23885_board cx23885_boards[] = {
 		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1270] = {
+		.name		= "Hauppauge WinTV-HVR1270",
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -280,6 +283,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x1b55,
 		.subdevice = 0x2a2c,
 		.card      = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x2211,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1270,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -619,6 +626,17 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		/* enable irq */
 		cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+		/* GPIO-6 I2C Gate which can isolate the 3305 from the bus */
+		/* GPIO-9 LG3305 reset */
+
+		/* Put the parts into reset and back */
+		cx23885_gpio_enable(dev, GPIO_9 | GPIO_6, 1);
+		cx23885_gpio_set(dev, GPIO_9 | GPIO_6);
+		cx23885_gpio_clear(dev, GPIO_9);
+		mdelay(20);
+		cx23885_gpio_set(dev, GPIO_9);
+		break;
 	}
 }
 
@@ -631,6 +649,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1800:
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
+	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 		/* FIXME: Implement me */
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -666,6 +685,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
+	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -723,6 +743,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
+	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index d9b03f83fa3..13dccb8ce0d 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -71,6 +71,7 @@
 #define CX23885_BOARD_TEVII_S470               15
 #define CX23885_BOARD_DVBWORLD_2005            16
 #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI      17
+#define CX23885_BOARD_HAUPPAUGE_HVR1270        18
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
cgit v1.2.3-70-g09d2


From a5dbf45766a378cc00f341f7179befab1edae573 Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Sun, 3 May 2009 23:27:02 -0300
Subject: V4L/DVB (11768): cx23885: add ATSC/QAM tuning support for Hauppauge
 WinTV-HVR1270

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-cards.c |  1 +
 drivers/media/video/cx23885/cx23885-dvb.c   | 34 +++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 49c6634c632..90d0ad63d99 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -183,6 +183,7 @@ struct cx23885_board cx23885_boards[] = {
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1270] = {
 		.name		= "Hauppauge WinTV-HVR1270",
+		.portc		= CX23885_MPEG_DVB,
 	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 07b76053a05..48cdf279598 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -51,6 +51,7 @@
 #include "cimax2.h"
 #include "netup-eeprom.h"
 #include "netup-init.h"
+#include "lgdt3305.h"
 
 static unsigned int debug;
 
@@ -226,6 +227,28 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = {
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
+static struct tda18271_std_map hcw_lgdt3305_tda18271_std_map = {
+	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x58 },
+	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x58 },
+};
+
+static struct tda18271_config hcw_lgdt3305_tda18271_config = {
+	.std_map = &hcw_lgdt3305_tda18271_std_map,
+};
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+	.i2c_addr           = 0x0e,
+	.mpeg_mode          = LGDT3305_MPEG_SERIAL,
+	.tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
+	.tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+	.deny_i2c_rptr      = 1,
+	.spectral_inversion = 1,
+	.qam_if_khz         = 4000,
+	.vsb_if_khz         = 3250,
+};
+
 static struct dibx000_agc_config xc3028_agc_config = {
 	BAND_VHF | BAND_UHF,	/* band_caps */
 
@@ -398,6 +421,17 @@ static int dvb_register(struct cx23885_tsport *port)
 				   &hauppauge_generic_tunerconfig, 0);
 		}
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+		i2c_bus = &dev->i2c_bus[0];
+		fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+					       &hcw_lgdt3305_config,
+					       &i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_bus[1].i2c_adap,
+				   &hcw_lgdt3305_tda18271_config);
+		}
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1800:
 		i2c_bus = &dev->i2c_bus[0];
 		switch (alt_tuner) {
-- 
cgit v1.2.3-70-g09d2


From d099becb0bd7ee01a13d58371b4ea5a2f7052c04 Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Fri, 8 May 2009 22:39:24 -0300
Subject: V4L/DVB (11769): cx23885: add ATSC/QAM tuning support for Hauppauge
 WinTV-HVR1275

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx23885  |  1 +
 drivers/media/video/cx23885/cx23885-cards.c | 17 +++++++++++++++--
 drivers/media/video/cx23885/cx23885-dvb.c   |  1 +
 drivers/media/video/cx23885/cx23885.h       |  1 +
 4 files changed, 18 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 9f07a6a3458..ce62f5a2831 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -17,3 +17,4 @@
  16 -> DVBWorld DVB-S2 2005                                [0001:2005]
  17 -> NetUP Dual DVB-S2 CI                                [1b55:2a2c]
  18 -> Hauppauge WinTV-HVR1270                             [0070:2211]
+ 19 -> Hauppauge WinTV-HVR1275                             [0070:2215]
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 90d0ad63d99..68ac04b7f1e 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -185,6 +185,10 @@ struct cx23885_board cx23885_boards[] = {
 		.name		= "Hauppauge WinTV-HVR1270",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1275] = {
+		.name		= "Hauppauge WinTV-HVR1275",
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -288,6 +292,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x2211,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1270,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x2215,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1275,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -628,12 +636,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+	case CX23885_BOARD_HAUPPAUGE_HVR1275:
+		/* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
 		/* GPIO-6 I2C Gate which can isolate the 3305 from the bus */
 		/* GPIO-9 LG3305 reset */
 
 		/* Put the parts into reset and back */
-		cx23885_gpio_enable(dev, GPIO_9 | GPIO_6, 1);
-		cx23885_gpio_set(dev, GPIO_9 | GPIO_6);
+		cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1);
+		cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5);
 		cx23885_gpio_clear(dev, GPIO_9);
 		mdelay(20);
 		cx23885_gpio_set(dev, GPIO_9);
@@ -651,6 +661,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 		/* FIXME: Implement me */
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -687,6 +698,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -745,6 +757,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 48cdf279598..7e354a93e89 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -422,6 +422,7 @@ static int dvb_register(struct cx23885_tsport *port)
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
+	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 		i2c_bus = &dev->i2c_bus[0];
 		fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
 					       &hcw_lgdt3305_config,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 13dccb8ce0d..3c941ccc308 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -72,6 +72,7 @@
 #define CX23885_BOARD_DVBWORLD_2005            16
 #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI      17
 #define CX23885_BOARD_HAUPPAUGE_HVR1270        18
+#define CX23885_BOARD_HAUPPAUGE_HVR1275        19
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
cgit v1.2.3-70-g09d2


From 19bc57968cc854c7da4846c21b3ef2a39e43f97d Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Fri, 8 May 2009 16:05:29 -0300
Subject: V4L/DVB (11770): cx23885: add ATSC/QAM tuning support for Hauppauge
 WinTV-HVR1255

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx23885  |  1 +
 drivers/media/video/cx23885/cx23885-cards.c | 12 ++++++++++++
 drivers/media/video/cx23885/cx23885-dvb.c   | 21 +++++++++++++++++++++
 drivers/media/video/cx23885/cx23885.h       |  1 +
 4 files changed, 35 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index ce62f5a2831..e7ed710f7ea 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -18,3 +18,4 @@
  17 -> NetUP Dual DVB-S2 CI                                [1b55:2a2c]
  18 -> Hauppauge WinTV-HVR1270                             [0070:2211]
  19 -> Hauppauge WinTV-HVR1275                             [0070:2215]
+ 20 -> Hauppauge WinTV-HVR1255                             [0070:2251]
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 68ac04b7f1e..604ceb18052 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -189,6 +189,10 @@ struct cx23885_board cx23885_boards[] = {
 		.name		= "Hauppauge WinTV-HVR1275",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1255] = {
+		.name		= "Hauppauge WinTV-HVR1255",
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -296,6 +300,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x2215,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1275,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x2251,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1255,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -637,6 +645,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
+	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 		/* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
 		/* GPIO-6 I2C Gate which can isolate the 3305 from the bus */
 		/* GPIO-9 LG3305 reset */
@@ -662,6 +671,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
+	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 		/* FIXME: Implement me */
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -699,6 +709,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
+	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -758,6 +769,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
+	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 7e354a93e89..b440b55f22c 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -197,6 +197,16 @@ static struct s5h1411_config dvico_s5h1411_config = {
 	.mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
 };
 
+static struct s5h1411_config hcw_s5h1411_config = {
+	.output_mode   = S5H1411_SERIAL_OUTPUT,
+	.gpio          = S5H1411_GPIO_OFF,
+	.vsb_if        = S5H1411_IF_44000,
+	.qam_if        = S5H1411_IF_4000,
+	.inversion     = S5H1411_INVERSION_ON,
+	.status_mode   = S5H1411_DEMODLOCKING,
+	.mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
 static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
 	.i2c_address      = 0x61,
 	.if_khz           = 5380,
@@ -433,6 +443,17 @@ static int dvb_register(struct cx23885_tsport *port)
 				   &hcw_lgdt3305_tda18271_config);
 		}
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1255:
+		i2c_bus = &dev->i2c_bus[0];
+		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
+					       &hcw_s5h1411_config,
+					       &i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_bus[1].i2c_adap,
+				   &hauppauge_tda18271_config);
+		}
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1800:
 		i2c_bus = &dev->i2c_bus[0];
 		switch (alt_tuner) {
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 3c941ccc308..9b42e41f30f 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -73,6 +73,7 @@
 #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI      17
 #define CX23885_BOARD_HAUPPAUGE_HVR1270        18
 #define CX23885_BOARD_HAUPPAUGE_HVR1275        19
+#define CX23885_BOARD_HAUPPAUGE_HVR1255        20
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
cgit v1.2.3-70-g09d2


From 6b926eca9824568b18825d3eade5fb39e3b5a9fb Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Tue, 12 May 2009 17:32:17 -0300
Subject: V4L/DVB (11771): cx23885: add DVB-T tuning support for Hauppauge
 WinTV-HVR1210

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx23885  |  1 +
 drivers/media/video/cx23885/cx23885-cards.c | 20 ++++++++++++++++++--
 drivers/media/video/cx23885/cx23885-dvb.c   | 24 ++++++++++++++++++++++++
 drivers/media/video/cx23885/cx23885.h       |  1 +
 4 files changed, 44 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index e7ed710f7ea..948e436108b 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -19,3 +19,4 @@
  18 -> Hauppauge WinTV-HVR1270                             [0070:2211]
  19 -> Hauppauge WinTV-HVR1275                             [0070:2215]
  20 -> Hauppauge WinTV-HVR1255                             [0070:2251]
+ 21 -> Hauppauge WinTV-HVR1210                             [0070:2291,0070:2295]
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 604ceb18052..82fc2577b5e 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -193,6 +193,10 @@ struct cx23885_board cx23885_boards[] = {
 		.name		= "Hauppauge WinTV-HVR1255",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1210] = {
+		.name		= "Hauppauge WinTV-HVR1210",
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -304,6 +308,14 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x2251,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1255,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x2291,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1210,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x2295,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1210,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -646,9 +658,10 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
+	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 		/* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
-		/* GPIO-6 I2C Gate which can isolate the 3305 from the bus */
-		/* GPIO-9 LG3305 reset */
+		/* GPIO-6 I2C Gate which can isolate the demod from the bus */
+		/* GPIO-9 Demod reset */
 
 		/* Put the parts into reset and back */
 		cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1);
@@ -672,6 +685,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
+	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 		/* FIXME: Implement me */
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -710,6 +724,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
+	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -770,6 +785,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
+	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index b440b55f22c..22d1aefc0bf 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -128,6 +128,15 @@ static struct tda10048_config hauppauge_hvr1200_config = {
 	.clk_freq_khz     = TDA10048_CLK_16000,
 };
 
+static struct tda10048_config hauppauge_hvr1210_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_SERIAL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.if_freq_khz      = TDA10048_IF_4000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+};
+
 static struct s5h1409_config hauppauge_ezqam_config = {
 	.demod_address = 0x32 >> 1,
 	.output_mode   = S5H1409_SERIAL_OUTPUT,
@@ -237,6 +246,10 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = {
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
+static struct tda18271_config hauppauge_hvr1210_tuner_config = {
+	.gate    = TDA18271_GATE_DIGITAL,
+};
+
 static struct tda18271_std_map hcw_lgdt3305_tda18271_std_map = {
 	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
 		      .if_lvl = 1, .rfagc_top = 0x58 },
@@ -554,6 +567,17 @@ static int dvb_register(struct cx23885_tsport *port)
 				&hauppauge_hvr1200_tuner_config);
 		}
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1210:
+		i2c_bus = &dev->i2c_bus[0];
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
+			&hauppauge_hvr1210_config,
+			&i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				0x60, &dev->i2c_bus[1].i2c_adap,
+				&hauppauge_hvr1210_tuner_config);
+		}
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 		i2c_bus = &dev->i2c_bus[0];
 		fe0->dvb.frontend = dvb_attach(dib7000p_attach,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 9b42e41f30f..5067c19b659 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -74,6 +74,7 @@
 #define CX23885_BOARD_HAUPPAUGE_HVR1270        18
 #define CX23885_BOARD_HAUPPAUGE_HVR1275        19
 #define CX23885_BOARD_HAUPPAUGE_HVR1255        20
+#define CX23885_BOARD_HAUPPAUGE_HVR1210        21
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
cgit v1.2.3-70-g09d2


From 5308cf09fe16bdf65f9c6e95e7168361efe7c1d5 Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Tue, 12 May 2009 18:37:35 -0300
Subject: V4L/DVB (11772): cx23885: update model matrix for "k2c2" retail
 boards

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-cards.c | 36 +++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 82fc2577b5e..057ef36d5a6 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -357,6 +357,42 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 
 	/* Make sure we support the board model */
 	switch (tv.model) {
+	case 22001:
+		/* WinTV-HVR1270 (PCIe, Retail, half height)
+		 * ATSC/QAM and basic analog, IR Blast */
+	case 22009:
+		/* WinTV-HVR1210 (PCIe, Retail, half height)
+		 * DVB-T and basic analog, IR Blast */
+	case 22011:
+		/* WinTV-HVR1270 (PCIe, Retail, half height)
+		 * ATSC/QAM and basic analog, IR Recv */
+	case 22019:
+		/* WinTV-HVR1210 (PCIe, Retail, half height)
+		 * DVB-T and basic analog, IR Recv */
+	case 22021:
+		/* WinTV-HVR1275 (PCIe, Retail, half height)
+		 * ATSC/QAM and basic analog, IR Recv */
+	case 22029:
+		/* WinTV-HVR1210 (PCIe, Retail, half height)
+		 * DVB-T and basic analog, IR Recv */
+	case 22101:
+		/* WinTV-HVR1270 (PCIe, Retail, full height)
+		 * ATSC/QAM and basic analog, IR Blast */
+	case 22109:
+		/* WinTV-HVR1210 (PCIe, Retail, full height)
+		 * DVB-T and basic analog, IR Blast */
+	case 22111:
+		/* WinTV-HVR1270 (PCIe, Retail, full height)
+		 * ATSC/QAM and basic analog, IR Recv */
+	case 22119:
+		/* WinTV-HVR1210 (PCIe, Retail, full height)
+		 * DVB-T and basic analog, IR Recv */
+	case 22121:
+		/* WinTV-HVR1275 (PCIe, Retail, full height)
+		 * ATSC/QAM and basic analog, IR Recv */
+	case 22129:
+		/* WinTV-HVR1210 (PCIe, Retail, full height)
+		 * DVB-T and basic analog, IR Recv */
 	case 71009:
 		/* WinTV-HVR1200 (PCIe, Retail, full height)
 		 * DVB-T and basic analog */
-- 
cgit v1.2.3-70-g09d2


From 247bc54053df81ede8de32074384c74b0e2eb79b Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Tue, 12 May 2009 18:53:47 -0300
Subject: V4L/DVB (11773): cx23885: clean up struct names for Hauppauge
 WinTV-HVR127X devices

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 22d1aefc0bf..c3293d8eb33 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -250,18 +250,18 @@ static struct tda18271_config hauppauge_hvr1210_tuner_config = {
 	.gate    = TDA18271_GATE_DIGITAL,
 };
 
-static struct tda18271_std_map hcw_lgdt3305_tda18271_std_map = {
+static struct tda18271_std_map hauppauge_hvr127x_std_map = {
 	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
 		      .if_lvl = 1, .rfagc_top = 0x58 },
 	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
 		      .if_lvl = 1, .rfagc_top = 0x58 },
 };
 
-static struct tda18271_config hcw_lgdt3305_tda18271_config = {
-	.std_map = &hcw_lgdt3305_tda18271_std_map,
+static struct tda18271_config hauppauge_hvr127x_config = {
+	.std_map = &hauppauge_hvr127x_std_map,
 };
 
-static struct lgdt3305_config hcw_lgdt3305_config = {
+static struct lgdt3305_config hauppauge_lgdt3305_config = {
 	.i2c_addr           = 0x0e,
 	.mpeg_mode          = LGDT3305_MPEG_SERIAL,
 	.tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
@@ -448,12 +448,12 @@ static int dvb_register(struct cx23885_tsport *port)
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 		i2c_bus = &dev->i2c_bus[0];
 		fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
-					       &hcw_lgdt3305_config,
+					       &hauppauge_lgdt3305_config,
 					       &i2c_bus->i2c_adap);
 		if (fe0->dvb.frontend != NULL) {
 			dvb_attach(tda18271_attach, fe0->dvb.frontend,
 				   0x60, &dev->i2c_bus[1].i2c_adap,
-				   &hcw_lgdt3305_tda18271_config);
+				   &hauppauge_hvr127x_config);
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
-- 
cgit v1.2.3-70-g09d2


From b25ed9c5352ed338376481d45525392a75d40e33 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Thu, 2 Apr 2009 22:14:51 -0300
Subject: V4L/DVB (11794): au0828: reduce reset time for xc5000 to 10ms

The xc5000 datasheet indicates that the reset pin only needs to be held low
for 10ms.  Reduce the value accordingly, which speeds up the firmware load
time a bit.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/au0828/au0828-cards.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 053bbe8c8e3..830c4a933f6 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -136,9 +136,9 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
 			/* Tuner Reset Command from xc5000 */
 			/* Drive the tuner into reset and out */
 			au0828_clear(dev, REG_001, 2);
-			mdelay(200);
+			mdelay(10);
 			au0828_set(dev, REG_001, 2);
-			mdelay(50);
+			mdelay(10);
 			return 0;
 		} else {
 			printk(KERN_ERR
-- 
cgit v1.2.3-70-g09d2


From ee7e63f599ae797c785281ee552c7da98b4efb7d Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Tue, 28 Apr 2009 14:07:14 -0300
Subject: V4L/DVB (11799): xc5000: don't load firmware until a tuning request
 is made

Defer loading of the xc5000 firmware until it is actually needed.  This helps
on distros that have hald, which results in the device not being available
for use for around ten seconds in cases where the i2c bus is slow (such as
the HVR-950Q).  Also, the firmware load isn't really useful since we
immediately put the device to sleep afterward, which means a firmware reload
will be required anyway.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tuner-core.c | 4 ----
 1 file changed, 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 1dac524fc8f..4018eacb3a4 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -420,10 +420,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		if (!dvb_attach(xc5000_attach,
 				&t->fe, t->i2c->adapter, &xc5000_cfg))
 			goto attach_failed;
-
-		xc_tuner_ops = &t->fe.ops.tuner_ops;
-		if (xc_tuner_ops->init)
-			xc_tuner_ops->init(&t->fe);
 		break;
 	}
 	default:
-- 
cgit v1.2.3-70-g09d2


From e4b8bc524141f48af29f5c3096ac96701cf39c8a Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 6 May 2009 20:54:00 -0300
Subject: V4L/DVB (11805): au0828: send command to power down tuner when done
 with analog

Make sure the au0828 issues the command to power down the tuner when the
user is done using analog support.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/au0828/au0828-video.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 27bedc6c779..f42f3deaa03 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -829,6 +829,9 @@ static int au0828_v4l2_close(struct file *filp)
 
 		au0828_uninit_isoc(dev);
 
+		/* Save some power by putting tuner to sleep */
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+
 		/* When close the device, set the usb intf0 into alt0 to free
 		   USB bandwidth */
 		ret = usb_set_interface(dev->usbdev, 0, 0);
-- 
cgit v1.2.3-70-g09d2


From b8d91986e60e5e15a5283935a99ef86650744a46 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Thu, 14 May 2009 21:50:36 -0300
Subject: V4L/DVB (11807): cx88: remove xc5000 reset for Pinnacle 800i

According to the engineer at PCTV Systems, the xc5000 reset pin is supposed
to be on GPIO12.  However, despite three nights of effort, pulling that GPIO
low didn't reset the xc5000.  While pulling MO_SRST_IO low does reset the
xc5000, this also resets in the s5h1409 being reset as well.  This causes
tuning to always fail since the internal state of the s5h1409 does not match
the driver's state.

Given that the only two conditions in which the driver performs a reset is
during firmware load and powering down the chip, I am taking out the reset.
We know that the chip is being reset when the cx88 comes online, and not being
able to do power management for this board is better than not having any
tuning at all.

Problem discovered when implementing proper power management for the xc5000,
which results in calls to the reset callback *after* s5h1409 is initialized.

Cc: Steven Toth <stoth@kernellabs.com>
Cc: Chaogui Zhang <czhang1974@gmail.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-cards.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 1039757e2c4..d2aa27e90ac 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2702,10 +2702,22 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,
 	switch (core->boardnr) {
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
 		if (command == 0) { /* This is the reset command from xc5000 */
-			/* Reset XC5000 tuner via SYS_RSTO_pin */
-			cx_write(MO_SRST_IO, 0);
-			msleep(10);
-			cx_write(MO_SRST_IO, 1);
+
+			/* djh - According to the engineer at PCTV Systems,
+			   the xc5000 reset pin is supposed to be on GPIO12.
+			   However, despite three nights of effort, pulling
+			   that GPIO low didn't reset the xc5000.  While
+			   pulling MO_SRST_IO low does reset the xc5000, this
+			   also resets in the s5h1409 being reset as well.
+			   This causes tuning to always fail since the internal
+			   state of the s5h1409 does not match the driver's
+			   state.  Given that the only two conditions in which
+			   the driver performs a reset is during firmware load
+			   and powering down the chip, I am taking out the
+			   reset.  We know that the chip is being reset
+			   when the cx88 comes online, and not being able to
+			   do power management for this board is worse than
+			   not having any tuning at all. */
 			return 0;
 		} else {
 			err_printk(core, "xc5000: unknown tuner "
-- 
cgit v1.2.3-70-g09d2


From 027aa2c771d9fb8dc6aae95c80b50e40e3c97dc5 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Thu, 14 May 2009 23:38:51 -0300
Subject: V4L/DVB (11808): au0828: get rid of debug printk that was causing
 compile failures

Remove a debug printk() line I added which is no longer needed, and happened
to be causing compile failures on some earlier kernels in Han's daily
compile report.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/au0828/au0828-video.c | 5 -----
 1 file changed, 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index f42f3deaa03..51527d7b55a 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -913,11 +913,6 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
 
 	rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
 
-	dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
-		(unsigned long)vma->vm_start,
-		(unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
-		rc);
-
 	return rc;
 }
 
-- 
cgit v1.2.3-70-g09d2


From d18e2fda7133287bf8a81809816e646cf17c332e Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Sat, 16 May 2009 17:09:28 -0300
Subject: V4L/DVB (11810): em28xx: properly set packet size based on the
 device's eeprom configuration.

The em28xx actually has a register that tells the driver what the maximum
packet size is (based on a value programmed into the eeprom).  Make use of
that register instead of assuming a hardcoded value of 564 (since 564 is not
correct for devices that do QAM such as the KWorld 340u).

Note that for now the em2874 code isn't there, falling back to the 564 value,
however this is not a problem since there are not any em2874 based devices in
the current v4l-dvb tree).

Thanks to Jarod Wilson for detecting the initial problem and figuring out that
the isoc configuration was wrong for his device.

Cc: Jarod Wilson <jarod@wilsonet.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-core.c | 35 ++++++++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx-dvb.c  |  6 ++++--
 drivers/media/video/em28xx/em28xx-reg.h  | 16 +++++++++++++++
 drivers/media/video/em28xx/em28xx.h      |  1 +
 4 files changed, 56 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 7375353c04e..b7a2fedc390 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1012,6 +1012,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 }
 EXPORT_SYMBOL_GPL(em28xx_init_isoc);
 
+/* Determine the packet size for the DVB stream for the given device
+   (underlying value programmed into the eeprom) */
+int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
+{
+	unsigned int chip_cfg2;
+	unsigned int packet_size = 564;
+
+	if (dev->chip_id == CHIP_ID_EM2874) {
+		/* FIXME - for now assume 564 like it was before, but the
+		   em2874 code should be added to return the proper value... */
+		packet_size = 564;
+	} else {
+		/* TS max packet size stored in bits 1-0 of R01 */
+		chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
+		switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
+		case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
+			packet_size = 188;
+			break;
+		case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
+			packet_size = 376;
+			break;
+		case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
+			packet_size = 564;
+			break;
+		case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
+			packet_size = 752;
+			break;
+		}
+	}
+
+	em28xx_coredbg("dvb max packet size=%d\n", packet_size);
+	return packet_size;
+}
+EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);
+
 /*
  * em28xx_wake_i2c()
  * configure i2c attached devices
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index c8188dc2b4b..e0438acf122 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -46,7 +46,6 @@ if (debug >= level) 						\
 } while (0)
 
 #define EM28XX_DVB_NUM_BUFS 5
-#define EM28XX_DVB_MAX_PACKETSIZE 564
 #define EM28XX_DVB_MAX_PACKETS 64
 
 struct em28xx_dvb {
@@ -142,14 +141,17 @@ static int start_streaming(struct em28xx_dvb *dvb)
 {
 	int rc;
 	struct em28xx *dev = dvb->adapter.priv;
+	int max_dvb_packet_size;
 
 	usb_set_interface(dev->udev, 0, 1);
 	rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	if (rc < 0)
 		return rc;
 
+	max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
+
 	return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS,
-				EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE,
+				EM28XX_DVB_NUM_BUFS, max_dvb_packet_size,
 				dvb_isoc_copy);
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 24e39c56811..a2676d63cfd 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -27,6 +27,22 @@
 #define EM28XX_CHIPCFG_AC97			0x10
 #define EM28XX_CHIPCFG_AUDIOMASK		0x30
 
+#define EM28XX_R01_CHIPCFG2	0x01
+
+/* em28xx Chip Configuration 2 0x01 */
+#define EM28XX_CHIPCFG2_TS_PRESENT		0x10
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK	0x0c /* bits 3-2 */
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF	0x00
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF	0x04
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF	0x08
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF	0x0c
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK	0x03 /* bits 0-1 */
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_188	0x00
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_376	0x01
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_564	0x02
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_752	0x03
+
+
 	/* GPIO/GPO registers */
 #define EM2880_R04_GPO	0x04    /* em2880-em2883 only */
 #define EM28XX_R08_GPIO	0x08	/* em2820 or upper */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 16f4c23f179..e801f783bdc 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -616,6 +616,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 		     int num_bufs, int max_pkt_size,
 		     int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
 void em28xx_uninit_isoc(struct em28xx *dev);
+int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
 int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
 int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
 void em28xx_wake_i2c(struct em28xx *dev);
-- 
cgit v1.2.3-70-g09d2


From 4557af9c5338605c85fe54f5ebba3d4b14a60ab8 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Sat, 23 May 2009 09:58:52 -0300
Subject: V4L/DVB (11825): em28xx: add Terratec Grabby

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 18 ++++++++++++++++++
 drivers/media/video/em28xx/em28xx.h       |  1 +
 2 files changed, 19 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7cb93fbbbbf..b4c78f2ab98 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1347,6 +1347,22 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_VIDEO,
 		} },
 	},
+	[EM2860_BOARD_TERRATEC_GRABBY] = {
+		.name            = "Terratec Grabby",
+		.vchannels       = 2,
+		.tuner_type      = TUNER_ABSENT,
+		.decoder         = EM28XX_SAA711X,
+		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.input           = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO2,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_VIDEO2,
+		} },
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1410,6 +1426,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2870_BOARD_TERRATEC_XS },
 	{ USB_DEVICE(0x0ccd, 0x0047),
 			.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+	{ USB_DEVICE(0x0ccd, 0x0096),
+			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
 	{ USB_DEVICE(0x185b, 0x2870),
 			.driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
 	{ USB_DEVICE(0x185b, 0x2041),
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index e801f783bdc..fa2fb411083 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -103,6 +103,7 @@
 #define EM2860_BOARD_EASYCAP                      64
 #define EM2820_BOARD_IODATA_GVMVP_SZ		  65
 #define EM2880_BOARD_EMPIRE_DUAL_TV		  66
+#define EM2860_BOARD_TERRATEC_GRABBY		  67
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
-- 
cgit v1.2.3-70-g09d2


From 766ed64de554fda08ceb927d36279eabcb08acb3 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Sun, 24 May 2009 00:46:01 -0300
Subject: V4L/DVB (11827): Add support for Terratec Grabster AV350

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 32 +++++++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx.h       |  1 +
 2 files changed, 33 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index b4c78f2ab98..3958f168fc5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -140,6 +140,16 @@ static struct em28xx_reg_seq compro_mute_gpio[] = {
 	{  -1,			-1,		-1,		-1},
 };
 
+/* Terratec AV350 */
+static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
+	{EM28XX_R08_GPIO,	0xff,	0x7f,		10},
+	{	-1,		-1,	-1,		-1},
+};
+
+static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
+	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{	-1,		-1,	-1,		-1},
+};
 /*
  *  Board definitions
  */
@@ -1363,6 +1373,26 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_VIDEO2,
 		} },
 	},
+	[EM2860_BOARD_TERRATEC_AV350] = {
+		.name            = "Terratec AV350",
+		.vchannels       = 2,
+		.tuner_type      = TUNER_ABSENT,
+		.decoder         = EM28XX_TVP5150,
+		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.mute_gpio       = terratec_av350_mute_gpio,
+		.input           = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = EM28XX_AUDIO_SRC_LINE,
+                        .gpio     = terratec_av350_unmute_gpio,
+
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = EM28XX_AUDIO_SRC_LINE,
+                        .gpio     = terratec_av350_unmute_gpio,
+		} },
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1426,6 +1456,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2870_BOARD_TERRATEC_XS },
 	{ USB_DEVICE(0x0ccd, 0x0047),
 			.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+	{ USB_DEVICE(0x0ccd, 0x0084),
+			.driver_info = EM2860_BOARD_TERRATEC_AV350 },
 	{ USB_DEVICE(0x0ccd, 0x0096),
 			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
 	{ USB_DEVICE(0x185b, 0x2870),
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index fa2fb411083..58c0ef4a2dc 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -104,6 +104,7 @@
 #define EM2820_BOARD_IODATA_GVMVP_SZ		  65
 #define EM2880_BOARD_EMPIRE_DUAL_TV		  66
 #define EM2860_BOARD_TERRATEC_GRABBY		  67
+#define EM2860_BOARD_TERRATEC_AV350		  68
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
-- 
cgit v1.2.3-70-g09d2


From 078f8947926732a526fb280c0f3a8920bf173b9c Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Wed, 6 May 2009 12:30:30 -0300
Subject: V4L/DVB (11835): uvcvideo: Parse frame descriptors with
 non-continuous indexes.

The UVC specification requires frame descriptors indexes to range from 1 to
the number of frame descriptors. At least some Hercules Dualpix Infinite
webcams erroneously use non-continuous index ranges. Make the driver support
them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 24 ++----------------------
 drivers/media/video/uvc/uvc_video.c  | 17 +++++++++++------
 2 files changed, 13 insertions(+), 28 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 507dc85646b..34cd36037f1 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -289,10 +289,8 @@ static int uvc_parse_format(struct uvc_device *dev,
 	struct uvc_format_desc *fmtdesc;
 	struct uvc_frame *frame;
 	const unsigned char *start = buffer;
-	unsigned char *_buffer;
 	unsigned int interval;
 	unsigned int i, n;
-	int _buflen;
 	__u8 ftype;
 
 	format->type = buffer[2];
@@ -413,20 +411,11 @@ static int uvc_parse_format(struct uvc_device *dev,
 	buflen -= buffer[0];
 	buffer += buffer[0];
 
-	/* Count the number of frame descriptors to test the bFrameIndex
-	 * field when parsing the descriptors. We can't rely on the
-	 * bNumFrameDescriptors field as some cameras don't initialize it
-	 * properly.
-	 */
-	for (_buflen = buflen, _buffer = buffer;
-	     _buflen > 2 && _buffer[2] == ftype;
-	     _buflen -= _buffer[0], _buffer += _buffer[0])
-		format->nframes++;
-
 	/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
 	 * based formats have frame descriptors.
 	 */
 	while (buflen > 2 && buffer[2] == ftype) {
+		frame = &format->frame[format->nframes];
 		if (ftype != VS_FRAME_FRAME_BASED)
 			n = buflen > 25 ? buffer[25] : 0;
 		else
@@ -441,16 +430,6 @@ static int uvc_parse_format(struct uvc_device *dev,
 			return -EINVAL;
 		}
 
-		if (buffer[3] - 1 >= format->nframes) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
-			       "interface %d frame index %u out of range\n",
-			       dev->udev->devnum, alts->desc.bInterfaceNumber,
-			       buffer[3]);
-			return -EINVAL;
-		}
-
-		frame = &format->frame[buffer[3] - 1];
-
 		frame->bFrameIndex = buffer[3];
 		frame->bmCapabilities = buffer[4];
 		frame->wWidth = get_unaligned_le16(&buffer[5]);
@@ -507,6 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 			10000000/frame->dwDefaultFrameInterval,
 			(100000000/frame->dwDefaultFrameInterval)%10);
 
+		format->nframes++;
 		buflen -= buffer[0];
 		buffer += buffer[0];
 	}
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6ce974d7362..01b633c7348 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl)
 {
 	struct uvc_format *format;
-	struct uvc_frame *frame;
+	struct uvc_frame *frame = NULL;
+	unsigned int i;
 
 	if (ctrl->bFormatIndex <= 0 ||
 	    ctrl->bFormatIndex > video->streaming->nformats)
@@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 
 	format = &video->streaming->format[ctrl->bFormatIndex - 1];
 
-	if (ctrl->bFrameIndex <= 0 ||
-	    ctrl->bFrameIndex > format->nframes)
-		return;
+	for (i = 0; i < format->nframes; ++i) {
+		if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
+			frame = &format->frame[i];
+			break;
+		}
+	}
 
-	frame = &format->frame[ctrl->bFrameIndex - 1];
+	if (frame == NULL)
+		return;
 
 	if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
 	     (ctrl->dwMaxVideoFrameSize == 0 &&
@@ -1089,7 +1094,7 @@ int uvc_video_init(struct uvc_video_device *video)
 	/* Zero bFrameIndex might be correct. Stream-based formats (including
 	 * MPEG-2 TS and DV) do not support frames but have a dummy frame
 	 * descriptor with bFrameIndex set to zero. If the default frame
-	 * descriptor is not found, use the first avalable frame.
+	 * descriptor is not found, use the first available frame.
 	 */
 	for (i = format->nframes; i > 0; --i) {
 		frame = &format->frame[i-1];
-- 
cgit v1.2.3-70-g09d2


From b2d9cc4226fa512aa36fd78738f5069dfce0583d Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Wed, 6 May 2009 12:37:44 -0300
Subject: V4L/DVB (11836): uvcvideo: Add missing whitespaces to multi-line
 format strings.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 34cd36037f1..f4fced34cfd 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -301,7 +301,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 	case VS_FORMAT_FRAME_BASED:
 		n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
 		if (buflen < n) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
 			       dev->udev->devnum,
 			       alts->desc.bInterfaceNumber);
@@ -336,7 +336,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
 	case VS_FORMAT_MJPEG:
 		if (buflen < 11) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
 			       dev->udev->devnum,
 			       alts->desc.bInterfaceNumber);
@@ -352,7 +352,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
 	case VS_FORMAT_DV:
 		if (buflen < 9) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
 			       dev->udev->devnum,
 			       alts->desc.bInterfaceNumber);
@@ -370,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 			strlcpy(format->name, "HD-DV", sizeof format->name);
 			break;
 		default:
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d: unknown DV format %u\n",
 			       dev->udev->devnum,
 			       alts->desc.bInterfaceNumber, buffer[8]);
@@ -399,7 +399,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 	case VS_FORMAT_STREAM_BASED:
 		/* Not supported yet. */
 	default:
-		uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+		uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 		       "interface %d unsupported format %u\n",
 		       dev->udev->devnum, alts->desc.bInterfaceNumber,
 		       buffer[2]);
@@ -424,7 +424,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 		n = n ? n : 3;
 
 		if (buflen < 26 + 4*n) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FRAME error\n", dev->udev->devnum,
 			       alts->desc.bInterfaceNumber);
 			return -EINVAL;
@@ -498,7 +498,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
 	if (buflen > 2 && buffer[2] == VS_COLORFORMAT) {
 		if (buflen < 6) {
-			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d COLORFORMAT error\n",
 			       dev->udev->devnum,
 			       alts->desc.bInterfaceNumber);
@@ -1296,7 +1296,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
 			continue;
 
 		if (forward->extension.bNrInPins != 1) {
-			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has"
+			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has "
 				"more than 1 input pin.\n", entity->id);
 			return -1;
 		}
-- 
cgit v1.2.3-70-g09d2


From 04a37e0f32f9882430bc1899899d2ed91b8aaf5b Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Tue, 19 May 2009 10:08:03 -0300
Subject: V4L/DVB (11837): uvcvideo: Start status polling on device open

Most UVC camera include an interrupt endpoint to report control value changes,
video streaming errors and camera button events. The USB controller
continuously polls the interrupt endpoint to retrieve such events. This
prevents the device from being auto-suspended, and thus consumes power.

Reporting video streaming errors don't make sense when the V4L2 device is
closed. Control value changes are probably useless as well if nobody listens to
the events, although caching will probably have to be completely disabled then.
No polling is thus be required when /dev/videoX is not opened.

To enable auto-suspend and save power do not poll the interrupt endpoint until
the device is open. We lose the ability to detect button events if no
application is using the camera.

http://bugzilla.kernel.org/show_bug.cgi?id=11948

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c |  1 +
 drivers/media/video/uvc/uvc_status.c | 21 ++++++++++++++++++---
 drivers/media/video/uvc/uvc_v4l2.c   | 12 ++++++++++++
 drivers/media/video/uvc/uvcvideo.h   |  3 +++
 4 files changed, 34 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index f4fced34cfd..3287454bb36 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1594,6 +1594,7 @@ static int uvc_probe(struct usb_interface *intf,
 	INIT_LIST_HEAD(&dev->entities);
 	INIT_LIST_HEAD(&dev->streaming);
 	kref_init(&dev->kref);
+	atomic_set(&dev->users, 0);
 
 	dev->udev = usb_get_dev(udev);
 	dev->intf = usb_get_intf(intf);
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 21d87124986..f152a990386 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -194,7 +194,7 @@ int uvc_status_init(struct uvc_device *dev)
 		dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
 		dev, interval);
 
-	return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+	return 0;
 }
 
 void uvc_status_cleanup(struct uvc_device *dev)
@@ -205,15 +205,30 @@ void uvc_status_cleanup(struct uvc_device *dev)
 	uvc_input_cleanup(dev);
 }
 
-int uvc_status_suspend(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev)
+{
+	if (dev->int_urb == NULL)
+		return 0;
+
+	return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+}
+
+void uvc_status_stop(struct uvc_device *dev)
 {
 	usb_kill_urb(dev->int_urb);
+}
+
+int uvc_status_suspend(struct uvc_device *dev)
+{
+	if (atomic_read(&dev->users))
+		usb_kill_urb(dev->int_urb);
+
 	return 0;
 }
 
 int uvc_status_resume(struct uvc_device *dev)
 {
-	if (dev->int_urb == NULL)
+	if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
 		return 0;
 
 	return usb_submit_urb(dev->int_urb, GFP_NOIO);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index ad7e64ff3ad..507542dcbda 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -439,6 +439,15 @@ static int uvc_v4l2_open(struct file *file)
 		goto done;
 	}
 
+	if (atomic_inc_return(&video->dev->users) == 1) {
+		if ((ret = uvc_status_start(video->dev)) < 0) {
+			usb_autopm_put_interface(video->dev->intf);
+			atomic_dec(&video->dev->users);
+			kfree(handle);
+			goto done;
+		}
+	}
+
 	handle->device = video;
 	handle->state = UVC_HANDLE_PASSIVE;
 	file->private_data = handle;
@@ -473,6 +482,9 @@ static int uvc_v4l2_release(struct file *file)
 	kfree(handle);
 	file->private_data = NULL;
 
+	if (atomic_dec_return(&video->dev->users) == 0)
+		uvc_status_stop(video->dev);
+
 	usb_autopm_put_interface(video->dev->intf);
 	kref_put(&video->dev->kref, uvc_delete);
 	return 0;
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e5014e668f9..daf07444730 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -634,6 +634,7 @@ struct uvc_device {
 	enum uvc_device_state state;
 	struct kref kref;
 	struct list_head list;
+	atomic_t users;
 
 	/* Video control interface */
 	__u16 uvc_version;
@@ -770,6 +771,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);
 extern void uvc_status_cleanup(struct uvc_device *dev);
+extern int uvc_status_start(struct uvc_device *dev);
+extern void uvc_status_stop(struct uvc_device *dev);
 extern int uvc_status_suspend(struct uvc_device *dev);
 extern int uvc_status_resume(struct uvc_device *dev);
 
-- 
cgit v1.2.3-70-g09d2


From 1010ed132727bbf486ac28fd149ccfb0ef5cd2ab Mon Sep 17 00:00:00 2001
From: "Cohen David.A" <david.cohen@nokia.com>
Date: Mon, 11 May 2009 11:00:20 -0300
Subject: V4L/DVB (11840): change kmalloc to vmalloc for sglist allocation in
 videobuf_dma_map/unmap

Change kmalloc()/kfree() to vmalloc()/vfree() for sglist allocation
during videobuf_dma_map() and videobuf_dma_unmap()

High resolution sensors might require too many contiguous pages
to be allocated for sglist by kmalloc() during videobuf_dma_map()
(i.e. 256Kib for 8MP sensor).
In such situations, kmalloc() could face some problem to find the
required free memory. vmalloc() is a safer solution instead, as the
allocated memory does not need to be contiguous.

Signed-off-by: David Cohen <david.cohen@nokia.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.em28xx |  2 ++
 drivers/media/video/videobuf-dma-sg.c     | 17 +++++++++--------
 2 files changed, 11 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index bf58d957e0d..20aa65a7059 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -62,3 +62,5 @@
  64 -> Easy Cap Capture DC-60                   (em2860)
  65 -> IO-DATA GV-MVP/SZ                        (em2820/em2840) [04bb:0515]
  66 -> Empire dual TV                           (em2880)
+ 67 -> Terratec Grabby                          (em2860)        [0ccd:0096]
+ 68 -> Terratec AV350                           (em2860)        [0ccd:0084]
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index da1790e57a8..c9a5d7edbe4 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -58,9 +58,10 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	struct page *pg;
 	int i;
 
-	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
+	sglist = vmalloc(nr_pages * sizeof(*sglist));
 	if (NULL == sglist)
 		return NULL;
+	memset(sglist, 0, nr_pages * sizeof(*sglist));
 	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
@@ -72,7 +73,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	return sglist;
 
  err:
-	kfree(sglist);
+	vfree(sglist);
 	return NULL;
 }
 
@@ -84,7 +85,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 
 	if (NULL == pages[0])
 		return NULL;
-	sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL);
+	sglist = vmalloc(nr_pages * sizeof(*sglist));
 	if (NULL == sglist)
 		return NULL;
 	sg_init_table(sglist, nr_pages);
@@ -104,12 +105,12 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 
  nopage:
 	dprintk(2,"sgl: oops - no page\n");
-	kfree(sglist);
+	vfree(sglist);
 	return NULL;
 
  highmem:
 	dprintk(2,"sgl: oops - highmem page\n");
-	kfree(sglist);
+	vfree(sglist);
 	return NULL;
 }
 
@@ -230,7 +231,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
 						(dma->vmalloc,dma->nr_pages);
 	}
 	if (dma->bus_addr) {
-		dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
+		dma->sglist = vmalloc(sizeof(*dma->sglist));
 		if (NULL != dma->sglist) {
 			dma->sglen  = 1;
 			sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
@@ -248,7 +249,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
 		if (0 == dma->sglen) {
 			printk(KERN_WARNING
 			       "%s: videobuf_map_sg failed\n",__func__);
-			kfree(dma->sglist);
+			vfree(dma->sglist);
 			dma->sglist = NULL;
 			dma->sglen = 0;
 			return -EIO;
@@ -274,7 +275,7 @@ int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
 
 	dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction);
 
-	kfree(dma->sglist);
+	vfree(dma->sglist);
 	dma->sglist = NULL;
 	dma->sglen = 0;
 	return 0;
-- 
cgit v1.2.3-70-g09d2


From 1df8e9861cf9fac5737ccb61c7f7fefa77711d40 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:48:07 -0300
Subject: V4L/DVB (11843): ir-kbd-i2c: Don't use i2c_client.name for our own
 needs

In the standard device driver binding model, the name field of
struct i2c_client is used to match devices to their drivers, so we
must stop using it for internal purposes. Define a separate field
in struct IR_i2c as a replacement, and use it.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-input.c |  2 +-
 drivers/media/video/em28xx/em28xx-cards.c   | 10 +++++-----
 drivers/media/video/em28xx/em28xx-input.c   |  2 +-
 drivers/media/video/ir-kbd-i2c.c            |  5 +++--
 drivers/media/video/saa7134/saa7134-input.c | 12 ++++++------
 include/media/ir-kbd-i2c.h                  |  1 +
 6 files changed, 17 insertions(+), 15 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 97e304c3c79..48f22fa38e6 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
 
 #define i2cdprintk(fmt, arg...) \
 	if (ir_debug) { \
-		printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
 	}
 
 #define dprintk(fmt, arg...) \
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3958f168fc5..b2aed29e2d7 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1384,13 +1384,13 @@ struct em28xx_board em28xx_boards[] = {
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.vmux     = TVP5150_COMPOSITE1,
 			.amux     = EM28XX_AUDIO_SRC_LINE,
-                        .gpio     = terratec_av350_unmute_gpio,
+			.gpio     = terratec_av350_unmute_gpio,
 
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = TVP5150_SVIDEO,
 			.amux     = EM28XX_AUDIO_SRC_LINE,
-                        .gpio     = terratec_av350_unmute_gpio,
+			.gpio     = terratec_av350_unmute_gpio,
 		} },
 	},
 };
@@ -1929,19 +1929,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
 	case (EM2820_BOARD_TERRATEC_CINERGY_250):
 		ir->ir_codes = ir_codes_em_terratec;
 		ir->get_key = em28xx_get_key_terratec;
-		snprintf(ir->c.name, sizeof(ir->c.name),
+		snprintf(ir->name, sizeof(ir->name),
 			 "i2c IR (EM28XX Terratec)");
 		break;
 	case (EM2820_BOARD_PINNACLE_USB_2):
 		ir->ir_codes = ir_codes_pinnacle_grey;
 		ir->get_key = em28xx_get_key_pinnacle_usb_grey;
-		snprintf(ir->c.name, sizeof(ir->c.name),
+		snprintf(ir->name, sizeof(ir->name),
 			 "i2c IR (EM28XX Pinnacle PCTV)");
 		break;
 	case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
 		ir->ir_codes = ir_codes_hauppauge_new;
 		ir->get_key = em28xx_get_key_em_haup;
-		snprintf(ir->c.name, sizeof(ir->c.name),
+		snprintf(ir->name, sizeof(ir->name),
 			 "i2c IR (EM2840 Hauppauge)");
 		break;
 	case (EM2820_BOARD_MSI_VOX_USB_2):
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index a5abfd7a19f..7450ba7dee8 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
 
 #define i2cdprintk(fmt, arg...) \
 	if (ir_debug) { \
-		printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
 	}
 
 #define dprintk(fmt, arg...) \
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 092c7da0f37..ba341e6fb2d 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -337,6 +337,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 
 	ir->c.adapter = adap;
 	ir->c.addr    = addr;
+	snprintf(ir->c.name, sizeof(ir->c.name), "ir-kbd");
 
 	i2c_set_clientdata(&ir->c, ir);
 
@@ -410,7 +411,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 	}
 
 	/* Sets name */
-	snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
+	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
 
 	/* register i2c device
@@ -435,7 +436,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 	/* init + register input device */
 	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
 	input_dev->id.bustype = BUS_I2C;
-	input_dev->name       = ir->c.name;
+	input_dev->name       = ir->name;
 	input_dev->phys       = ir->phys;
 
 	err = input_register_device(ir->input);
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 45063751726..6cd693d3b8e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
 #define dprintk(fmt, arg...)	if (ir_debug) \
 	printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
-	printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
+	printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
 
 /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
 static int saa7134_rc5_irq(struct saa7134_dev *dev);
@@ -693,7 +693,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
-		snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
+		snprintf(ir->name, sizeof(ir->name), "Pinnacle PCTV");
 		if (pinnacle_remote == 0) {
 			ir->get_key   = get_key_pinnacle_color;
 			ir->ir_codes = ir_codes_pinnacle_color;
@@ -703,17 +703,17 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 		}
 		break;
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
-		snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
+		snprintf(ir->name, sizeof(ir->name), "Purple TV");
 		ir->get_key   = get_key_purpletv;
 		ir->ir_codes  = ir_codes_purpletv;
 		break;
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
-		snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
+		snprintf(ir->name, sizeof(ir->name), "MSI TV@nywhere Plus");
 		ir->get_key  = get_key_msi_tvanywhere_plus;
 		ir->ir_codes = ir_codes_msi_tvanywhere_plus;
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-		snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
+		snprintf(ir->name, sizeof(ir->name), "HVR 1110");
 		ir->get_key   = get_key_hvr1110;
 		ir->ir_codes  = ir_codes_hauppauge_new;
 		break;
@@ -729,7 +729,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
 	case SAA7134_BOARD_BEHOLD_H6:
-		snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
+		snprintf(ir->name, sizeof(ir->name), "BeholdTV");
 		ir->get_key   = get_key_beholdm6xx;
 		ir->ir_codes  = ir_codes_behold;
 		break;
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 07963d70540..6a9719c8e90 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -15,6 +15,7 @@ struct IR_i2c {
 	unsigned char          old;
 
 	struct delayed_work    work;
+	char                   name[32];
 	char                   phys[32];
 	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
 };
-- 
cgit v1.2.3-70-g09d2


From c668f32dca105d876e51862a003a302fa61e4ae4 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:48:50 -0300
Subject: V4L/DVB (11844): ir-kbd-i2c: Switch to the new-style device binding
 model

Let card drivers probe for IR receiver devices and instantiate them if
found. Ultimately it would be better if we could stop probing
completely, but I suspect this won't be possible for all card types.

There's certainly room for cleanups. For example, some drivers are
sharing I2C adapter IDs, so they also had to share the list of I2C
addresses being probed for an IR receiver. Now that each driver
explicitly says which addresses should be probed, maybe some addresses
can be dropped from some drivers.

Also, the special cases in saa7134-i2c should probably be handled on a
per-board basis. This would be more efficient and less risky than always
probing extra addresses on all boards. I'll give it a try later.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/bt8xx/bttv-i2c.c        |  21 +++
 drivers/media/video/cx231xx/cx231xx-cards.c |  11 +-
 drivers/media/video/cx231xx/cx231xx-i2c.c   |   3 +
 drivers/media/video/cx231xx/cx231xx.h       |   1 +
 drivers/media/video/cx23885/cx23885-i2c.c   |  12 ++
 drivers/media/video/cx88/cx88-i2c.c         |  13 ++
 drivers/media/video/em28xx/em28xx-cards.c   |  20 ++-
 drivers/media/video/em28xx/em28xx-i2c.c     |   3 +
 drivers/media/video/em28xx/em28xx-input.c   |   6 +-
 drivers/media/video/em28xx/em28xx.h         |   1 +
 drivers/media/video/ir-kbd-i2c.c            | 200 +++++-----------------------
 drivers/media/video/ivtv/ivtv-i2c.c         |  31 ++++-
 drivers/media/video/saa7134/saa7134-i2c.c   |   3 +
 drivers/media/video/saa7134/saa7134-input.c |  86 ++++++++++--
 drivers/media/video/saa7134/saa7134.h       |   1 +
 include/media/ir-kbd-i2c.h                  |   2 +-
 16 files changed, 220 insertions(+), 194 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index a99d92fac3d..ebd1ee9dc87 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -389,6 +389,27 @@ int __devinit init_bttv_i2c(struct bttv *btv)
 	}
 	if (0 == btv->i2c_rc && i2c_scan)
 		do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
+
+	/* Instantiate the IR receiver device, if present */
+	if (0 == btv->i2c_rc) {
+		struct i2c_board_info info;
+		/* The external IR receiver is at i2c address 0x34 (0x35 for
+		   reads).  Future Hauppauge cards will have an internal
+		   receiver at 0x30 (0x31 for reads).  In theory, both can be
+		   fitted, and Hauppauge suggest an external overrides an
+		   internal.
+
+		   That's why we probe 0x1a (~0x34) first. CB
+		*/
+		const unsigned short addr_list[] = {
+			0x1a, 0x18, 0x4b, 0x64, 0x30,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
+	}
 	return btv->i2c_rc;
 }
 
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index c8a32b1b538..734f6eaefd9 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -281,13 +281,16 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
 }
 
 /* ----------------------------------------------------------------------- */
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+void cx231xx_register_i2c_ir(struct cx231xx *dev)
 {
-	if (disable_ir) {
-		ir->get_key = NULL;
+	if (disable_ir)
 		return;
-	}
 
+	/* REVISIT: instantiate IR device */
+}
+
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+{
 	/* detect & configure */
 	switch (dev->model) {
 
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index b4a03d813e0..ac4099a49da 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -537,6 +537,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus)
 	if (0 == bus->i2c_rc) {
 		if (i2c_scan)
 			cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+
+		/* Instantiate the IR receiver device, if present */
+		cx231xx_register_i2c_ir(dev);
 	} else
 		cx231xx_warn("%s: i2c bus %d register FAILED\n",
 			     dev->name, bus->nr);
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index aa4a23ef491..8c300f60fdf 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -738,6 +738,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev);
 extern struct cx231xx_board cx231xx_boards[];
 extern struct usb_device_id cx231xx_id_table[];
 extern const unsigned int cx231xx_bcount;
+void cx231xx_register_i2c_ir(struct cx231xx *dev);
 void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
 int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
 
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 3421bd12056..384dec34134 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -357,6 +357,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
 		printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
 			dev->name, bus->nr);
 
+	/* Instantiate the IR receiver device, if present */
+	if (0 == bus->i2c_rc) {
+		struct i2c_board_info info;
+		const unsigned short addr_list[] = {
+			0x6b, I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
+	}
+
 	return bus->i2c_rc;
 }
 
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 996b4ed5a4f..ee1ca39db06 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -180,6 +180,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
 			do_i2c_scan(core->name,&core->i2c_client);
 	} else
 		printk("%s: i2c register FAILED\n", core->name);
+
+	/* Instantiate the IR receiver device, if present */
+	if (0 == core->i2c_rc) {
+		struct i2c_board_info info;
+		const unsigned short addr_list[] = {
+			0x18, 0x6b, 0x71,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
+	}
 	return core->i2c_rc;
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index b2aed29e2d7..edba71115a9 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1912,13 +1912,23 @@ static int em28xx_hint_board(struct em28xx *dev)
 }
 
 /* ----------------------------------------------------------------------- */
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+void em28xx_register_i2c_ir(struct em28xx *dev)
 {
-	if (disable_ir) {
-		ir->get_key = NULL;
-		return ;
-	}
+	struct i2c_board_info info;
+	const unsigned short addr_list[] = {
+		 0x30, 0x47, I2C_CLIENT_END
+	};
+
+	if (disable_ir)
+		return;
 
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+}
+
+void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+{
 	/* detect & configure */
 	switch (dev->model) {
 	case (EM2800_BOARD_UNKNOWN):
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index f0bf1d960c7..d90294cbb70 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -575,6 +575,9 @@ int em28xx_i2c_register(struct em28xx *dev)
 	if (i2c_scan)
 		em28xx_do_i2c_scan(dev);
 
+	/* Instantiate the IR receiver device, if present */
+	em28xx_register_i2c_ir(dev);
+
 	return 0;
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 7450ba7dee8..7a0fe3816e3 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -85,7 +85,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -114,7 +114,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char code;
 
 	/* poll IR chip */
-	if (2 != i2c_master_recv(&ir->c, buf, 2))
+	if (2 != i2c_master_recv(ir->c, buf, 2))
 		return -EIO;
 
 	/* Does eliminate repeated parity code */
@@ -147,7 +147,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
 
 	/* poll IR chip */
 
-	if (3 != i2c_master_recv(&ir->c, buf, 3)) {
+	if (3 != i2c_master_recv(ir->c, buf, 3)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 58c0ef4a2dc..9c632541df1 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -643,6 +643,7 @@ extern void em28xx_card_setup(struct em28xx *dev);
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
 extern const unsigned int em28xx_bcount;
+void em28xx_register_i2c_ir(struct em28xx *dev);
 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
 void em28xx_release_resources(struct em28xx *dev);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index ba341e6fb2d..cb833a63041 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
 	int start, range, toggle, dev, code, ircode;
 
 	/* poll IR chip */
-	if (size != i2c_master_recv(&ir->c,buf,size))
+	if (size != i2c_master_recv(ir->c, buf, size))
 		return -EIO;
 
 	/* split rc5 data block ... */
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char buf[4];
 
 	/* poll IR chip */
-	if (4 != i2c_master_recv(&ir->c,buf,4)) {
+	if (4 != i2c_master_recv(ir->c, buf, 4)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
 				     u32 *ir_key, u32 *ir_raw)
 {
 	unsigned char subaddr, key, keygroup;
-	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
 				   .buf = &subaddr, .len = 1},
-				 { .addr = ir->c.addr, .flags = I2C_M_RD,
+				 { .addr = ir->c->addr, .flags = I2C_M_RD,
 				  .buf = &key, .len = 1} };
 	subaddr = 0x0d;
-	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
 		dprintk(1, "read error\n");
 		return -EIO;
 	}
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
 
 	subaddr = 0x0b;
 	msg[1].buf = &keygroup;
-	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
 		dprintk(1, "read error\n");
 		return -EIO;
 	}
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work)
 
 	/* MSI TV@nywhere Plus requires more frequent polling
 	   otherwise it will miss some keypresses */
-	if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
+	if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30)
 		polling_interval = 50;
 
 	ir_key_poll(ir);
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work)
 
 /* ----------------------------------------------------------------------- */
 
-static int ir_attach(struct i2c_adapter *adap, int addr,
-		      unsigned short flags, int kind);
-static int ir_detach(struct i2c_client *client);
-static int ir_probe(struct i2c_adapter *adap);
-
-static struct i2c_driver driver = {
-	.driver = {
-		.name   = "ir-kbd-i2c",
-	},
-	.id             = I2C_DRIVERID_INFRARED,
-	.attach_adapter = ir_probe,
-	.detach_client  = ir_detach,
-};
-
-static struct i2c_client client_template =
-{
-	.name = "unset",
-	.driver = &driver
-};
-
-static int ir_attach(struct i2c_adapter *adap, int addr,
-		     unsigned short flags, int kind)
+static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	char *name;
 	int ir_type;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
+	struct i2c_adapter *adap = client->adapter;
+	unsigned short addr = client->addr;
 	int err;
 
 	ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
@@ -332,14 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 		goto err_out_free;
 	}
 
-	ir->c = client_template;
+	ir->c = client;
 	ir->input = input_dev;
-
-	ir->c.adapter = adap;
-	ir->c.addr    = addr;
-	snprintf(ir->c.name, sizeof(ir->c.name), "ir-kbd");
-
-	i2c_set_clientdata(&ir->c, ir);
+	i2c_set_clientdata(client, ir);
 
 	switch(addr) {
 	case 0x64:
@@ -414,24 +390,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
 
-	/* register i2c device
-	 * At device register, IR codes may be changed to be
-	 * board dependent.
-	 */
-	err = i2c_attach_client(&ir->c);
-	if (err)
-		goto err_out_free;
-
-	/* If IR not supported or disabled, unregisters driver */
-	if (ir->get_key == NULL) {
-		err = -ENODEV;
-		goto err_out_detach;
-	}
-
-	/* Phys addr can only be set after attaching (for ir->c.dev) */
 	snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
-		 dev_name(&ir->c.adapter->dev),
-		 dev_name(&ir->c.dev));
+		 dev_name(&adap->dev),
+		 dev_name(&client->dev));
 
 	/* init + register input device */
 	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
@@ -441,7 +402,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 
 	err = input_register_device(ir->input);
 	if (err)
-		goto err_out_detach;
+		goto err_out_free;
 
 	printk(DEVNAME ": %s detected at %s [%s]\n",
 	       ir->input->name, ir->input->phys, adap->name);
@@ -452,135 +413,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 
 	return 0;
 
- err_out_detach:
-	i2c_detach_client(&ir->c);
  err_out_free:
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
 
-static int ir_detach(struct i2c_client *client)
+static int ir_remove(struct i2c_client *client)
 {
 	struct IR_i2c *ir = i2c_get_clientdata(client);
 
 	/* kill outstanding polls */
 	cancel_delayed_work_sync(&ir->work);
 
-	/* unregister devices */
+	/* unregister device */
 	input_unregister_device(ir->input);
-	i2c_detach_client(&ir->c);
 
 	/* free memory */
 	kfree(ir);
 	return 0;
 }
 
-static int ir_probe(struct i2c_adapter *adap)
-{
-
-	/* The external IR receiver is at i2c address 0x34 (0x35 for
-	   reads).  Future Hauppauge cards will have an internal
-	   receiver at 0x30 (0x31 for reads).  In theory, both can be
-	   fitted, and Hauppauge suggest an external overrides an
-	   internal.
-
-	   That's why we probe 0x1a (~0x34) first. CB
-	*/
-
-	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
-	static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
-	static const int probe_em28XX[] = { 0x30, 0x47, -1 };
-	static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
-	static const int probe_cx23885[] = { 0x6b, -1 };
-	const int *probe;
-	struct i2c_msg msg = {
-		.flags = I2C_M_RD,
-		.len = 0,
-		.buf = NULL,
-	};
-	int i, rc;
-
-	switch (adap->id) {
-	case I2C_HW_B_BT848:
-		probe = probe_bttv;
-		break;
-	case I2C_HW_B_CX2341X:
-		probe = probe_bttv;
-		break;
-	case I2C_HW_SAA7134:
-		probe = probe_saa7134;
-		break;
-	case I2C_HW_B_EM28XX:
-		probe = probe_em28XX;
-		break;
-	case I2C_HW_B_CX2388x:
-		probe = probe_cx88;
-		break;
-	case I2C_HW_B_CX23885:
-		probe = probe_cx23885;
-		break;
-	default:
-		return 0;
-	}
-
-	for (i = 0; -1 != probe[i]; i++) {
-		msg.addr = probe[i];
-		rc = i2c_transfer(adap, &msg, 1);
-		dprintk(1,"probe 0x%02x @ %s: %s\n",
-			probe[i], adap->name,
-			(1 == rc) ? "yes" : "no");
-		if (1 == rc) {
-			ir_attach(adap, probe[i], 0, 0);
-			return 0;
-		}
-	}
-
-	/* Special case for MSI TV@nywhere Plus remote */
-	if (adap->id == I2C_HW_SAA7134) {
-		u8 temp;
-
-		/* MSI TV@nywhere Plus controller doesn't seem to
-		   respond to probes unless we read something from
-		   an existing device. Weird... */
-
-		msg.addr = 0x50;
-		rc = i2c_transfer(adap, &msg, 1);
-			dprintk(1, "probe 0x%02x @ %s: %s\n",
-			msg.addr, adap->name,
-			(1 == rc) ? "yes" : "no");
-
-		/* Now do the probe. The controller does not respond
-		   to 0-byte reads, so we use a 1-byte read instead. */
-		msg.addr = 0x30;
-		msg.len = 1;
-		msg.buf = &temp;
-		rc = i2c_transfer(adap, &msg, 1);
-		dprintk(1, "probe 0x%02x @ %s: %s\n",
-			msg.addr, adap->name,
-			(1 == rc) ? "yes" : "no");
-		if (1 == rc)
-			ir_attach(adap, msg.addr, 0, 0);
-	}
-
-	/* Special case for AVerMedia Cardbus remote */
-	if (adap->id == I2C_HW_SAA7134) {
-		unsigned char subaddr, data;
-		struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
-					   .buf = &subaddr, .len = 1},
-					 { .addr = 0x40, .flags = I2C_M_RD,
-					   .buf = &data, .len = 1} };
-		subaddr = 0x0d;
-		rc = i2c_transfer(adap, msg, 2);
-		dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
-			msg[0].addr, subaddr, adap->name,
-			(2 == rc) ? "yes" : "no");
-		if (2 == rc)
-			ir_attach(adap, msg[0].addr, 0, 0);
-	}
+static const struct i2c_device_id ir_kbd_id[] = {
+	/* Generic entry for any IR receiver */
+	{ "ir_video", 0 },
+	/* IR device specific entries could be added here */
+	{ }
+};
 
-	return 0;
-}
+static struct i2c_driver driver = {
+	.driver = {
+		.name   = "ir-kbd-i2c",
+	},
+	.probe          = ir_probe,
+	.remove         = ir_remove,
+	.id_table       = ir_kbd_id,
+};
 
 /* ----------------------------------------------------------------------- */
 
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9e3d32b8004..0ecde9ca05c 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -579,9 +579,11 @@ static struct i2c_client ivtv_i2c_client_template = {
 	.name = "ivtv internal",
 };
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter + instantiate IR receiver */
 int init_ivtv_i2c(struct ivtv *itv)
 {
+	int retval;
+
 	IVTV_DEBUG_I2C("i2c init\n");
 
 	/* Sanity checks for the I2C hardware arrays. They must be the
@@ -619,9 +621,32 @@ int init_ivtv_i2c(struct ivtv *itv)
 	ivtv_setsda(itv, 1);
 
 	if (itv->options.newi2c > 0)
-		return i2c_add_adapter(&itv->i2c_adap);
+		retval = i2c_add_adapter(&itv->i2c_adap);
 	else
-		return i2c_bit_add_bus(&itv->i2c_adap);
+		retval = i2c_bit_add_bus(&itv->i2c_adap);
+
+	/* Instantiate the IR receiver device, if present */
+	if (retval == 0) {
+		struct i2c_board_info info;
+		/* The external IR receiver is at i2c address 0x34 (0x35 for
+		   reads).  Future Hauppauge cards will have an internal
+		   receiver at 0x30 (0x31 for reads).  In theory, both can be
+		   fitted, and Hauppauge suggest an external overrides an
+		   internal.
+
+		   That's why we probe 0x1a (~0x34) first. CB
+		*/
+		const unsigned short addr_list[] = {
+			0x1a, 0x18, 0x64, 0x30,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+	}
+
+	return retval;
 }
 
 void exit_ivtv_i2c(struct ivtv *itv)
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index f3e285aa2fb..a96f75985cb 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -433,6 +433,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev)
 	saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
 	if (i2c_scan)
 		do_i2c_scan(dev->name,&dev->i2c_client);
+
+	/* Instantiate the IR receiver device, if present */
+	saa7134_probe_i2c_ir(dev);
 	return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 6cd693d3b8e..4144ca9cc7e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
 	int gpio;
 
 	/* <dev> is needed to access GPIO. Used by the saa_readl macro. */
-	struct saa7134_dev *dev = ir->c.adapter->algo_data;
+	struct saa7134_dev *dev = ir->c->adapter->algo_data;
 	if (dev == NULL) {
 		dprintk("get_key_msi_tvanywhere_plus: "
-			"gir->c.adapter->algo_data is NULL!\n");
+			"gir->c->adapter->algo_data is NULL!\n");
 		return -EIO;
 	}
 
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
 
 	/* GPIO says there is a button press. Get it. */
 
-	if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char buf[5], cod4, code3, code4;
 
 	/* poll IR chip */
-	if (5 != i2c_master_recv(&ir->c,buf,5))
+	if (5 != i2c_master_recv(ir->c, buf, 5))
 		return -EIO;
 
 	cod4	= buf[4];
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	unsigned char data[12];
 	u32 gpio;
 
-	struct saa7134_dev *dev = ir->c.adapter->algo_data;
+	struct saa7134_dev *dev = ir->c->adapter->algo_data;
 
 	/* rising SAA7134_GPIO_GPRESCAN reads the status */
 	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	if (0x400000 & ~gpio)
 		return 0; /* No button press */
 
-	ir->c.addr = 0x5a >> 1;
+	ir->c->addr = 0x5a >> 1;
 
-	if (12 != i2c_master_recv(&ir->c, data, 12)) {
+	if (12 != i2c_master_recv(ir->c, data, 12)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
 	unsigned int start = 0,parity = 0,code = 0;
 
 	/* poll IR chip */
-	if (4 != i2c_master_recv(&ir->c, b, 4)) {
+	if (4 != i2c_master_recv(ir->c, b, 4)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -682,14 +682,76 @@ void saa7134_input_fini(struct saa7134_dev *dev)
 	dev->remote = NULL;
 }
 
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
+	struct i2c_board_info info;
+	const unsigned short addr_list[] = {
+		0x7a, 0x47, 0x71, 0x2d,
+		I2C_CLIENT_END
+	};
+
+	const unsigned short addr_list_msi[] = {
+		0x30, I2C_CLIENT_END
+	};
+	struct i2c_msg msg_msi = {
+		.addr = 0x50,
+		.flags = I2C_M_RD,
+		.len = 0,
+		.buf = NULL,
+	};
+
+	unsigned char subaddr, data;
+	struct i2c_msg msg_avermedia[] = { {
+		.addr = 0x40,
+		.flags = 0,
+		.len = 1,
+		.buf = &subaddr,
+	}, {
+		.addr = 0x40,
+		.flags = I2C_M_RD,
+		.len = 1,
+		.buf = &data,
+	} };
+
+	struct i2c_client *client;
+	int rc;
+
 	if (disable_ir) {
-		dprintk("Found supported i2c remote, but IR has been disabled\n");
-		ir->get_key=NULL;
+		dprintk("IR has been disabled, not probing for i2c remote\n");
 		return;
 	}
 
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+	if (client)
+		return;
+
+	/* MSI TV@nywhere Plus controller doesn't seem to
+	   respond to probes unless we read something from
+	   an existing device. Weird... */
+	rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+	dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+		msg_msi.addr, dev->i2c_adap.name,
+		(1 == rc) ? "yes" : "no");
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi);
+	if (client)
+		return;
+
+	/* Special case for AVerMedia Cardbus remote */
+	subaddr = 0x0d;
+	rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2);
+	dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n",
+		msg_avermedia[0].addr, subaddr, dev->i2c_adap.name,
+		(2 == rc) ? "yes" : "no");
+	if (2 == rc) {
+		info.addr = msg_avermedia[0].addr;
+		i2c_new_device(&dev->i2c_adap, &info);
+	}
+}
+
+void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+{
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 8229ab21322..116534ec33e 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -799,6 +799,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
 int  saa7134_input_init1(struct saa7134_dev *dev);
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
 void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
 void saa7134_ir_stop(struct saa7134_dev *dev);
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 6a9719c8e90..94a77b15a30 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -7,7 +7,7 @@ struct IR_i2c;
 
 struct IR_i2c {
 	IR_KEYTAB_TYPE         *ir_codes;
-	struct i2c_client      c;
+	struct i2c_client      *c;
 	struct input_dev       *input;
 	struct ir_input_state  ir;
 
-- 
cgit v1.2.3-70-g09d2


From 4d7a2d6721a6380d4ffc26d81d2c8232fd0d2dfc Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:49:32 -0300
Subject: V4L/DVB (11845): ir-kbd-i2c: Use initialization data

For specific boards, pass initialization data to ir-kbd-i2c instead
of modifying the settings after the device is initialized. This is
more efficient and easier to read.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-cards.c |  3 -
 drivers/media/video/cx231xx/cx231xx-i2c.c   | 29 ---------
 drivers/media/video/cx231xx/cx231xx.h       |  1 -
 drivers/media/video/em28xx/em28xx-cards.c   | 31 +++++-----
 drivers/media/video/em28xx/em28xx-i2c.c     | 22 -------
 drivers/media/video/em28xx/em28xx.h         |  1 -
 drivers/media/video/ir-kbd-i2c.c            | 12 +++-
 drivers/media/video/saa7134/saa7134-i2c.c   | 28 ---------
 drivers/media/video/saa7134/saa7134-input.c | 94 ++++++++++++++---------------
 drivers/media/video/saa7134/saa7134.h       |  1 -
 include/media/ir-kbd-i2c.h                  |  7 +++
 11 files changed, 79 insertions(+), 150 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 734f6eaefd9..63d2239fd32 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -287,10 +287,7 @@ void cx231xx_register_i2c_ir(struct cx231xx *dev)
 		return;
 
 	/* REVISIT: instantiate IR device */
-}
 
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
-{
 	/* detect & configure */
 	switch (dev->model) {
 
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index ac4099a49da..33219dc4d64 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap)
 	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
 }
 
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
-	struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
-	struct cx231xx *dev = bus->dev;
-
-	switch (client->addr << 1) {
-	case 0x8e:
-		{
-			struct IR_i2c *ir = i2c_get_clientdata(client);
-			dprintk1(1, "attach_inform: IR detected (%s).\n",
-				 ir->phys);
-			cx231xx_set_ir(dev, ir);
-			break;
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	return 0;
-}
-
 static struct i2c_algorithm cx231xx_algo = {
 	.master_xfer = cx231xx_i2c_xfer,
 	.functionality = functionality,
@@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = {
 	.name = "cx231xx",
 	.id = I2C_HW_B_CX231XX,
 	.algo = &cx231xx_algo,
-	.client_register = attach_inform,
 };
 
 static struct i2c_client cx231xx_client_template = {
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 8c300f60fdf..e38eb2d425f 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -739,7 +739,6 @@ extern struct cx231xx_board cx231xx_boards[];
 extern struct usb_device_id cx231xx_id_table[];
 extern const unsigned int cx231xx_bcount;
 void cx231xx_register_i2c_ir(struct cx231xx *dev);
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
 int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
 
 /* Provided by cx231xx-input.c */
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index edba71115a9..fe2a471e5f6 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1915,6 +1915,7 @@ static int em28xx_hint_board(struct em28xx *dev)
 void em28xx_register_i2c_ir(struct em28xx *dev)
 {
 	struct i2c_board_info info;
+	struct IR_i2c_init_data init_data;
 	const unsigned short addr_list[] = {
 		 0x30, 0x47, I2C_CLIENT_END
 	};
@@ -1923,12 +1924,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
 		return;
 
 	memset(&info, 0, sizeof(struct i2c_board_info));
+	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
 	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
-}
 
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
-{
 	/* detect & configure */
 	switch (dev->model) {
 	case (EM2800_BOARD_UNKNOWN):
@@ -1937,22 +1935,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
 		break;
 	case (EM2800_BOARD_TERRATEC_CINERGY_200):
 	case (EM2820_BOARD_TERRATEC_CINERGY_250):
-		ir->ir_codes = ir_codes_em_terratec;
-		ir->get_key = em28xx_get_key_terratec;
-		snprintf(ir->name, sizeof(ir->name),
-			 "i2c IR (EM28XX Terratec)");
+		init_data.ir_codes = ir_codes_em_terratec;
+		init_data.get_key = em28xx_get_key_terratec;
+		init_data.name = "i2c IR (EM28XX Terratec)";
 		break;
 	case (EM2820_BOARD_PINNACLE_USB_2):
-		ir->ir_codes = ir_codes_pinnacle_grey;
-		ir->get_key = em28xx_get_key_pinnacle_usb_grey;
-		snprintf(ir->name, sizeof(ir->name),
-			 "i2c IR (EM28XX Pinnacle PCTV)");
+		init_data.ir_codes = ir_codes_pinnacle_grey;
+		init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+		init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
 		break;
 	case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
-		ir->ir_codes = ir_codes_hauppauge_new;
-		ir->get_key = em28xx_get_key_em_haup;
-		snprintf(ir->name, sizeof(ir->name),
-			 "i2c IR (EM2840 Hauppauge)");
+		init_data.ir_codes = ir_codes_hauppauge_new;
+		init_data.get_key = em28xx_get_key_em_haup;
+		init_data.name = "i2c IR (EM2840 Hauppauge)";
 		break;
 	case (EM2820_BOARD_MSI_VOX_USB_2):
 		break;
@@ -1963,6 +1958,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
 	case (EM2800_BOARD_GRABBEEX_USB2800):
 		break;
 	}
+
+	if (init_data.name)
+		info.platform_data = &init_data;
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
 }
 
 void em28xx_card_setup(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d90294cbb70..2c86fcf089f 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap)
 	return I2C_FUNC_SMBUS_EMUL;
 }
 
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
-	struct em28xx *dev = client->adapter->algo_data;
-	struct IR_i2c *ir = i2c_get_clientdata(client);
-
-	switch (client->addr << 1) {
-	case 0x60:
-	case 0x8e:
-		dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
-		em28xx_set_ir(dev, ir);
-		break;
-	}
-
-	return 0;
-}
-
 static struct i2c_algorithm em28xx_algo = {
 	.master_xfer   = em28xx_i2c_xfer,
 	.functionality = functionality,
@@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = {
 	.name = "em28xx",
 	.id = I2C_HW_B_EM28XX,
 	.algo = &em28xx_algo,
-	.client_register = attach_inform,
 };
 
 static struct i2c_client em28xx_client_template = {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 9c632541df1..8db797fedb7 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -644,7 +644,6 @@ extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
 extern const unsigned int em28xx_bcount;
 void em28xx_register_i2c_ir(struct em28xx *dev);
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
 void em28xx_release_resources(struct em28xx *dev);
 
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index cb833a63041..3a8880243b1 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -298,7 +298,7 @@ static void ir_work(struct work_struct *work)
 static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	IR_KEYTAB_TYPE *ir_codes = NULL;
-	char *name;
+	const char *name;
 	int ir_type;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
@@ -386,6 +386,16 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		goto err_out_free;
 	}
 
+	/* Let the caller override settings */
+	if (client->dev.platform_data) {
+		const struct IR_i2c_init_data *init_data =
+						client->dev.platform_data;
+
+		ir_codes = init_data->ir_codes;
+		name = init_data->name;
+		ir->get_key = init_data->get_key;
+	}
+
 	/* Sets name */
 	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index a96f75985cb..a8a355e2879 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap)
 	return I2C_FUNC_SMBUS_EMUL;
 }
 
-static int attach_inform(struct i2c_client *client)
-{
-	struct saa7134_dev *dev = client->adapter->algo_data;
-
-	d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
-		client->driver->driver.name, client->addr, client->name);
-
-	/* Am I an i2c remote control? */
-
-	switch (client->addr) {
-		case 0x7a:
-		case 0x47:
-		case 0x71:
-		case 0x2d:
-		case 0x30:
-		{
-			struct IR_i2c *ir = i2c_get_clientdata(client);
-			d1printk("%s i2c IR detected (%s).\n",
-				 client->driver->driver.name, ir->phys);
-			saa7134_set_i2c_ir(dev,ir);
-			break;
-		}
-	}
-
-	return 0;
-}
-
 static struct i2c_algorithm saa7134_algo = {
 	.master_xfer   = saa7134_i2c_xfer,
 	.functionality = functionality,
@@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = {
 	.name          = "saa7134",
 	.id            = I2C_HW_SAA7134,
 	.algo          = &saa7134_algo,
-	.client_register = attach_inform,
 };
 
 static struct i2c_client saa7134_client_template = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 4144ca9cc7e..a20f687f81a 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -685,6 +685,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
 void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
 	struct i2c_board_info info;
+	struct IR_i2c_init_data init_data;
 	const unsigned short addr_list[] = {
 		0x7a, 0x47, 0x71, 0x2d,
 		I2C_CLIENT_END
@@ -722,62 +723,35 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 	}
 
 	memset(&info, 0, sizeof(struct i2c_board_info));
+	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
 	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
-	if (client)
-		return;
-
-	/* MSI TV@nywhere Plus controller doesn't seem to
-	   respond to probes unless we read something from
-	   an existing device. Weird... */
-	rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
-	dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
-		msg_msi.addr, dev->i2c_adap.name,
-		(1 == rc) ? "yes" : "no");
-	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi);
-	if (client)
-		return;
 
-	/* Special case for AVerMedia Cardbus remote */
-	subaddr = 0x0d;
-	rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2);
-	dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n",
-		msg_avermedia[0].addr, subaddr, dev->i2c_adap.name,
-		(2 == rc) ? "yes" : "no");
-	if (2 == rc) {
-		info.addr = msg_avermedia[0].addr;
-		i2c_new_device(&dev->i2c_adap, &info);
-	}
-}
-
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
-{
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
-		snprintf(ir->name, sizeof(ir->name), "Pinnacle PCTV");
+		init_data.name = "Pinnacle PCTV";
 		if (pinnacle_remote == 0) {
-			ir->get_key   = get_key_pinnacle_color;
-			ir->ir_codes = ir_codes_pinnacle_color;
+			init_data.get_key = get_key_pinnacle_color;
+			init_data.ir_codes = ir_codes_pinnacle_color;
 		} else {
-			ir->get_key   = get_key_pinnacle_grey;
-			ir->ir_codes = ir_codes_pinnacle_grey;
+			init_data.get_key = get_key_pinnacle_grey;
+			init_data.ir_codes = ir_codes_pinnacle_grey;
 		}
 		break;
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
-		snprintf(ir->name, sizeof(ir->name), "Purple TV");
-		ir->get_key   = get_key_purpletv;
-		ir->ir_codes  = ir_codes_purpletv;
+		init_data.name = "Purple TV";
+		init_data.get_key = get_key_purpletv;
+		init_data.ir_codes = ir_codes_purpletv;
 		break;
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
-		snprintf(ir->name, sizeof(ir->name), "MSI TV@nywhere Plus");
-		ir->get_key  = get_key_msi_tvanywhere_plus;
-		ir->ir_codes = ir_codes_msi_tvanywhere_plus;
+		init_data.name = "MSI TV@nywhere Plus";
+		init_data.get_key = get_key_msi_tvanywhere_plus;
+		init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-		snprintf(ir->name, sizeof(ir->name), "HVR 1110");
-		ir->get_key   = get_key_hvr1110;
-		ir->ir_codes  = ir_codes_hauppauge_new;
+		init_data.name = "HVR 1110";
+		init_data.get_key = get_key_hvr1110;
+		init_data.ir_codes = ir_codes_hauppauge_new;
 		break;
 	case SAA7134_BOARD_BEHOLD_607FM_MK3:
 	case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -791,15 +765,39 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
 	case SAA7134_BOARD_BEHOLD_H6:
-		snprintf(ir->name, sizeof(ir->name), "BeholdTV");
-		ir->get_key   = get_key_beholdm6xx;
-		ir->ir_codes  = ir_codes_behold;
-		break;
-	default:
-		dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
+		init_data.name = "BeholdTV";
+		init_data.get_key = get_key_beholdm6xx;
+		init_data.ir_codes = ir_codes_behold;
 		break;
 	}
 
+	if (init_data.name)
+		info.platform_data = &init_data;
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+	if (client)
+		return;
+
+	/* MSI TV@nywhere Plus controller doesn't seem to
+	   respond to probes unless we read something from
+	   an existing device. Weird... */
+	rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+	dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+		msg_msi.addr, dev->i2c_adap.name,
+		(1 == rc) ? "yes" : "no");
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi);
+	if (client)
+		return;
+
+	/* Special case for AVerMedia Cardbus remote */
+	subaddr = 0x0d;
+	rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2);
+	dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n",
+		msg_avermedia[0].addr, subaddr, dev->i2c_adap.name,
+		(2 == rc) ? "yes" : "no");
+	if (2 == rc) {
+		info.addr = msg_avermedia[0].addr;
+		i2c_new_device(&dev->i2c_adap, &info);
+	}
 }
 
 static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 116534ec33e..ae7602d343c 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -800,7 +800,6 @@ int  saa7134_input_init1(struct saa7134_dev *dev);
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
 void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
 void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
 void saa7134_ir_stop(struct saa7134_dev *dev);
 
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 94a77b15a30..3ad4ed5402f 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -19,4 +19,11 @@ struct IR_i2c {
 	char                   phys[32];
 	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
 };
+
+/* Can be passed when instantiating an ir_video i2c device */
+struct IR_i2c_init_data {
+	IR_KEYTAB_TYPE         *ir_codes;
+	const char             *name;
+	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
+};
 #endif
-- 
cgit v1.2.3-70-g09d2


From 9a4cc5ac991d3b697db4f9e5015a758621a95009 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:50:11 -0300
Subject: V4L/DVB (11846): ir-kbd-i2c: Don't assume all IR receivers are
 supported

The code in ir_probe makes the dangerous assumption that all IR
receivers are supported by the driver. The new i2c model makes it
possible for bridge drivers to instantiate IR devices before they are
supported, therefore the ir-kbd-i2c drivers must be made more robust
to not spam the logs or even crash on unsupported IR devices. Simply,
the driver will not bind to the unsupported devices.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ir-kbd-i2c.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 3a8880243b1..86f2fefe1ed 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -298,7 +298,7 @@ static void ir_work(struct work_struct *work)
 static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	IR_KEYTAB_TYPE *ir_codes = NULL;
-	const char *name;
+	const char *name = NULL;
 	int ir_type;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
@@ -380,8 +380,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		ir_codes    = ir_codes_avermedia_cardbus;
 		break;
 	default:
-		/* shouldn't happen */
-		printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
+		dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
 		err = -ENODEV;
 		goto err_out_free;
 	}
@@ -396,6 +395,14 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		ir->get_key = init_data->get_key;
 	}
 
+	/* Make sure we are all setup before going on */
+	if (!name || !ir->get_key || !ir_codes) {
+		dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
+			addr);
+		err = -ENODEV;
+		goto err_out_free;
+	}
+
 	/* Sets name */
 	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
-- 
cgit v1.2.3-70-g09d2


From ec218a412bcc126d49dec002d06b24a10d0ab6cd Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:51:46 -0300
Subject: V4L/DVB (11847): saa7134: Simplify handling of IR on MSI TV@nywhere
 Plus

Now that we instantiate I2C IR devices explicitly, we can skip probing
altogether on boards where the I2C IR device address is known. The MSI
TV@nywhere Plus is one of these boards.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-input.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index a20f687f81a..97fe6d14174 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -691,9 +691,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 		I2C_CLIENT_END
 	};
 
-	const unsigned short addr_list_msi[] = {
-		0x30, I2C_CLIENT_END
-	};
 	struct i2c_msg msg_msi = {
 		.addr = 0x50,
 		.flags = I2C_M_RD,
@@ -747,6 +744,15 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 		init_data.name = "MSI TV@nywhere Plus";
 		init_data.get_key = get_key_msi_tvanywhere_plus;
 		init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
+		info.addr = 0x30;
+		/* MSI TV@nywhere Plus controller doesn't seem to
+		   respond to probes unless we read something from
+		   an existing device. Weird...
+		   REVISIT: might no longer be needed */
+		rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+		dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+			msg_msi.addr, dev->i2c_adap.name,
+			(1 == rc) ? "yes" : "no");
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
 		init_data.name = "HVR 1110";
@@ -773,18 +779,14 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 
 	if (init_data.name)
 		info.platform_data = &init_data;
-	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
-	if (client)
+	/* No need to probe if address is known */
+	if (info.addr) {
+		i2c_new_device(&dev->i2c_adap, &info);
 		return;
+	}
 
-	/* MSI TV@nywhere Plus controller doesn't seem to
-	   respond to probes unless we read something from
-	   an existing device. Weird... */
-	rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
-	dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
-		msg_msi.addr, dev->i2c_adap.name,
-		(1 == rc) ? "yes" : "no");
-	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi);
+	/* Address not known, fallback to probing */
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
 	if (client)
 		return;
 
-- 
cgit v1.2.3-70-g09d2


From d9a88e632b2c527165434c404a0a1ca16d2d3793 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:52:44 -0300
Subject: V4L/DVB (11848): saa7134: Simplify handling of IR on AVerMedia
 Cardbus E506R

Now that we instantiate I2C IR devices explicitly, we can skip probing
altogether on boards where the I2C IR device address is known. The
AVerMedia Cardbus E506R is one of these boards.

Tested-by: Oldrich Jedlicka <oldium.pro@seznam.cz>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-input.c | 33 +++++------------------------
 1 file changed, 5 insertions(+), 28 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 97fe6d14174..6e219c2db84 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -698,20 +698,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 		.buf = NULL,
 	};
 
-	unsigned char subaddr, data;
-	struct i2c_msg msg_avermedia[] = { {
-		.addr = 0x40,
-		.flags = 0,
-		.len = 1,
-		.buf = &subaddr,
-	}, {
-		.addr = 0x40,
-		.flags = I2C_M_RD,
-		.len = 1,
-		.buf = &data,
-	} };
-
-	struct i2c_client *client;
 	int rc;
 
 	if (disable_ir) {
@@ -775,6 +761,10 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 		init_data.get_key = get_key_beholdm6xx;
 		init_data.ir_codes = ir_codes_behold;
 		break;
+	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+		info.addr = 0x40;
+		break;
 	}
 
 	if (init_data.name)
@@ -786,20 +776,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 	}
 
 	/* Address not known, fallback to probing */
-	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
-	if (client)
-		return;
-
-	/* Special case for AVerMedia Cardbus remote */
-	subaddr = 0x0d;
-	rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2);
-	dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n",
-		msg_avermedia[0].addr, subaddr, dev->i2c_adap.name,
-		(2 == rc) ? "yes" : "no");
-	if (2 == rc) {
-		info.addr = msg_avermedia[0].addr;
-		i2c_new_device(&dev->i2c_adap, &info);
-	}
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
 }
 
 static int saa7134_rc5_irq(struct saa7134_dev *dev)
-- 
cgit v1.2.3-70-g09d2


From 20b0ead5fd82fcf4824ea0b9c082d9dcfae59b02 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:55:13 -0300
Subject: V4L/DVB (11849): ivtv: Probe more I2C addresses for IR devices

Probe I2C addresses 0x71 and 0x6b for IR receiver devices (for the
PVR150 and Adaptec cards, respectively.)

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ivtv/ivtv-i2c.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 0ecde9ca05c..e52aa322b13 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -637,7 +637,12 @@ int init_ivtv_i2c(struct ivtv *itv)
 		   That's why we probe 0x1a (~0x34) first. CB
 		*/
 		const unsigned short addr_list[] = {
-			0x1a, 0x18, 0x64, 0x30,
+			0x1a,	/* Hauppauge IR external */
+			0x18,	/* Hauppauge IR internal */
+			0x71,	/* Hauppauge IR (PVR150) */
+			0x64,	/* Pixelview IR */
+			0x30,	/* KNC ONE IR */
+			0x6b,	/* Adaptec IR */
 			I2C_CLIENT_END
 		};
 
-- 
cgit v1.2.3-70-g09d2


From 7e1111859204ea76ddb8bb682d8b4097cada4385 Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Wed, 13 May 2009 16:56:20 -0300
Subject: V4L/DVB (11850): pvrusb2: Instantiate ir_video I2C device by default

Now that the ir-kbd-i2c driver has been converted to a new-style i2c
driver, we can instantiate the ir_video I2C device by default. The
pvr2_disable_ir_video is kept to disable the IR receiver, either
because the user doesn't use it, or for debugging purpose.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index b88a61df177..610bd848df2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -42,7 +42,7 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
 module_param_array(ir_mode, int, NULL, 0444);
 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
 
-static int pvr2_disable_ir_video = 1;
+static int pvr2_disable_ir_video;
 module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
 		   int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(disable_autoload_ir_video,
-- 
cgit v1.2.3-70-g09d2


From 849a3aba2d9830dc2a78a66078023e7e5ac26e15 Mon Sep 17 00:00:00 2001
From: Filipe Rosset <rosset.filipe@gmail.com>
Date: Tue, 19 May 2009 10:12:17 -0300
Subject: V4L/DVB (11838): uvcvideo: Add Lenovo Thinkpad SL400 to device list
 comments

Update the 17ef:480b device comment to list Lenovo Thinkpad SL400.

Signed-off-by: Filipe Rosset <rosset.filipe@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 3287454bb36..46bfecb194e 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1908,7 +1908,7 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
-	/* Lenovo Thinkpad SL500 */
+	/* Lenovo Thinkpad SL400/SL500 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
 	  .idVendor		= 0x17ef,
-- 
cgit v1.2.3-70-g09d2


From 7d8535329c4e620c155895a33e1bcc47239858b8 Mon Sep 17 00:00:00 2001
From: Dean Anderson <dean@sensoray.com>
Date: Fri, 15 May 2009 14:32:04 -0300
Subject: V4L/DVB (11851): patch: s2255drv: adding V4L2_MODE_HIGHQUALITY

Adding V4L2_MODE_HIGHQUALITY feature.

Signed-off-by: Dean Anderson <dean@sensoray.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/s2255drv.c | 48 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 90e1dbc1aa8..f08939c1f16 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -109,6 +109,8 @@
 #define SCALE_4CIFS	1	/* 640x480(NTSC) or 704x576(PAL) */
 #define SCALE_2CIFS	2	/* 640x240(NTSC) or 704x288(PAL) */
 #define SCALE_1CIFS	3	/* 320x240(NTSC) or 352x288(PAL) */
+/* SCALE_4CIFSI is the 2 fields interpolated into one */
+#define SCALE_4CIFSI	4	/* 640x480(NTSC) or 704x576(PAL) high quality */
 
 #define COLOR_YUVPL	1	/* YUV planar */
 #define COLOR_YUVPK	2	/* YUV packed */
@@ -238,6 +240,8 @@ struct s2255_dev {
 	struct s2255_mode	mode[MAX_CHANNELS];
 	/* jpeg compression */
 	struct v4l2_jpegcompression jc[MAX_CHANNELS];
+	/* capture parameters (for high quality mode full size) */
+	struct v4l2_captureparm cap_parm[MAX_CHANNELS];
 	const struct s2255_fmt	*cur_fmt[MAX_CHANNELS];
 	int			cur_frame[MAX_CHANNELS];
 	int			last_frame[MAX_CHANNELS];
@@ -1020,9 +1024,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	fh->type = f->type;
 	norm = norm_minw(fh->dev->vdev[fh->channel]);
 	if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
-		if (fh->height > norm_minh(fh->dev->vdev[fh->channel]))
-			fh->mode.scale = SCALE_4CIFS;
-		else
+		if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) {
+			if (fh->dev->cap_parm[fh->channel].capturemode &
+			    V4L2_MODE_HIGHQUALITY) {
+				fh->mode.scale = SCALE_4CIFSI;
+				dprintk(2, "scale 4CIFSI\n");
+			} else {
+				fh->mode.scale = SCALE_4CIFS;
+				dprintk(2, "scale 4CIFS\n");
+			}
+		} else
 			fh->mode.scale = SCALE_2CIFS;
 
 	} else {
@@ -1123,6 +1134,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
 	if (mode->format == FORMAT_NTSC) {
 		switch (mode->scale) {
 		case SCALE_4CIFS:
+		case SCALE_4CIFSI:
 			linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
 			pixelsPerLine = LINE_SZ_4CIFS_NTSC;
 			break;
@@ -1140,6 +1152,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
 	} else if (mode->format == FORMAT_PAL) {
 		switch (mode->scale) {
 		case SCALE_4CIFS:
+		case SCALE_4CIFSI:
 			linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
 			pixelsPerLine = LINE_SZ_4CIFS_PAL;
 			break;
@@ -1495,6 +1508,33 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
 	dprintk(2, "setting jpeg quality %d\n", jc->quality);
 	return 0;
 }
+
+static int vidioc_g_parm(struct file *file, void *priv,
+			 struct v4l2_streamparm *sp)
+{
+	struct s2255_fh *fh = priv;
+	struct s2255_dev *dev = fh->dev;
+	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
+	dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode);
+	return 0;
+}
+
+static int vidioc_s_parm(struct file *file, void *priv,
+			 struct v4l2_streamparm *sp)
+{
+	struct s2255_fh *fh = priv;
+	struct s2255_dev *dev = fh->dev;
+
+	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode;
+	dprintk(2, "setting param capture mode %d\n",
+		sp->parm.capture.capturemode);
+	return 0;
+}
 static int s2255_open(struct file *file)
 {
 	int minor = video_devdata(file)->minor;
@@ -1786,6 +1826,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
 #endif
 	.vidioc_s_jpegcomp = vidioc_s_jpegcomp,
 	.vidioc_g_jpegcomp = vidioc_g_jpegcomp,
+	.vidioc_s_parm = vidioc_s_parm,
+	.vidioc_g_parm = vidioc_g_parm,
 };
 
 static struct video_device template = {
-- 
cgit v1.2.3-70-g09d2


From 4a567394dce57e8a2329f0a1123b951b0f070d39 Mon Sep 17 00:00:00 2001
From: "figo.zhang" <figo.zhang@kolorific.com>
Date: Sun, 17 May 2009 23:13:13 -0300
Subject: V4L/DVB (11852): saa7134-video.c: poll method lose race condition

saa7134-video.c: poll method lose race condition

Signed-off-by: Figo Zhang <figo.zhang@kolorific.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-video.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 493cad94146..ceae3c88f93 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1423,11 +1423,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct saa7134_fh *fh = file->private_data;
 	struct videobuf_buffer *buf = NULL;
+	unsigned int rc = 0;
 
 	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
 		return videobuf_poll_stream(file, &fh->vbi, wait);
 
 	if (res_check(fh,RESOURCE_VIDEO)) {
+		mutex_lock(&fh->cap.vb_lock);
 		if (!list_empty(&fh->cap.stream))
 			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
 	} else {
@@ -1446,13 +1448,14 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 	}
 
 	if (!buf)
-		return POLLERR;
+		goto err;
 
 	poll_wait(file, &buf->done, wait);
 	if (buf->state == VIDEOBUF_DONE ||
 	    buf->state == VIDEOBUF_ERROR)
-		return POLLIN|POLLRDNORM;
-	return 0;
+		rc = POLLIN|POLLRDNORM;
+	mutex_unlock(&fh->cap.vb_lock);
+	return rc;
 
 err:
 	mutex_unlock(&fh->cap.vb_lock);
-- 
cgit v1.2.3-70-g09d2


From 6ecdf92d211fb37a905fce5d0a8668c831764abc Mon Sep 17 00:00:00 2001
From: "figo.zhang" <figo.zhang@kolorific.com>
Date: Sun, 17 May 2009 23:31:55 -0300
Subject: V4L/DVB (11853): minor have assigned value twice

The variable minor have assigned value twice, the first time is in the
initial "video_device" data struct in those drivers, pls see
saa7134-video.c,line 2503.

 ---

Signed-off-by: Figo.zhang <figo.zhang@kolorific.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/bt8xx/bttv-driver.c    | 1 -
 drivers/media/video/cx23885/cx23885-417.c  | 1 -
 drivers/media/video/cx88/cx88-core.c       | 1 -
 drivers/media/video/saa7134/saa7134-core.c | 1 -
 4 files changed, 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 23b7499b318..539ae45bebd 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4166,7 +4166,6 @@ static struct video_device *vdev_init(struct bttv *btv,
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor   = -1;
 	vfd->v4l2_dev = &btv->c.v4l2_dev;
 	vfd->release = video_device_release;
 	vfd->debug   = bttv_debug;
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 6f5df90af93..2943bfd32a9 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1742,7 +1742,6 @@ static struct video_device *cx23885_video_dev_alloc(
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor   = -1;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, cx23885_boards[tsport->dev->board].name);
 	vfd->parent  = &pci->dev;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 0e149b22bd1..b4049de071a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1010,7 +1010,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor   = -1;
 	vfd->v4l2_dev = &core->v4l2_dev;
 	vfd->parent = &pci->dev;
 	vfd->release = video_device_release;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 2def6fec814..37b14526a09 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -775,7 +775,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor   = -1;
 	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	vfd->debug   = video_debug;
-- 
cgit v1.2.3-70-g09d2


From 8816bef53cfaf21fcce47fe5fd403d2e39ba6d2d Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@kernellabs.com>
Date: Fri, 15 May 2009 21:04:18 -0300
Subject: V4L/DVB (11855): cx23885: Ensure we specify I/F's for all bandwidths

cx23885: Ensure we specify I/F's for all bandwidths

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index c3293d8eb33..577e83829ad 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -124,7 +124,9 @@ static struct tda10048_config hauppauge_hvr1200_config = {
 	.output_mode      = TDA10048_SERIAL_OUTPUT,
 	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
 	.inversion        = TDA10048_INVERSION_ON,
-	.if_freq_khz      = TDA10048_IF_4300,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3800,
+	.dtv8_if_freq_khz = TDA10048_IF_4300,
 	.clk_freq_khz     = TDA10048_CLK_16000,
 };
 
-- 
cgit v1.2.3-70-g09d2


From 08b83583dcc09260784b398783ac47e13d351fdc Mon Sep 17 00:00:00 2001
From: Steven Toth <stoth@kernellabs.com>
Date: Fri, 15 May 2009 21:04:56 -0300
Subject: V4L/DVB (11856): pvrusb2: Ensure we specify I/F's for all bandwidths

pvrusb2: Ensure we specify I/F's for all bandwidths

Signed-off-by: Steven Toth <stoth@kernellabs.com>
Acked-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-devattr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 341af4355c0..336a20eded0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -285,7 +285,9 @@ static struct tda10048_config hauppauge_tda10048_config = {
 	.output_mode    = TDA10048_PARALLEL_OUTPUT,
 	.fwbulkwritelen = TDA10048_BULKWRITE_50,
 	.inversion      = TDA10048_INVERSION_ON,
-	.if_freq_khz    = TDA10048_IF_4300,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3800,
+	.dtv8_if_freq_khz = TDA10048_IF_4300,
 	.clk_freq_khz   = TDA10048_CLK_16000,
 	.disable_gate_access = 1,
 };
-- 
cgit v1.2.3-70-g09d2


From c27586e4d647c5c07c81e766d34ceef6ba5a316d Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Sat, 16 May 2009 11:00:23 -0300
Subject: V4L/DVB (11858): cx23885: fix tda10048 IF frequencies for the
 Hauppauge WinTV-HVR1210

Steve missed the HVR1210 config struct for the TDA10048 in his IF freq patch.

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 577e83829ad..45784a38430 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -135,7 +135,9 @@ static struct tda10048_config hauppauge_hvr1210_config = {
 	.output_mode      = TDA10048_SERIAL_OUTPUT,
 	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
 	.inversion        = TDA10048_INVERSION_ON,
-	.if_freq_khz      = TDA10048_IF_4000,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3500,
+	.dtv8_if_freq_khz = TDA10048_IF_4000,
 	.clk_freq_khz     = TDA10048_CLK_16000,
 };
 
-- 
cgit v1.2.3-70-g09d2


From b9dcdb6fb870ce83578465b3ffd047185bead67f Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Wed, 20 May 2009 16:06:10 -0300
Subject: V4L/DVB (11860): saa7134: fix quirk in saa7134_i2c_xfer for the
 saa7131 bridge

The i2c quirk in the saa7134_i2c_xfer function does a bogus write
to i2c address 0xfd, to work around a bug in the silicon that
affects read transactions.

Unfortunately, this hack is not working properly, since the bogus
write is to 0xfd, an invalid i2c address.  Fix this quirk by using
an actual valid i2c address, 0xfe, which is still unlikely to be
used as an i2c address for any actual i2c client.

This is required in order to properly communicate with a TDA10048
DVB-T demod located at i2c address 0x10 on the primary i2c bus.

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index a8a355e2879..8096dace5f6 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -259,7 +259,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
 				/* workaround for a saa7134 i2c bug
 				 * needed to talk to the mt352 demux
 				 * thanks to pinnacle for the hint */
-				int quirk = 0xfd;
+				int quirk = 0xfe;
 				d1printk(" [%02x quirk]",quirk);
 				i2c_send_byte(dev,START,quirk);
 				i2c_recv_byte(dev);
-- 
cgit v1.2.3-70-g09d2


From 1bc7f51c57c52cfac1a455d8f8ef99703e719e55 Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Mon, 19 Jan 2009 01:10:49 -0300
Subject: V4L/DVB (11861): saa7134: enable digital tv support for Hauppauge
 WinTV-HVR1110r3

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.saa7134  |  2 +-
 drivers/media/video/saa7134/Kconfig         |  1 +
 drivers/media/video/saa7134/saa7134-cards.c |  4 +++-
 drivers/media/video/saa7134/saa7134-dvb.c   | 26 ++++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 112ff4f4fd9..e56934e501b 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -154,7 +154,7 @@
 153 -> Kworld Plus TV Analog Lite PCI           [17de:7128]
 154 -> Avermedia AVerTV GO 007 FM Plus          [1461:f31d]
 155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
-156 -> Hauppauge WinTV-HVR1110r3                [0070:6707,0070:6709,0070:670a]
+156 -> Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid   [0070:6707,0070:6709,0070:670a]
 157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
 158 -> AVerMedia Cardbus TV/Radio (E501R)       [1461:b7e9]
 159 -> Beholder BeholdTV 505 RDS                [0000:505B]
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 0ba68987bfc..5bcce092e80 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -44,6 +44,7 @@ config VIDEO_SAA7134_DVB
 	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	---help---
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0eced41443e..73482eb8d38 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -3364,13 +3364,15 @@ struct saa7134_board saa7134_boards[] = {
 		},
 	},
 	[SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
-		.name           = "Hauppauge WinTV-HVR1110r3",
+		.name           = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tuner_config   = 3,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.ts_type	= SAA7134_MPEG_TS_SERIAL,
 		.gpiomask       = 0x0800100, /* GPIO 21 is an INPUT */
 		.inputs         = {{
 			.name = name_tv,
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 4eff1ca8593..31930f26ffc 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -48,6 +48,7 @@
 #include "isl6405.h"
 #include "lnbp21.h"
 #include "tuner-simple.h"
+#include "tda10048.h"
 #include "tda18271.h"
 #include "lgdt3305.h"
 #include "tda8290.h"
@@ -978,6 +979,18 @@ static struct lgdt3305_config hcw_lgdt3305_config = {
 	.vsb_if_khz         = 3250,
 };
 
+static struct tda10048_config hcw_tda10048_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_SERIAL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3500,
+	.dtv8_if_freq_khz = TDA10048_IF_4000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+	.disable_gate_access = 1,
+};
+
 static struct tda18271_std_map hauppauge_tda18271_std_map = {
 	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
 		      .if_lvl = 1, .rfagc_top = 0x58, },
@@ -1106,6 +1119,19 @@ static int dvb_init(struct saa7134_dev *dev)
 					 &tda827x_cfg_2) < 0)
 			goto dettach_frontend;
 		break;
+	case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
+					       &hcw_tda10048_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, 0x4b,
+				   &tda829x_no_probe);
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_adap,
+				   &hcw_tda18271_config);
+		}
+		break;
 	case SAA7134_BOARD_PHILIPS_TIGER:
 		if (configure_tda827x_fe(dev, &philips_tiger_config,
 					 &tda827x_cfg_0) < 0)
-- 
cgit v1.2.3-70-g09d2


From 5ab740522fbee3a2ef83554b9a9c92692c8c0f74 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 10 May 2009 22:14:29 -0300
Subject: V4L/DVB (11863): cx18: Initial attempt to get sliced VBI working for
 625 line systems

Initial changes to get sliced VBI for 625 line system working.  This is patch
is untested.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-core.c | 59 ++++++++++++++++++++++++++-------
 drivers/media/video/cx18/cx18-av-vbi.c  |  4 +--
 drivers/media/video/cx18/cx18-streams.c |  8 ++++-
 3 files changed, 56 insertions(+), 15 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 2b07b156340..d98010e0da9 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -288,17 +288,52 @@ void cx18_av_std_setup(struct cx18 *cx)
 	else
 		cx18_av_write(cx, 0x49f, 0x14);
 
+	/*
+	 * Note: At the end of a field, there are 3 sets of half line duration
+	 * (double horizontal rate) pulses:
+	 *
+	 * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
+	 * 5 (625) or 6 (525) vertical sync pulses of half line duration
+	 * 5 (625) or 6 (525) half-lines of equalization pulses
+	 */
 	if (std & V4L2_STD_625_50) {
-		/* FIXME - revisit these for Sliced VBI */
+		/*
+		 * The following relationships of half line counts should hold:
+		 * 625 = vblank656 + vactive + postvactive
+		 * 10 = vblank656 - vblank = vsync pulses + equalization pulses
+		 *
+		 * vblank656: half lines after line 625/mid-313 of blanked video
+		 * vblank:    half lines, after line 5/317, of blanked video
+		 * vactive:   half lines of active video
+		 * postvactive: 5 half lines after the end of active video
+		 *
+		 * As far as I can tell:
+		 * vblank656 starts counting from the falling edge of the first
+		 * 	vsync pulse (start of line 1 or mid-313)
+		 * vblank starts counting from the after the 5 vsync pulses and
+		 * 	5 or 4 equalization pulses (start of line 6 or 318)
+		 *
+		 * For 625 line systems the driver will extract VBI information
+		 * from lines 6-23 and lines 318-335 (but the slicer can only
+		 * handle 17 lines, not the 18 in the vblank region).
+		 */
+		vblank656 = 46; /* lines  1 -  23  &  313 - 335 */
+		vblank = 36;    /* lines  6 -  23  &  318 - 335 */
+		vactive = 574;  /* lines 24 - 310  &  336 - 622 */
+
+		/*
+		 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
+		 * is 864 pixels = 720 active + 144 blanking.  ITU-R BT.601
+		 * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
+		 * the end of active video to start a horizontal line, so that
+		 * leaves 132 pixels of hblank to ignore.
+		 */
 		hblank = 132;
 		hactive = 720;
-		burst = 93;
-		vblank = 36;
-		vactive = 580;
-		vblank656 = 40;
-		src_decimation = 0x21f;
 
+		burst = 93;
 		luma_lpf = 2;
+		src_decimation = 0x21f;
 		if (std & V4L2_STD_PAL) {
 			uv_lpf = 1;
 			comb = 0x20;
@@ -315,13 +350,13 @@ void cx18_av_std_setup(struct cx18 *cx)
 	} else {
 		/*
 		 * The following relationships of half line counts should hold:
-		 * 525 = vsync + vactive + vblank656
-		 * 12 = vblank656 - vblank
+		 * 525 = prevsync + vblank656 + vactive
+		 * 12 = vblank656 - vblank = vsync pulses + equalization pulses
 		 *
-		 * vsync:     always 6 half-lines of vsync pulses
-		 * vactive:   half lines of active video
+		 * prevsync:  6 half-lines before the vsync pulses
 		 * vblank656: half lines, after line 3/mid-266, of blanked video
 		 * vblank:    half lines, after line 9/272, of blanked video
+		 * vactive:   half lines of active video
 		 *
 		 * As far as I can tell:
 		 * vblank656 starts counting from the falling edge of the first
@@ -954,9 +989,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 		 * cx18_av_std_setup(), above standard values:
 		 *
 		 * 480 + 1 for 60 Hz systems
-		 * 576 + 4 for 50 Hz systems
+		 * 576 - 2 for 50 Hz systems
 		 */
-		Vlines = pix->height + (is_50Hz ? 4 : 1);
+		Vlines = pix->height + (is_50Hz ? -2 : 1);
 
 		/*
 		 * Invalid height and width scaling requests are:
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 23b31670bf1..640121448eb 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -255,8 +255,8 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
 	}
 
 	cx18_av_write(cx, 0x43c, 0x16);
-	/* FIXME - should match vblank set in cx18_av_std_setup() */
-	cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
+	/* Should match vblank set in cx18_av_std_setup() */
+	cx18_av_write(cx, 0x474, is_pal ? 36 : 26);
 	return 0;
 }
 
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 41a1b2618aa..a0800393316 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -371,9 +371,15 @@ static void cx18_vbi_setup(struct cx18_stream *s)
 		 * Tell the encoder to capture 21-4+1=18 lines per field,
 		 * since we want lines 10 through 21.
 		 *
+		 * For 625/50 systems, according to the VIP 2 & BT.656 std:
+		 * The EAV RP code's Field bit toggles on line 1, a few lines
+		 * after the Vertcal Blank bit has already toggled.
+		 * Tell the encoder to capture 23-1+1=23 lines per field,
+		 * since we want lines 6 through 23.
+		 *
 		 * FIXME - revisit for 625/50 systems
 		 */
-		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
+		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 1 + 1) * 2;
 	}
 
 	data[0] = s->handle;
-- 
cgit v1.2.3-70-g09d2


From 929a3ad1525895c394cbe97a6b74792da9a865a6 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sat, 16 May 2009 21:06:57 -0300
Subject: V4L/DVB (11864): cx18: Complete support for Sliced and Raw VBI for
 625 line systems

Finish changes for sliced and raw VBI for 625 line systems.  Tested with VPS
and WSS being emitted by a PVR-350 in field 1 lines 16 and 23.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-core.c | 27 +++++++++++++++++++--------
 drivers/media/video/cx18/cx18-av-vbi.c  |  2 +-
 drivers/media/video/cx18/cx18-streams.c |  9 ++++-----
 3 files changed, 24 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index d98010e0da9..33ec269a0f5 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -299,13 +299,13 @@ void cx18_av_std_setup(struct cx18 *cx)
 	if (std & V4L2_STD_625_50) {
 		/*
 		 * The following relationships of half line counts should hold:
-		 * 625 = vblank656 + vactive + postvactive
+		 * 625 = vblank656 + vactive
 		 * 10 = vblank656 - vblank = vsync pulses + equalization pulses
 		 *
 		 * vblank656: half lines after line 625/mid-313 of blanked video
 		 * vblank:    half lines, after line 5/317, of blanked video
-		 * vactive:   half lines of active video
-		 * postvactive: 5 half lines after the end of active video
+		 * vactive:   half lines of active video +
+		 * 		5 half lines after the end of active video
 		 *
 		 * As far as I can tell:
 		 * vblank656 starts counting from the falling edge of the first
@@ -316,10 +316,21 @@ void cx18_av_std_setup(struct cx18 *cx)
 		 * For 625 line systems the driver will extract VBI information
 		 * from lines 6-23 and lines 318-335 (but the slicer can only
 		 * handle 17 lines, not the 18 in the vblank region).
+		 * In addition, we need vblank656 and vblank to be one whole
+		 * line longer, to cover line 24 and 336, so the SAV/EAV RP
+		 * codes get generated such that the encoder can actually
+		 * extract line 23 & 335 (WSS).  We'll lose 1 line in each field
+		 * at the top of the screen.
+		 *
+		 * It appears the 5 half lines that happen after active
+		 * video must be included in vactive (579 instead of 574),
+		 * otherwise the colors get badly displayed in various regions
+		 * of the screen.  I guess the chroma comb filter gets confused
+		 * without them (at least when a PVR-350 is the PAL source).
 		 */
-		vblank656 = 46; /* lines  1 -  23  &  313 - 335 */
-		vblank = 36;    /* lines  6 -  23  &  318 - 335 */
-		vactive = 574;  /* lines 24 - 310  &  336 - 622 */
+		vblank656 = 48; /* lines  1 -  24  &  313 - 336 */
+		vblank = 38;    /* lines  6 -  24  &  318 - 336 */
+		vactive = 579;  /* lines 24 - 313  &  337 - 626 */
 
 		/*
 		 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
@@ -989,9 +1000,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 		 * cx18_av_std_setup(), above standard values:
 		 *
 		 * 480 + 1 for 60 Hz systems
-		 * 576 - 2 for 50 Hz systems
+		 * 576 + 3 for 50 Hz systems
 		 */
-		Vlines = pix->height + (is_50Hz ? -2 : 1);
+		Vlines = pix->height + (is_50Hz ? 3 : 1);
 
 		/*
 		 * Invalid height and width scaling requests are:
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 640121448eb..a51732bcca4 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -256,7 +256,7 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
 
 	cx18_av_write(cx, 0x43c, 0x16);
 	/* Should match vblank set in cx18_av_std_setup() */
-	cx18_av_write(cx, 0x474, is_pal ? 36 : 26);
+	cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
 	return 0;
 }
 
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index a0800393316..54d248e16d8 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -374,12 +374,11 @@ static void cx18_vbi_setup(struct cx18_stream *s)
 		 * For 625/50 systems, according to the VIP 2 & BT.656 std:
 		 * The EAV RP code's Field bit toggles on line 1, a few lines
 		 * after the Vertcal Blank bit has already toggled.
-		 * Tell the encoder to capture 23-1+1=23 lines per field,
-		 * since we want lines 6 through 23.
-		 *
-		 * FIXME - revisit for 625/50 systems
+		 * (We've actually set the digitizer so that the Field bit
+		 * toggles on line 2.) Tell the encoder to capture 23-2+1=22
+		 * lines per field, since we want lines 6 through 23.
 		 */
-		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 1 + 1) * 2;
+		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
 	}
 
 	data[0] = s->handle;
-- 
cgit v1.2.3-70-g09d2


From 86bc85b38602411a9582b829fdd0ee02cf582985 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sat, 16 May 2009 22:43:43 -0300
Subject: V4L/DVB (11865): cx18: Tweak color burst gate delay and initial color
 sub-carrier freq

Fix the burst gate delays to use a crystal value of 28636360 as assumed by
the rest of the driver.  Also have the initial color sub-carrier freq paramter
use the src decimation ratio per the documentation, instead of the actual
crystal/pixel clock ratio.  The tracking circuit will find the correct color
subcarrier in any case, as long as we're close.  Also fix up some debug print
statements.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-core.c | 69 +++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 21 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 33ec269a0f5..0b3d840cc2e 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -277,8 +277,15 @@ void cx18_av_std_setup(struct cx18 *cx)
 	struct cx18_av_state *state = &cx->av_state;
 	struct v4l2_subdev *sd = &state->sd;
 	v4l2_std_id std = state->std;
+
+	/*
+	 * Video ADC crystal clock to pixel clock SRC decimation ratio
+	 * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
+	 */
+	const int src_decimation = 0x21f;
+
 	int hblank, hactive, burst, vblank, vactive, sc;
-	int vblank656, src_decimation;
+	int vblank656;
 	int luma_lpf, uv_lpf, comb;
 	u32 pll_int, pll_frac, pll_post;
 
@@ -342,21 +349,31 @@ void cx18_av_std_setup(struct cx18 *cx)
 		hblank = 132;
 		hactive = 720;
 
+		/*
+		 * Burst gate delay (for 625 line systems)
+		 * Hsync leading edge to color burst rise = 5.6 us
+		 * Color burst width = 2.25 us
+		 * Gate width = 4 pixel clocks
+		 * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
+		 */
 		burst = 93;
 		luma_lpf = 2;
-		src_decimation = 0x21f;
 		if (std & V4L2_STD_PAL) {
 			uv_lpf = 1;
 			comb = 0x20;
-			sc = 688739;
+			/* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
+			sc = 688700;
 		} else if (std == V4L2_STD_PAL_Nc) {
 			uv_lpf = 1;
 			comb = 0x20;
-			sc = 556453;
+			/* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
+			sc = 556422;
 		} else { /* SECAM */
 			uv_lpf = 0;
 			comb = 0;
-			sc = 672351;
+			/* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
+			/* sc = 4328130 * src_decimation/28636360 * 2^13 */
+			sc = 672314;
 		}
 	} else {
 		/*
@@ -394,20 +411,30 @@ void cx18_av_std_setup(struct cx18 *cx)
 		luma_lpf = 1;
 		uv_lpf = 1;
 
-		src_decimation = 0x21f;
+		/*
+		 * Burst gate delay (for 525 line systems)
+		 * Hsync leading edge to color burst rise = 5.3 us
+		 * Color burst width = 2.5 us
+		 * Gate width = 4 pixel clocks
+		 * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
+		 */
 		if (std == V4L2_STD_PAL_60) {
-			burst = 0x5b;
+			burst = 90;
 			luma_lpf = 2;
 			comb = 0x20;
-			sc = 688739;
+			/* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
+			sc = 688700;
 		} else if (std == V4L2_STD_PAL_M) {
-			burst = 0x61;
+			/* The 97 needs to be verified against PAL-M timings */
+			burst = 97;
 			comb = 0x20;
-			sc = 555452;
+			/* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
+			sc = 555421;
 		} else {
-			burst = 0x5b;
+			burst = 90;
 			comb = 0x66;
-			sc = 556063;
+			/* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
+			sc = 556032;
 		}
 	}
 
@@ -419,23 +446,23 @@ void cx18_av_std_setup(struct cx18 *cx)
 			    pll_int, pll_frac, pll_post);
 
 	if (pll_post) {
-		int fin, fsc, pll;
+		int fsc, pll;
 
 		pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
 		pll /= pll_post;
-		CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n",
+		CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
 				    pll / 1000000, pll % 1000000);
-		CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n",
+		CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
 				    pll / 8000000, (pll / 8) % 1000000);
 
-		fin = ((u64)src_decimation * pll) >> 12;
-		CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n",
-				    fin / 1000000, fin % 1000000);
+		CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
+				    "= %d.%03d\n", src_decimation / 256,
+				    ((src_decimation % 256) * 1000) / 256);
 
-		fsc = (((u64)sc) * pll) >> 24L;
+		fsc = ((((u64)sc) * 28636360)/src_decimation) >> 13L;
 		CX18_DEBUG_INFO_DEV(sd,
-				    "Chroma sub-carrier freq = %d.%06d MHz\n",
-				    fsc / 1000000, fsc % 1000000);
+				    "Chroma sub-carrier initial freq = %d.%06d "
+				    "MHz\n", fsc / 1000000, fsc % 1000000);
 
 		CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
 				    "vactive %i, vblank656 %i, src_dec %i, "
-- 
cgit v1.2.3-70-g09d2


From 1af63b3d1dfd38175c145f1435bab865ebdd8951 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Wed, 13 May 2009 14:21:46 -0300
Subject: V4L/DVB (11867): gspca - spca508: Cleanup source and update
 copyright.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca508.c | 1888 ++++++++++++++++-------------------
 1 file changed, 872 insertions(+), 1016 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index adacf843766..5896bfe2ffd 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1,7 +1,7 @@
 /*
  * SPCA508 chip based cameras subdriver
  *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
  *
  * 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
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	unsigned char brightness;
+	u8 brightness;
 
-	char subtype;
+	u8 subtype;
 #define CreativeVista 0
 #define HamaUSBSightcam 1
 #define HamaUSBSightcam2 2
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = {
 };
 
 /* Frame packet header offsets for the spca508 */
-#define SPCA508_OFFSET_TYPE 1
-#define SPCA508_OFFSET_COMPRESS 2
-#define SPCA508_OFFSET_FRAMSEQ 8
-#define SPCA508_OFFSET_WIN1LUM 11
 #define SPCA508_OFFSET_DATA 37
 
-#define SPCA508_SNAPBIT 0x20
-#define SPCA508_SNAPCTRL 0x40
-/*************** I2c ****************/
-#define SPCA508_INDEX_I2C_BASE 0x8800
-
 /*
  * Initialization data: this is the first set-up data written to the
  * device (before the open data).
  */
 static const u16 spca508_init_data[][2] =
 {
-	/*  line   URB      value, index */
-	/* 44274  1804 */ {0x0000, 0x870b},
-
-	/* 44299  1805 */ {0x0020, 0x8112},
-	/* Video drop enable, ISO streaming disable */
-	/* 44324  1806 */ {0x0003, 0x8111},
-	/* Reset compression & memory */
-	/* 44349  1807 */ {0x0000, 0x8110},
-	/* Disable all outputs */
-	/* 44372  1808 */ /* READ {0x0000, 0x8114} -> 0000: 00  */
-	/* 44398  1809 */ {0x0000, 0x8114},
-	/* SW GPIO data */
-	/* 44423  1810 */ {0x0008, 0x8110},
-	/* Enable charge pump output */
-	/* 44527  1811 */ {0x0002, 0x8116},
-	/* 200 kHz pump clock */
-	/* 44555  1812 */
-		/* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
-	/* 44590  1813 */ {0x0003, 0x8111},
-	/* Reset compression & memory */
-	/* 44615  1814 */ {0x0000, 0x8111},
-	/* Normal mode (not reset) */
-	/* 44640  1815 */ {0x0098, 0x8110},
-	/* Enable charge pump output, sync.serial,external 2x clock */
-	/* 44665  1816 */ {0x000d, 0x8114},
-	/* SW GPIO data */
-	/* 44690  1817 */ {0x0002, 0x8116},
-	/* 200 kHz pump clock */
-	/* 44715  1818 */ {0x0020, 0x8112},
-	/* Video drop enable, ISO streaming disable */
+	{0x0000, 0x870b},
+
+	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
+	{0x0003, 0x8111},	/* Reset compression & memory */
+	{0x0000, 0x8110},	/* Disable all outputs */
+	/* READ {0x0000, 0x8114} -> 0000: 00  */
+	{0x0000, 0x8114},	/* SW GPIO data */
+	{0x0008, 0x8110},	/* Enable charge pump output */
+	{0x0002, 0x8116},	/* 200 kHz pump clock */
+	/* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
+	{0x0003, 0x8111},	/* Reset compression & memory */
+	{0x0000, 0x8111},	/* Normal mode (not reset) */
+	{0x0098, 0x8110},
+		/* Enable charge pump output, sync.serial,external 2x clock */
+	{0x000d, 0x8114},	/* SW GPIO data */
+	{0x0002, 0x8116},	/* 200 kHz pump clock */
+	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
 /* --------------------------------------- */
-	/* 44740  1819 */ {0x000f, 0x8402},
-	/* memory bank */
-	/* 44765  1820 */ {0x0000, 0x8403},
-	/* ... address */
+	{0x000f, 0x8402},	/* memory bank */
+	{0x0000, 0x8403},	/* ... address */
 /* --------------------------------------- */
 /* 0x88__ is Synchronous Serial Interface. */
 /* TBD: This table could be expressed more compactly */
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] =
 /* TBD: Should see if the values in spca50x_i2c_data */
 /* would work with the VQ110 instead of the values */
 /* below. */
-	/* 44790  1821 */ {0x00c0, 0x8804},
-	/* SSI slave addr */
-	/* 44815  1822 */ {0x0008, 0x8802},
-	/* 375 Khz SSI clock */
-	/* 44838  1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 44862  1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 44888  1825 */ {0x0008, 0x8802},
-	/* 375 Khz SSI clock */
-	/* 44913  1826 */ {0x0012, 0x8801},
-	/* SSI reg addr */
-	/* 44938  1827 */ {0x0080, 0x8800},
-	/* SSI data to write */
-	/* 44961  1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 44985  1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45009  1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45035  1831 */ {0x0008, 0x8802},
-	/* 375 Khz SSI clock */
-	/* 45060  1832 */ {0x0012, 0x8801},
-	/* SSI reg addr */
-	/* 45085  1833 */ {0x0000, 0x8800},
-	/* SSI data to write */
-	/* 45108  1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45132  1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45156  1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45182  1837 */ {0x0008, 0x8802},
-	/* 375 Khz SSI clock */
-	/* 45207  1838 */ {0x0011, 0x8801},
-	/* SSI reg addr */
-	/* 45232  1839 */ {0x0040, 0x8800},
-	/* SSI data to write */
-	/* 45255  1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45279  1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45303  1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45329  1843 */ {0x0008, 0x8802},
-	/* 45354  1844 */ {0x0013, 0x8801},
-	/* 45379  1845 */ {0x0000, 0x8800},
-	/* 45402  1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45426  1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45450  1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45476  1849 */ {0x0008, 0x8802},
-	/* 45501  1850 */ {0x0014, 0x8801},
-	/* 45526  1851 */ {0x0000, 0x8800},
-	/* 45549  1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45573  1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45597  1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45623  1855 */ {0x0008, 0x8802},
-	/* 45648  1856 */ {0x0015, 0x8801},
-	/* 45673  1857 */ {0x0001, 0x8800},
-	/* 45696  1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45720  1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45744  1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45770  1861 */ {0x0008, 0x8802},
-	/* 45795  1862 */ {0x0016, 0x8801},
-	/* 45820  1863 */ {0x0003, 0x8800},
-	/* 45843  1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45867  1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 45891  1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 45917  1867 */ {0x0008, 0x8802},
-	/* 45942  1868 */ {0x0017, 0x8801},
-	/* 45967  1869 */ {0x0036, 0x8800},
-	/* 45990  1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46014  1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46038  1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46064  1873 */ {0x0008, 0x8802},
-	/* 46089  1874 */ {0x0018, 0x8801},
-	/* 46114  1875 */ {0x00ec, 0x8800},
-	/* 46137  1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46161  1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46185  1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46211  1879 */ {0x0008, 0x8802},
-	/* 46236  1880 */ {0x001a, 0x8801},
-	/* 46261  1881 */ {0x0094, 0x8800},
-	/* 46284  1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46308  1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46332  1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46358  1885 */ {0x0008, 0x8802},
-	/* 46383  1886 */ {0x001b, 0x8801},
-	/* 46408  1887 */ {0x0000, 0x8800},
-	/* 46431  1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46455  1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46479  1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46505  1891 */ {0x0008, 0x8802},
-	/* 46530  1892 */ {0x0027, 0x8801},
-	/* 46555  1893 */ {0x00a2, 0x8800},
-	/* 46578  1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46602  1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46626  1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46652  1897 */ {0x0008, 0x8802},
-	/* 46677  1898 */ {0x0028, 0x8801},
-	/* 46702  1899 */ {0x0040, 0x8800},
-	/* 46725  1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46749  1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46773  1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46799  1903 */ {0x0008, 0x8802},
-	/* 46824  1904 */ {0x002a, 0x8801},
-	/* 46849  1905 */ {0x0084, 0x8800},
-	/* 46872  1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 46896  1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
-	/* 46920  1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 46946  1909 */ {0x0008, 0x8802},
-	/* 46971  1910 */ {0x002b, 0x8801},
-	/* 46996  1911 */ {0x00a8, 0x8800},
-	/* 47019  1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47043  1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47067  1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47093  1915 */ {0x0008, 0x8802},
-	/* 47118  1916 */ {0x002c, 0x8801},
-	/* 47143  1917 */ {0x00fe, 0x8800},
-	/* 47166  1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47190  1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47214  1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47240  1921 */ {0x0008, 0x8802},
-	/* 47265  1922 */ {0x002d, 0x8801},
-	/* 47290  1923 */ {0x0003, 0x8800},
-	/* 47313  1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47337  1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47361  1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47387  1927 */ {0x0008, 0x8802},
-	/* 47412  1928 */ {0x0038, 0x8801},
-	/* 47437  1929 */ {0x0083, 0x8800},
-	/* 47460  1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47484  1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47508  1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47534  1933 */ {0x0008, 0x8802},
-	/* 47559  1934 */ {0x0033, 0x8801},
-	/* 47584  1935 */ {0x0081, 0x8800},
-	/* 47607  1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47631  1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47655  1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47681  1939 */ {0x0008, 0x8802},
-	/* 47706  1940 */ {0x0034, 0x8801},
-	/* 47731  1941 */ {0x004a, 0x8800},
-	/* 47754  1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47778  1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47802  1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47828  1945 */ {0x0008, 0x8802},
-	/* 47853  1946 */ {0x0039, 0x8801},
-	/* 47878  1947 */ {0x0000, 0x8800},
-	/* 47901  1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47925  1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 47949  1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 47975  1951 */ {0x0008, 0x8802},
-	/* 48000  1952 */ {0x0010, 0x8801},
-	/* 48025  1953 */ {0x00a8, 0x8800},
-	/* 48048  1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48072  1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48096  1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48122  1957 */ {0x0008, 0x8802},
-	/* 48147  1958 */ {0x0006, 0x8801},
-	/* 48172  1959 */ {0x0058, 0x8800},
-	/* 48195  1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48219  1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
-	/* 48243  1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48269  1963 */ {0x0008, 0x8802},
-	/* 48294  1964 */ {0x0000, 0x8801},
-	/* 48319  1965 */ {0x0004, 0x8800},
-	/* 48342  1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48366  1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48390  1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48416  1969 */ {0x0008, 0x8802},
-	/* 48441  1970 */ {0x0040, 0x8801},
-	/* 48466  1971 */ {0x0080, 0x8800},
-	/* 48489  1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48513  1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48537  1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48563  1975 */ {0x0008, 0x8802},
-	/* 48588  1976 */ {0x0041, 0x8801},
-	/* 48613  1977 */ {0x000c, 0x8800},
-	/* 48636  1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48660  1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48684  1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48710  1981 */ {0x0008, 0x8802},
-	/* 48735  1982 */ {0x0042, 0x8801},
-	/* 48760  1983 */ {0x000c, 0x8800},
-	/* 48783  1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48807  1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48831  1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 48857  1987 */ {0x0008, 0x8802},
-	/* 48882  1988 */ {0x0043, 0x8801},
-	/* 48907  1989 */ {0x0028, 0x8800},
-	/* 48930  1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48954  1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 48978  1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49004  1993 */ {0x0008, 0x8802},
-	/* 49029  1994 */ {0x0044, 0x8801},
-	/* 49054  1995 */ {0x0080, 0x8800},
-	/* 49077  1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49101  1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49125  1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49151  1999 */ {0x0008, 0x8802},
-	/* 49176  2000 */ {0x0045, 0x8801},
-	/* 49201  2001 */ {0x0020, 0x8800},
-	/* 49224  2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49248  2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49272  2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49298  2005 */ {0x0008, 0x8802},
-	/* 49323  2006 */ {0x0046, 0x8801},
-	/* 49348  2007 */ {0x0020, 0x8800},
-	/* 49371  2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49395  2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49419  2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49445  2011 */ {0x0008, 0x8802},
-	/* 49470  2012 */ {0x0047, 0x8801},
-	/* 49495  2013 */ {0x0080, 0x8800},
-	/* 49518  2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49542  2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49566  2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49592  2017 */ {0x0008, 0x8802},
-	/* 49617  2018 */ {0x0048, 0x8801},
-	/* 49642  2019 */ {0x004c, 0x8800},
-	/* 49665  2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49689  2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49713  2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49739  2023 */ {0x0008, 0x8802},
-	/* 49764  2024 */ {0x0049, 0x8801},
-	/* 49789  2025 */ {0x0084, 0x8800},
-	/* 49812  2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49836  2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49860  2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 49886  2029 */ {0x0008, 0x8802},
-	/* 49911  2030 */ {0x004a, 0x8801},
-	/* 49936  2031 */ {0x0084, 0x8800},
-	/* 49959  2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 49983  2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 50007  2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 50033  2035 */ {0x0008, 0x8802},
-	/* 50058  2036 */ {0x004b, 0x8801},
-	/* 50083  2037 */ {0x0084, 0x8800},
-	/* 50106  2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
+	{0x00c0, 0x8804},	/* SSI slave addr */
+	{0x0008, 0x8802},	/* 375 Khz SSI clock */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},	/* 375 Khz SSI clock */
+	{0x0012, 0x8801},	/* SSI reg addr */
+	{0x0080, 0x8800},	/* SSI data to write */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},	/* 375 Khz SSI clock */
+	{0x0012, 0x8801},	/* SSI reg addr */
+	{0x0000, 0x8800},	/* SSI data to write */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},	/* 375 Khz SSI clock */
+	{0x0011, 0x8801},	/* SSI reg addr */
+	{0x0040, 0x8800},	/* SSI data to write */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0013, 0x8801},
+	{0x0000, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0014, 0x8801},
+	{0x0000, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0015, 0x8801},
+	{0x0001, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0016, 0x8801},
+	{0x0003, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0017, 0x8801},
+	{0x0036, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0018, 0x8801},
+	{0x00ec, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x001a, 0x8801},
+	{0x0094, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x001b, 0x8801},
+	{0x0000, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0027, 0x8801},
+	{0x00a2, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0028, 0x8801},
+	{0x0040, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x002a, 0x8801},
+	{0x0084, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00 */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x002b, 0x8801},
+	{0x00a8, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x002c, 0x8801},
+	{0x00fe, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x002d, 0x8801},
+	{0x0003, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0038, 0x8801},
+	{0x0083, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0033, 0x8801},
+	{0x0081, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0034, 0x8801},
+	{0x004a, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0039, 0x8801},
+	{0x0000, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0010, 0x8801},
+	{0x00a8, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0006, 0x8801},
+	{0x0058, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00 */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0000, 0x8801},
+	{0x0004, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0040, 0x8801},
+	{0x0080, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0041, 0x8801},
+	{0x000c, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0042, 0x8801},
+	{0x000c, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0043, 0x8801},
+	{0x0028, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0044, 0x8801},
+	{0x0080, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0045, 0x8801},
+	{0x0020, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0046, 0x8801},
+	{0x0020, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0047, 0x8801},
+	{0x0080, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0048, 0x8801},
+	{0x004c, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x0049, 0x8801},
+	{0x0084, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x004a, 0x8801},
+	{0x0084, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x0008, 0x8802},
+	{0x004b, 0x8801},
+	{0x0084, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 	/* --------------------------------------- */
-	/* 50132  2039 */ {0x0012, 0x8700},
-	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
-	/* 50157  2040 */ {0x0000, 0x8701},
-	/* CKx1 clock delay adj */
-	/* 50182  2041 */ {0x0000, 0x8701},
-	/* CKx1 clock delay adj */
-	/* 50207  2042 */ {0x0001, 0x870c},
-	/* CKOx2 output */
+	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+	{0x0000, 0x8701},	/* CKx1 clock delay adj */
+	{0x0000, 0x8701},	/* CKx1 clock delay adj */
+	{0x0001, 0x870c},	/* CKOx2 output */
 	/* --------------------------------------- */
-	/* 50232  2043 */ {0x0080, 0x8600},
-	/* Line memory read counter (L) */
-	/* 50257  2044 */ {0x0001, 0x8606},
-	/* reserved */
-	/* 50282  2045 */ {0x0064, 0x8607},
-	/* Line memory read counter (H) 0x6480=25,728 */
-	/* 50307  2046 */ {0x002a, 0x8601},
-	/* CDSP sharp interpolation mode,
+	{0x0080, 0x8600},	/* Line memory read counter (L) */
+	{0x0001, 0x8606},	/* reserved */
+	{0x0064, 0x8607},	/* Line memory read counter (H) 0x6480=25,728 */
+	{0x002a, 0x8601},	/* CDSP sharp interpolation mode,
 	 *			line sel for color sep, edge enhance enab */
-	/* 50332  2047 */ {0x0000, 0x8602},
-	/* optical black level for user settng = 0 */
-	/* 50357  2048 */ {0x0080, 0x8600},
-	/* Line memory read counter (L) */
-	/* 50382  2049 */ {0x000a, 0x8603},
-	/* optical black level calc mode: auto; optical black offset = 10 */
-	/* 50407  2050 */ {0x00df, 0x865b},
-	/* Horiz offset for valid pixels (L)=0xdf */
-	/* 50432  2051 */ {0x0012, 0x865c},
-	/* Vert offset for valid lines (L)=0x12 */
+	{0x0000, 0x8602},	/* optical black level for user settng = 0 */
+	{0x0080, 0x8600},	/* Line memory read counter (L) */
+	{0x000a, 0x8603},	/* optical black level calc mode:
+				 * auto; optical black offset = 10 */
+	{0x00df, 0x865b},	/* Horiz offset for valid pixels (L)=0xdf */
+	{0x0012, 0x865c},	/* Vert offset for valid lines (L)=0x12 */
 
 /* The following two lines seem to be the "wrong" resolution. */
 /* But perhaps these indicate the actual size of the sensor */
 /* rather than the size of the current video mode. */
-	/* 50457  2052 */ {0x0058, 0x865d},
-	/* Horiz valid pixels (*4) (L) = 352 */
-	/* 50482  2053 */ {0x0048, 0x865e},
-	/* Vert valid lines (*4) (L) = 288 */
-
-	/* 50507  2054 */ {0x0015, 0x8608},
-	/* A11 Coef ... */
-	/* 50532  2055 */ {0x0030, 0x8609},
-	/* 50557  2056 */ {0x00fb, 0x860a},
-	/* 50582  2057 */ {0x003e, 0x860b},
-	/* 50607  2058 */ {0x00ce, 0x860c},
-	/* 50632  2059 */ {0x00f4, 0x860d},
-	/* 50657  2060 */ {0x00eb, 0x860e},
-	/* 50682  2061 */ {0x00dc, 0x860f},
-	/* 50707  2062 */ {0x0039, 0x8610},
-	/* 50732  2063 */ {0x0001, 0x8611},
-	/* R offset for white balance ... */
-	/* 50757  2064 */ {0x0000, 0x8612},
-	/* 50782  2065 */ {0x0001, 0x8613},
-	/* 50807  2066 */ {0x0000, 0x8614},
-	/* 50832  2067 */ {0x005b, 0x8651},
-	/* R gain for white balance ... */
-	/* 50857  2068 */ {0x0040, 0x8652},
-	/* 50882  2069 */ {0x0060, 0x8653},
-	/* 50907  2070 */ {0x0040, 0x8654},
-	/* 50932  2071 */ {0x0000, 0x8655},
-	/* 50957  2072 */ {0x0001, 0x863f},
-	/* Fixed gamma correction enable, USB control,
-	 *			 lum filter disable, lum noise clip disable */
-	/* 50982  2073 */ {0x00a1, 0x8656},
-	/* Window1 size 256x256, Windows2 size 64x64,
-	 *		 gamma look-up disable, new edge enhancement enable */
-	/* 51007  2074 */ {0x0018, 0x8657},
-	/* Edge gain high thresh */
-	/* 51032  2075 */ {0x0020, 0x8658},
-	/* Edge gain low thresh */
-	/* 51057  2076 */ {0x000a, 0x8659},
-	/* Edge bandwidth high threshold */
-	/* 51082  2077 */ {0x0005, 0x865a},
-	/* Edge bandwidth low threshold */
+	{0x0058, 0x865d},	/* Horiz valid pixels (*4) (L) = 352 */
+	{0x0048, 0x865e},	/* Vert valid lines (*4) (L) = 288 */
+
+	{0x0015, 0x8608},	/* A11 Coef ... */
+	{0x0030, 0x8609},
+	{0x00fb, 0x860a},
+	{0x003e, 0x860b},
+	{0x00ce, 0x860c},
+	{0x00f4, 0x860d},
+	{0x00eb, 0x860e},
+	{0x00dc, 0x860f},
+	{0x0039, 0x8610},
+	{0x0001, 0x8611},	/* R offset for white balance ... */
+	{0x0000, 0x8612},
+	{0x0001, 0x8613},
+	{0x0000, 0x8614},
+	{0x005b, 0x8651},	/* R gain for white balance ... */
+	{0x0040, 0x8652},
+	{0x0060, 0x8653},
+	{0x0040, 0x8654},
+	{0x0000, 0x8655},
+	{0x0001, 0x863f},	/* Fixed gamma correction enable, USB control,
+				 * lum filter disable, lum noise clip disable */
+	{0x00a1, 0x8656},	/* Window1 size 256x256, Windows2 size 64x64,
+				 * gamma look-up disable,
+				 * new edge enhancement enable */
+	{0x0018, 0x8657},	/* Edge gain high thresh */
+	{0x0020, 0x8658},	/* Edge gain low thresh */
+	{0x000a, 0x8659},	/* Edge bandwidth high threshold */
+	{0x0005, 0x865a},	/* Edge bandwidth low threshold */
 	/* -------------------------------- */
-	/* 51107  2078 */ {0x0030, 0x8112},
-	/* Video drop enable, ISO streaming enable */
-	/* 51130  2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 51154  2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 51180  2081 */ {0xa908, 0x8802},
-	/* 51205  2082 */ {0x0034, 0x8801},
-	/* SSI reg addr */
-	/* 51230  2083 */ {0x00ca, 0x8800},
+	{0x0030, 0x8112},	/* Video drop enable, ISO streaming enable */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0xa908, 0x8802},
+	{0x0034, 0x8801},	/* SSI reg addr */
+	{0x00ca, 0x8800},
 	/* SSI data to write */
-	/* 51253  2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 51277  2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 51301  2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 51327  2087 */ {0x1f08, 0x8802},
-	/* 51352  2088 */ {0x0006, 0x8801},
-	/* 51377  2089 */ {0x0080, 0x8800},
-	/* 51400  2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0x1f08, 0x8802},
+	{0x0006, 0x8801},
+	{0x0080, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
 /* ----- Read back coefs we wrote earlier. */
-	/* 51424  2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15  */
-	/* 51448  2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30  */
-	/* 51472  2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb  */
-	/* 51496  2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e  */
-	/* 51520  2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce  */
-	/* 51544  2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4  */
-	/* 51568  2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb  */
-	/* 51592  2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc  */
-	/* 51616  2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39  */
-	/* 51640  2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 51664  2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08  */
-	/* 51690  2102 */ {0xb008, 0x8802},
-	/* 51715  2103 */ {0x0006, 0x8801},
-	/* 51740  2104 */ {0x007d, 0x8800},
-	/* 51763  2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0000, 0x8608 } -> 0000: 15  */
+	/* READ { 0x0000, 0x8609 } -> 0000: 30  */
+	/* READ { 0x0000, 0x860a } -> 0000: fb  */
+	/* READ { 0x0000, 0x860b } -> 0000: 3e  */
+	/* READ { 0x0000, 0x860c } -> 0000: ce  */
+	/* READ { 0x0000, 0x860d } -> 0000: f4  */
+	/* READ { 0x0000, 0x860e } -> 0000: eb  */
+	/* READ { 0x0000, 0x860f } -> 0000: dc  */
+	/* READ { 0x0000, 0x8610 } -> 0000: 39  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
+	{0xb008, 0x8802},
+	{0x0006, 0x8801},
+	{0x007d, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
 
 	/* This chunk is seemingly redundant with */
 	/* earlier commands (A11 Coef...), but if I disable it, */
 	/* the image appears too dark.  Maybe there was some kind of */
 	/* reset since the earlier commands, so this is necessary again. */
-	/* 51789  2106 */ {0x0015, 0x8608},
-	/* 51814  2107 */ {0x0030, 0x8609},
-	/* 51839  2108 */ {0xfffb, 0x860a},
-	/* 51864  2109 */ {0x003e, 0x860b},
-	/* 51889  2110 */ {0xffce, 0x860c},
-	/* 51914  2111 */ {0xfff4, 0x860d},
-	/* 51939  2112 */ {0xffeb, 0x860e},
-	/* 51964  2113 */ {0xffdc, 0x860f},
-	/* 51989  2114 */ {0x0039, 0x8610},
-	/* 52014  2115 */ {0x0018, 0x8657},
-
-	/* 52039  2116 */ {0x0000, 0x8508},
-	/* Disable compression. */
+	{0x0015, 0x8608},
+	{0x0030, 0x8609},
+	{0xfffb, 0x860a},
+	{0x003e, 0x860b},
+	{0xffce, 0x860c},
+	{0xfff4, 0x860d},
+	{0xffeb, 0x860e},
+	{0xffdc, 0x860f},
+	{0x0039, 0x8610},
+	{0x0018, 0x8657},
+
+	{0x0000, 0x8508},	/* Disable compression. */
 	/* Previous line was:
-	 * 52039  2116 *  { 0, 0x0021, 0x8508 },  * Enable compression. */
-	/* 52064  2117 */ {0x0032, 0x850b},
-	/* compression stuff */
-	/* 52089  2118 */ {0x0003, 0x8509},
-	/* compression stuff */
-	/* 52114  2119 */ {0x0011, 0x850a},
-	/* compression stuff */
-	/* 52139  2120 */ {0x0021, 0x850d},
-	/* compression stuff */
-	/* 52164  2121 */ {0x0010, 0x850c},
-	/* compression stuff */
-	/* 52189  2122 */ {0x0003, 0x8500},
-	/* *** Video mode: 160x120 */
-	/* 52214  2123 */ {0x0001, 0x8501},
-	/* Hardware-dominated snap control */
-	/* 52239  2124 */ {0x0061, 0x8656},
-	/* Window1 size 128x128, Windows2 size 128x128,
-	 *		gamma look-up disable, new edge enhancement enable */
-	/* 52264  2125 */ {0x0018, 0x8617},
-	/* Window1 start X (*2) */
-	/* 52289  2126 */ {0x0008, 0x8618},
-	/* Window1 start Y (*2) */
-	/* 52314  2127 */ {0x0061, 0x8656},
-	/* Window1 size 128x128, Windows2 size 128x128,
-	 *		gamma look-up disable, new edge enhancement enable */
-	/* 52339  2128 */ {0x0058, 0x8619},
-	/* Window2 start X (*2) */
-	/* 52364  2129 */ {0x0008, 0x861a},
-	/* Window2 start Y (*2) */
-	/* 52389  2130 */ {0x00ff, 0x8615},
-	/* High lum thresh for white balance */
-	/* 52414  2131 */ {0x0000, 0x8616},
-	/* Low lum thresh for white balance */
-	/* 52439  2132 */ {0x0012, 0x8700},
-	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
-	/* 52464  2133 */ {0x0012, 0x8700},
-	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
-	/* 52487  2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61  */
-	/* 52513  2135 */ {0x0028, 0x8802},
-	/* 375 Khz SSI clock, SSI r/w sync with VSYNC */
-	/* 52536  2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 52560  2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28  */
-	/* 52586  2138 */ {0x1f28, 0x8802},
-	/* 375 Khz SSI clock, SSI r/w sync with VSYNC */
-	/* 52611  2139 */ {0x0010, 0x8801},
-	/* SSI reg addr */
-	/* 52636  2140 */ {0x003e, 0x8800},
-	/* SSI data to write */
-	/* 52659  2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 52685  2142 */ {0x0028, 0x8802},
-	/* 52708  2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 52732  2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28  */
-	/* 52758  2145 */ {0x1f28, 0x8802},
-	/* 52783  2146 */ {0x0000, 0x8801},
-	/* 52808  2147 */ {0x001f, 0x8800},
-	/* 52831  2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 52857  2149 */ {0x0001, 0x8602},
-	/* optical black level for user settning = 1 */
+	{0x0021, 0x8508},	 * Enable compression. */
+	{0x0032, 0x850b},	/* compression stuff */
+	{0x0003, 0x8509},	/* compression stuff */
+	{0x0011, 0x850a},	/* compression stuff */
+	{0x0021, 0x850d},	/* compression stuff */
+	{0x0010, 0x850c},	/* compression stuff */
+	{0x0003, 0x8500},	/* *** Video mode: 160x120 */
+	{0x0001, 0x8501},	/* Hardware-dominated snap control */
+	{0x0061, 0x8656},	/* Window1 size 128x128, Windows2 size 128x128,
+				 * gamma look-up disable,
+				 * new edge enhancement enable */
+	{0x0018, 0x8617},	/* Window1 start X (*2) */
+	{0x0008, 0x8618},	/* Window1 start Y (*2) */
+	{0x0061, 0x8656},	/* Window1 size 128x128, Windows2 size 128x128,
+				 * gamma look-up disable,
+				 * new edge enhancement enable */
+	{0x0058, 0x8619},	/* Window2 start X (*2) */
+	{0x0008, 0x861a},	/* Window2 start Y (*2) */
+	{0x00ff, 0x8615},	/* High lum thresh for white balance */
+	{0x0000, 0x8616},	/* Low lum thresh for white balance */
+	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+	/* READ { 0x0000, 0x8656 } -> 0000: 61  */
+	{0x0028, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
+	{0x1f28, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
+	{0x0010, 0x8801},	/* SSI reg addr */
+	{0x003e, 0x8800},	/* SSI data to write */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	{0x0028, 0x8802},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
+	{0x1f28, 0x8802},
+	{0x0000, 0x8801},
+	{0x001f, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	{0x0001, 0x8602},    /* optical black level for user settning = 1 */
 
 	/* Original: */
-	/* 52882  2150 */ {0x0023, 0x8700},
-	/* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
-	/* 52907  2151 */ {0x000f, 0x8602},
-	/* optical black level for user settning = 15 */
-
-	/* 52932  2152 */ {0x0028, 0x8802},
-	/* 52955  2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 52979  2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28  */
-	/* 53005  2155 */ {0x1f28, 0x8802},
-	/* 53030  2156 */ {0x0010, 0x8801},
-	/* 53055  2157 */ {0x007b, 0x8800},
-	/* 53078  2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00  */
-	/* 53104  2159 */ {0x002f, 0x8651},
-	/* R gain for white balance ... */
-	/* 53129  2160 */ {0x0080, 0x8653},
-	/* 53152  2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00  */
-	/* 53178  2162 */ {0x0000, 0x8655},
-
-	/* 53203  2163 */ {0x0030, 0x8112},
-	/* Video drop enable, ISO streaming enable */
-	/* 53228  2164 */ {0x0020, 0x8112},
-	/* Video drop enable, ISO streaming disable */
-	/* 53252  2165 */
-	     /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
+	{0x0023, 0x8700},	/* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
+	{0x000f, 0x8602},    /* optical black level for user settning = 15 */
+
+	{0x0028, 0x8802},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
+	{0x1f28, 0x8802},
+	{0x0010, 0x8801},
+	{0x007b, 0x8800},
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	{0x002f, 0x8651},	/* R gain for white balance ... */
+	{0x0080, 0x8653},
+	/* READ { 0x0000, 0x8655 } -> 0000: 00  */
+	{0x0000, 0x8655},
+
+	{0x0030, 0x8112},	/* Video drop enable, ISO streaming enable */
+	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
+	/* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
 	{}
 };
 
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] =
  * Initialization data for Intel EasyPC Camera CS110
  */
 static const u16 spca508cs110_init_data[][2] = {
-	{0x0000, 0x870b}, /* Reset CTL3 */
-	{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
-	{0x0000, 0x8111}, /* Normal operation on reset */
+	{0x0000, 0x870b},	/* Reset CTL3 */
+	{0x0003, 0x8111},	/* Soft Reset compression, memory, TG & CDSP */
+	{0x0000, 0x8111},	/* Normal operation on reset */
 	{0x0090, 0x8110},
 		 /* External Clock 2x & Synchronous Serial Interface Output */
-	{0x0020, 0x8112}, /* Video Drop packet enable */
-	{0x0000, 0x8114}, /* Software GPIO output data */
+	{0x0020, 0x8112},	/* Video Drop packet enable */
+	{0x0000, 0x8114},	/* Software GPIO output data */
 	{0x0001, 0x8114},
 	{0x0001, 0x8114},
 	{0x0001, 0x8114},
 	{0x0003, 0x8114},
 
 	/* Initial sequence Synchronous Serial Interface */
-	{0x000f, 0x8402}, /* Memory bank Address */
-	{0x0000, 0x8403}, /* Memory bank Address */
-	{0x00ba, 0x8804}, /* SSI Slave address */
-	{0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
-	{0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */
+	{0x000f, 0x8402},	/* Memory bank Address */
+	{0x0000, 0x8403},	/* Memory bank Address */
+	{0x00ba, 0x8804},	/* SSI Slave address */
+	{0x0010, 0x8802},	/* 93.75kHz SSI Clock Two DataByte */
+	{0x0010, 0x8802},	/* 93.75kHz SSI Clock two DataByte */
 
 	{0x0001, 0x8801},
-	{0x000a, 0x8805},/* a - NWG: Dunno what this is about */
+	{0x000a, 0x8805},	/* a - NWG: Dunno what this is about */
 	{0x0000, 0x8800},
 	{0x0010, 0x8802},
 
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = {
 	{0x0000, 0x8800},
 	{0x0010, 0x8802},
 
-	{0x0002, 0x8704}, /* External input CKIx1 */
-	{0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
-	{0x009a, 0x8600}, /* Line memory Read Counter (L) */
-	{0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
-	{0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */
-	{0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */
+	{0x0002, 0x8704},	/* External input CKIx1 */
+	{0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
+	{0x009a, 0x8600},	/* Line memory Read Counter (L) */
+	{0x0001, 0x865b},	/* 1 Horizontal Offset for Valid Pixel(L) */
+	{0x0003, 0x865c},	/* 3 Vertical Offset for Valid Lines(L) */
+	{0x0058, 0x865d},	/* 58 Horizontal Valid Pixel Window(L) */
 
-	{0x0006, 0x8660}, /* Nibble data + input order */
+	{0x0006, 0x8660},	/* Nibble data + input order */
 
-	{0x000a, 0x8602}, /* Optical black level set to 0x0a */
-/* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */
+	{0x000a, 0x8602},	/* Optical black level set to 0x0a */
+	{0x0000, 0x8603},	/* Optical black level Offset */
 
-/* 1962 *  {0, 0x0000, 0x8611},  * 0 R  Offset for white Balance */
-/* 1963 *  {0, 0x0000, 0x8612},  * 1 Gr Offset for white Balance */
-/* 1964 *  {0, 0x0000, 0x8613},  * 1f B  Offset for white Balance */
-/* 1965 *  {0, 0x0000, 0x8614},  * f0 Gb Offset for white Balance */
+/*	{0x0000, 0x8611},	 * 0 R  Offset for white Balance */
+/*	{0x0000, 0x8612},	 * 1 Gr Offset for white Balance */
+/*	{0x0000, 0x8613},	 * 1f B  Offset for white Balance */
+/*	{0x0000, 0x8614},	 * f0 Gb Offset for white Balance */
 
-	{0x0040, 0x8651}, /* 2b BLUE gain for white balance  good at all 60 */
-	{0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */
-	{0x0035, 0x8653}, /* 26 RED gain for white balance */
-	{0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */
+	{0x0040, 0x8651},   /* 2b BLUE gain for white balance  good at all 60 */
+	{0x0030, 0x8652},	/* 41 Gr Gain for white Balance (L) */
+	{0x0035, 0x8653},	/* 26 RED gain for white balance */
+	{0x0035, 0x8654},	/* 40Gb Gain for white Balance (L) */
 	{0x0041, 0x863f},
 	      /* Fixed Gamma correction enabled (makes colours look better) */
 
-/* 2422 */ {0x0000, 0x8655},
-	/* High bits for white balance*****brightness control*** */
+	{0x0000, 0x8655},
+		/* High bits for white balance*****brightness control*** */
 	{}
 };
 
 static const u16 spca508_sightcam_init_data[][2] = {
 /* This line seems to setup the frame/canvas */
-	/*368  */ {0x000f, 0x8402},
+	{0x000f, 0x8402},
 
 /* Theese 6 lines are needed to startup the webcam */
-	/*398  */ {0x0090, 0x8110},
-	/*399  */ {0x0001, 0x8114},
-	/*400  */ {0x0001, 0x8114},
-	/*401  */ {0x0001, 0x8114},
-	/*402  */ {0x0003, 0x8114},
-	/*403  */ {0x0080, 0x8804},
+	{0x0090, 0x8110},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0003, 0x8114},
+	{0x0080, 0x8804},
 
 /* This part seems to make the pictures darker? (autobrightness?) */
-	/*436  */ {0x0001, 0x8801},
-	/*437  */ {0x0004, 0x8800},
-	/*439  */ {0x0003, 0x8801},
-	/*440  */ {0x00e0, 0x8800},
-	/*442  */ {0x0004, 0x8801},
-	/*443  */ {0x00b4, 0x8800},
-	/*445  */ {0x0005, 0x8801},
-	/*446  */ {0x0000, 0x8800},
-
-	/*448  */ {0x0006, 0x8801},
-	/*449  */ {0x00e0, 0x8800},
-	/*451  */ {0x0007, 0x8801},
-	/*452  */ {0x000c, 0x8800},
+	{0x0001, 0x8801},
+	{0x0004, 0x8800},
+	{0x0003, 0x8801},
+	{0x00e0, 0x8800},
+	{0x0004, 0x8801},
+	{0x00b4, 0x8800},
+	{0x0005, 0x8801},
+	{0x0000, 0x8800},
+
+	{0x0006, 0x8801},
+	{0x00e0, 0x8800},
+	{0x0007, 0x8801},
+	{0x000c, 0x8800},
 
 /* This section is just needed, it probably
  * does something like the previous section,
  * but the cam won't start if it's not included.
  */
-	/*484  */ {0x0014, 0x8801},
-	/*485  */ {0x0008, 0x8800},
-	/*487  */ {0x0015, 0x8801},
-	/*488  */ {0x0067, 0x8800},
-	/*490  */ {0x0016, 0x8801},
-	/*491  */ {0x0000, 0x8800},
-	/*493  */ {0x0017, 0x8801},
-	/*494  */ {0x0020, 0x8800},
-	/*496  */ {0x0018, 0x8801},
-	/*497  */ {0x0044, 0x8800},
+	{0x0014, 0x8801},
+	{0x0008, 0x8800},
+	{0x0015, 0x8801},
+	{0x0067, 0x8800},
+	{0x0016, 0x8801},
+	{0x0000, 0x8800},
+	{0x0017, 0x8801},
+	{0x0020, 0x8800},
+	{0x0018, 0x8801},
+	{0x0044, 0x8800},
 
 /* Makes the picture darker - and the
  * cam won't start if not included
  */
-	/*505  */ {0x001e, 0x8801},
-	/*506  */ {0x00ea, 0x8800},
-	/*508  */ {0x001f, 0x8801},
-	/*509  */ {0x0001, 0x8800},
-	/*511  */ {0x0003, 0x8801},
-	/*512  */ {0x00e0, 0x8800},
+	{0x001e, 0x8801},
+	{0x00ea, 0x8800},
+	{0x001f, 0x8801},
+	{0x0001, 0x8800},
+	{0x0003, 0x8801},
+	{0x00e0, 0x8800},
 
 /* seems to place the colors ontop of each other #1 */
-	/*517  */ {0x0006, 0x8704},
-	/*518  */ {0x0001, 0x870c},
-	/*519  */ {0x0016, 0x8600},
-	/*520  */ {0x0002, 0x8606},
+	{0x0006, 0x8704},
+	{0x0001, 0x870c},
+	{0x0016, 0x8600},
+	{0x0002, 0x8606},
 
 /* if not included the pictures becomes _very_ dark */
-	/*521  */ {0x0064, 0x8607},
-	/*522  */ {0x003a, 0x8601},
-	/*523  */ {0x0000, 0x8602},
+	{0x0064, 0x8607},
+	{0x003a, 0x8601},
+	{0x0000, 0x8602},
 
 /* seems to place the colors ontop of each other #2 */
-	/*524  */ {0x0016, 0x8600},
-	/*525  */ {0x0018, 0x8617},
-	/*526  */ {0x0008, 0x8618},
-	/*527  */ {0x00a1, 0x8656},
+	{0x0016, 0x8600},
+	{0x0018, 0x8617},
+	{0x0008, 0x8618},
+	{0x00a1, 0x8656},
 
 /* webcam won't start if not included */
-	/*528  */ {0x0007, 0x865b},
-	/*529  */ {0x0001, 0x865c},
-	/*530  */ {0x0058, 0x865d},
-	/*531  */ {0x0048, 0x865e},
+	{0x0007, 0x865b},
+	{0x0001, 0x865c},
+	{0x0058, 0x865d},
+	{0x0048, 0x865e},
 
 /* adjusts the colors */
-	/*541  */ {0x0049, 0x8651},
-	/*542  */ {0x0040, 0x8652},
-	/*543  */ {0x004c, 0x8653},
-	/*544  */ {0x0040, 0x8654},
+	{0x0049, 0x8651},
+	{0x0040, 0x8652},
+	{0x004c, 0x8653},
+	{0x0040, 0x8654},
 	{}
 };
 
 static const u16 spca508_sightcam2_init_data[][2] = {
-/* 35 */ {0x0020, 0x8112},
-
-/* 36 */ {0x000f, 0x8402},
-/* 37 */ {0x0000, 0x8403},
-
-/* 38 */ {0x0008, 0x8201},
-/* 39 */ {0x0008, 0x8200},
-/* 40 */ {0x0001, 0x8200},
-/* 43 */ {0x0009, 0x8201},
-/* 44 */ {0x0008, 0x8200},
-/* 45 */ {0x0001, 0x8200},
-/* 48 */ {0x000a, 0x8201},
-/* 49 */ {0x0008, 0x8200},
-/* 50 */ {0x0001, 0x8200},
-/* 53 */ {0x000b, 0x8201},
-/* 54 */ {0x0008, 0x8200},
-/* 55 */ {0x0001, 0x8200},
-/* 58 */ {0x000c, 0x8201},
-/* 59 */ {0x0008, 0x8200},
-/* 60 */ {0x0001, 0x8200},
-/* 63 */ {0x000d, 0x8201},
-/* 64 */ {0x0008, 0x8200},
-/* 65 */ {0x0001, 0x8200},
-/* 68 */ {0x000e, 0x8201},
-/* 69 */ {0x0008, 0x8200},
-/* 70 */ {0x0001, 0x8200},
-/* 73 */ {0x0007, 0x8201},
-/* 74 */ {0x0008, 0x8200},
-/* 75 */ {0x0001, 0x8200},
-/* 78 */ {0x000f, 0x8201},
-/* 79 */ {0x0008, 0x8200},
-/* 80 */ {0x0001, 0x8200},
-
-/* 84 */ {0x0018, 0x8660},
-/* 85 */ {0x0010, 0x8201},
-
-/* 86 */ {0x0008, 0x8200},
-/* 87 */ {0x0001, 0x8200},
-/* 90 */ {0x0011, 0x8201},
-/* 91 */ {0x0008, 0x8200},
-/* 92 */ {0x0001, 0x8200},
-
-/* 95 */ {0x0000, 0x86b0},
-/* 96 */ {0x0034, 0x86b1},
-/* 97 */ {0x0000, 0x86b2},
-/* 98 */ {0x0049, 0x86b3},
-/* 99 */ {0x0000, 0x86b4},
-/* 100 */ {0x0000, 0x86b4},
-
-/* 101 */ {0x0012, 0x8201},
-/* 102 */ {0x0008, 0x8200},
-/* 103 */ {0x0001, 0x8200},
-/* 106 */ {0x0013, 0x8201},
-/* 107 */ {0x0008, 0x8200},
-/* 108 */ {0x0001, 0x8200},
-
-/* 111 */ {0x0001, 0x86b0},
-/* 112 */ {0x00aa, 0x86b1},
-/* 113 */ {0x0000, 0x86b2},
-/* 114 */ {0x00e4, 0x86b3},
-/* 115 */ {0x0000, 0x86b4},
-/* 116 */ {0x0000, 0x86b4},
-
-/* 118 */ {0x0018, 0x8660},
-
-/* 119 */ {0x0090, 0x8110},
-/* 120 */ {0x0001, 0x8114},
-/* 121 */ {0x0001, 0x8114},
-/* 122 */ {0x0001, 0x8114},
-/* 123 */ {0x0003, 0x8114},
-
-/* 124 */ {0x0080, 0x8804},
-/* 157 */ {0x0003, 0x8801},
-/* 158 */ {0x0012, 0x8800},
-/* 160 */ {0x0004, 0x8801},
-/* 161 */ {0x0005, 0x8800},
-/* 163 */ {0x0005, 0x8801},
-/* 164 */ {0x0000, 0x8800},
-/* 166 */ {0x0006, 0x8801},
-/* 167 */ {0x0000, 0x8800},
-/* 169 */ {0x0007, 0x8801},
-/* 170 */ {0x0000, 0x8800},
-/* 172 */ {0x0008, 0x8801},
-/* 173 */ {0x0005, 0x8800},
-/* 175 */ {0x000a, 0x8700},
-/* 176 */ {0x000e, 0x8801},
-/* 177 */ {0x0004, 0x8800},
-/* 179 */ {0x0005, 0x8801},
-/* 180 */ {0x0047, 0x8800},
-/* 182 */ {0x0006, 0x8801},
-/* 183 */ {0x0000, 0x8800},
-/* 185 */ {0x0007, 0x8801},
-/* 186 */ {0x00c0, 0x8800},
-/* 188 */ {0x0008, 0x8801},
-/* 189 */ {0x0003, 0x8800},
-/* 191 */ {0x0013, 0x8801},
-/* 192 */ {0x0001, 0x8800},
-/* 194 */ {0x0009, 0x8801},
-/* 195 */ {0x0000, 0x8800},
-/* 197 */ {0x000a, 0x8801},
-/* 198 */ {0x0000, 0x8800},
-/* 200 */ {0x000b, 0x8801},
-/* 201 */ {0x0000, 0x8800},
-/* 203 */ {0x000c, 0x8801},
-/* 204 */ {0x0000, 0x8800},
-/* 206 */ {0x000e, 0x8801},
-/* 207 */ {0x0004, 0x8800},
-/* 209 */ {0x000f, 0x8801},
-/* 210 */ {0x0000, 0x8800},
-/* 212 */ {0x0010, 0x8801},
-/* 213 */ {0x0006, 0x8800},
-/* 215 */ {0x0011, 0x8801},
-/* 216 */ {0x0006, 0x8800},
-/* 218 */ {0x0012, 0x8801},
-/* 219 */ {0x0000, 0x8800},
-/* 221 */ {0x0013, 0x8801},
-/* 222 */ {0x0001, 0x8800},
-
-/* 224 */ {0x000a, 0x8700},
-/* 225 */ {0x0000, 0x8702},
-/* 226 */ {0x0000, 0x8703},
-/* 227 */ {0x00c2, 0x8704},
-/* 228 */ {0x0001, 0x870c},
-
-/* 229 */ {0x0044, 0x8600},
-/* 230 */ {0x0002, 0x8606},
-/* 231 */ {0x0064, 0x8607},
-/* 232 */ {0x003a, 0x8601},
-/* 233 */ {0x0008, 0x8602},
-/* 234 */ {0x0044, 0x8600},
-/* 235 */ {0x0018, 0x8617},
-/* 236 */ {0x0008, 0x8618},
-/* 237 */ {0x00a1, 0x8656},
-/* 238 */ {0x0004, 0x865b},
-/* 239 */ {0x0002, 0x865c},
-/* 240 */ {0x0058, 0x865d},
-/* 241 */ {0x0048, 0x865e},
-/* 242 */ {0x0012, 0x8608},
-/* 243 */ {0x002c, 0x8609},
-/* 244 */ {0x0002, 0x860a},
-/* 245 */ {0x002c, 0x860b},
-/* 246 */ {0x00db, 0x860c},
-/* 247 */ {0x00f9, 0x860d},
-/* 248 */ {0x00f1, 0x860e},
-/* 249 */ {0x00e3, 0x860f},
-/* 250 */ {0x002c, 0x8610},
-/* 251 */ {0x006c, 0x8651},
-/* 252 */ {0x0041, 0x8652},
-/* 253 */ {0x0059, 0x8653},
-/* 254 */ {0x0040, 0x8654},
-/* 255 */ {0x00fa, 0x8611},
-/* 256 */ {0x00ff, 0x8612},
-/* 257 */ {0x00f8, 0x8613},
-/* 258 */ {0x0000, 0x8614},
-/* 259 */ {0x0001, 0x863f},
-/* 260 */ {0x0000, 0x8640},
-/* 261 */ {0x0026, 0x8641},
-/* 262 */ {0x0045, 0x8642},
-/* 263 */ {0x0060, 0x8643},
-/* 264 */ {0x0075, 0x8644},
-/* 265 */ {0x0088, 0x8645},
-/* 266 */ {0x009b, 0x8646},
-/* 267 */ {0x00b0, 0x8647},
-/* 268 */ {0x00c5, 0x8648},
-/* 269 */ {0x00d2, 0x8649},
-/* 270 */ {0x00dc, 0x864a},
-/* 271 */ {0x00e5, 0x864b},
-/* 272 */ {0x00eb, 0x864c},
-/* 273 */ {0x00f0, 0x864d},
-/* 274 */ {0x00f6, 0x864e},
-/* 275 */ {0x00fa, 0x864f},
-/* 276 */ {0x00ff, 0x8650},
-/* 277 */ {0x0060, 0x8657},
-/* 278 */ {0x0010, 0x8658},
-/* 279 */ {0x0018, 0x8659},
-/* 280 */ {0x0005, 0x865a},
-/* 281 */ {0x0018, 0x8660},
-/* 282 */ {0x0003, 0x8509},
-/* 283 */ {0x0011, 0x850a},
-/* 284 */ {0x0032, 0x850b},
-/* 285 */ {0x0010, 0x850c},
-/* 286 */ {0x0021, 0x850d},
-/* 287 */ {0x0001, 0x8500},
-/* 288 */ {0x0000, 0x8508},
-/* 289 */ {0x0012, 0x8608},
-/* 290 */ {0x002c, 0x8609},
-/* 291 */ {0x0002, 0x860a},
-/* 292 */ {0x0039, 0x860b},
-/* 293 */ {0x00d0, 0x860c},
-/* 294 */ {0x00f7, 0x860d},
-/* 295 */ {0x00ed, 0x860e},
-/* 296 */ {0x00db, 0x860f},
-/* 297 */ {0x0039, 0x8610},
-/* 298 */ {0x0012, 0x8657},
-/* 299 */ {0x000c, 0x8619},
-/* 300 */ {0x0004, 0x861a},
-/* 301 */ {0x00a1, 0x8656},
-/* 302 */ {0x00c8, 0x8615},
-/* 303 */ {0x0032, 0x8616},
-
-/* 306 */ {0x0030, 0x8112},
-/* 313 */ {0x0020, 0x8112},
-/* 314 */ {0x0020, 0x8112},
-/* 315 */ {0x000f, 0x8402},
-/* 316 */ {0x0000, 0x8403},
-
-/* 317 */ {0x0090, 0x8110},
-/* 318 */ {0x0001, 0x8114},
-/* 319 */ {0x0001, 0x8114},
-/* 320 */ {0x0001, 0x8114},
-/* 321 */ {0x0003, 0x8114},
-/* 322 */ {0x0080, 0x8804},
-
-/* 355 */ {0x0003, 0x8801},
-/* 356 */ {0x0012, 0x8800},
-/* 358 */ {0x0004, 0x8801},
-/* 359 */ {0x0005, 0x8800},
-/* 361 */ {0x0005, 0x8801},
-/* 362 */ {0x0047, 0x8800},
-/* 364 */ {0x0006, 0x8801},
-/* 365 */ {0x0000, 0x8800},
-/* 367 */ {0x0007, 0x8801},
-/* 368 */ {0x00c0, 0x8800},
-/* 370 */ {0x0008, 0x8801},
-/* 371 */ {0x0003, 0x8800},
-/* 373 */ {0x000a, 0x8700},
-/* 374 */ {0x000e, 0x8801},
-/* 375 */ {0x0004, 0x8800},
-/* 377 */ {0x0005, 0x8801},
-/* 378 */ {0x0047, 0x8800},
-/* 380 */ {0x0006, 0x8801},
-/* 381 */ {0x0000, 0x8800},
-/* 383 */ {0x0007, 0x8801},
-/* 384 */ {0x00c0, 0x8800},
-/* 386 */ {0x0008, 0x8801},
-/* 387 */ {0x0003, 0x8800},
-/* 389 */ {0x0013, 0x8801},
-/* 390 */ {0x0001, 0x8800},
-/* 392 */ {0x0009, 0x8801},
-/* 393 */ {0x0000, 0x8800},
-/* 395 */ {0x000a, 0x8801},
-/* 396 */ {0x0000, 0x8800},
-/* 398 */ {0x000b, 0x8801},
-/* 399 */ {0x0000, 0x8800},
-/* 401 */ {0x000c, 0x8801},
-/* 402 */ {0x0000, 0x8800},
-/* 404 */ {0x000e, 0x8801},
-/* 405 */ {0x0004, 0x8800},
-/* 407 */ {0x000f, 0x8801},
-/* 408 */ {0x0000, 0x8800},
-/* 410 */ {0x0010, 0x8801},
-/* 411 */ {0x0006, 0x8800},
-/* 413 */ {0x0011, 0x8801},
-/* 414 */ {0x0006, 0x8800},
-/* 416 */ {0x0012, 0x8801},
-/* 417 */ {0x0000, 0x8800},
-/* 419 */ {0x0013, 0x8801},
-/* 420 */ {0x0001, 0x8800},
-/* 422 */ {0x000a, 0x8700},
-/* 423 */ {0x0000, 0x8702},
-/* 424 */ {0x0000, 0x8703},
-/* 425 */ {0x00c2, 0x8704},
-/* 426 */ {0x0001, 0x870c},
-/* 427 */ {0x0044, 0x8600},
-/* 428 */ {0x0002, 0x8606},
-/* 429 */ {0x0064, 0x8607},
-/* 430 */ {0x003a, 0x8601},
-/* 431 */ {0x0008, 0x8602},
-/* 432 */ {0x0044, 0x8600},
-/* 433 */ {0x0018, 0x8617},
-/* 434 */ {0x0008, 0x8618},
-/* 435 */ {0x00a1, 0x8656},
-/* 436 */ {0x0004, 0x865b},
-/* 437 */ {0x0002, 0x865c},
-/* 438 */ {0x0058, 0x865d},
-/* 439 */ {0x0048, 0x865e},
-/* 440 */ {0x0012, 0x8608},
-/* 441 */ {0x002c, 0x8609},
-/* 442 */ {0x0002, 0x860a},
-/* 443 */ {0x002c, 0x860b},
-/* 444 */ {0x00db, 0x860c},
-/* 445 */ {0x00f9, 0x860d},
-/* 446 */ {0x00f1, 0x860e},
-/* 447 */ {0x00e3, 0x860f},
-/* 448 */ {0x002c, 0x8610},
-/* 449 */ {0x006c, 0x8651},
-/* 450 */ {0x0041, 0x8652},
-/* 451 */ {0x0059, 0x8653},
-/* 452 */ {0x0040, 0x8654},
-/* 453 */ {0x00fa, 0x8611},
-/* 454 */ {0x00ff, 0x8612},
-/* 455 */ {0x00f8, 0x8613},
-/* 456 */ {0x0000, 0x8614},
-/* 457 */ {0x0001, 0x863f},
-/* 458 */ {0x0000, 0x8640},
-/* 459 */ {0x0026, 0x8641},
-/* 460 */ {0x0045, 0x8642},
-/* 461 */ {0x0060, 0x8643},
-/* 462 */ {0x0075, 0x8644},
-/* 463 */ {0x0088, 0x8645},
-/* 464 */ {0x009b, 0x8646},
-/* 465 */ {0x00b0, 0x8647},
-/* 466 */ {0x00c5, 0x8648},
-/* 467 */ {0x00d2, 0x8649},
-/* 468 */ {0x00dc, 0x864a},
-/* 469 */ {0x00e5, 0x864b},
-/* 470 */ {0x00eb, 0x864c},
-/* 471 */ {0x00f0, 0x864d},
-/* 472 */ {0x00f6, 0x864e},
-/* 473 */ {0x00fa, 0x864f},
-/* 474 */ {0x00ff, 0x8650},
-/* 475 */ {0x0060, 0x8657},
-/* 476 */ {0x0010, 0x8658},
-/* 477 */ {0x0018, 0x8659},
-/* 478 */ {0x0005, 0x865a},
-/* 479 */ {0x0018, 0x8660},
-/* 480 */ {0x0003, 0x8509},
-/* 481 */ {0x0011, 0x850a},
-/* 482 */ {0x0032, 0x850b},
-/* 483 */ {0x0010, 0x850c},
-/* 484 */ {0x0021, 0x850d},
-/* 485 */ {0x0001, 0x8500},
-/* 486 */ {0x0000, 0x8508},
-
-/* 487 */ {0x0012, 0x8608},
-/* 488 */ {0x002c, 0x8609},
-/* 489 */ {0x0002, 0x860a},
-/* 490 */ {0x0039, 0x860b},
-/* 491 */ {0x00d0, 0x860c},
-/* 492 */ {0x00f7, 0x860d},
-/* 493 */ {0x00ed, 0x860e},
-/* 494 */ {0x00db, 0x860f},
-/* 495 */ {0x0039, 0x8610},
-/* 496 */ {0x0012, 0x8657},
-/* 497 */ {0x0064, 0x8619},
+	{0x0020, 0x8112},
+
+	{0x000f, 0x8402},
+	{0x0000, 0x8403},
+
+	{0x0008, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x0009, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000a, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000b, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000c, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000d, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000e, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x0007, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x000f, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+
+	{0x0018, 0x8660},
+	{0x0010, 0x8201},
+
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x0011, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+
+	{0x0000, 0x86b0},
+	{0x0034, 0x86b1},
+	{0x0000, 0x86b2},
+	{0x0049, 0x86b3},
+	{0x0000, 0x86b4},
+	{0x0000, 0x86b4},
+
+	{0x0012, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+	{0x0013, 0x8201},
+	{0x0008, 0x8200},
+	{0x0001, 0x8200},
+
+	{0x0001, 0x86b0},
+	{0x00aa, 0x86b1},
+	{0x0000, 0x86b2},
+	{0x00e4, 0x86b3},
+	{0x0000, 0x86b4},
+	{0x0000, 0x86b4},
+
+	{0x0018, 0x8660},
+
+	{0x0090, 0x8110},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0003, 0x8114},
+
+	{0x0080, 0x8804},
+	{0x0003, 0x8801},
+	{0x0012, 0x8800},
+	{0x0004, 0x8801},
+	{0x0005, 0x8800},
+	{0x0005, 0x8801},
+	{0x0000, 0x8800},
+	{0x0006, 0x8801},
+	{0x0000, 0x8800},
+	{0x0007, 0x8801},
+	{0x0000, 0x8800},
+	{0x0008, 0x8801},
+	{0x0005, 0x8800},
+	{0x000a, 0x8700},
+	{0x000e, 0x8801},
+	{0x0004, 0x8800},
+	{0x0005, 0x8801},
+	{0x0047, 0x8800},
+	{0x0006, 0x8801},
+	{0x0000, 0x8800},
+	{0x0007, 0x8801},
+	{0x00c0, 0x8800},
+	{0x0008, 0x8801},
+	{0x0003, 0x8800},
+	{0x0013, 0x8801},
+	{0x0001, 0x8800},
+	{0x0009, 0x8801},
+	{0x0000, 0x8800},
+	{0x000a, 0x8801},
+	{0x0000, 0x8800},
+	{0x000b, 0x8801},
+	{0x0000, 0x8800},
+	{0x000c, 0x8801},
+	{0x0000, 0x8800},
+	{0x000e, 0x8801},
+	{0x0004, 0x8800},
+	{0x000f, 0x8801},
+	{0x0000, 0x8800},
+	{0x0010, 0x8801},
+	{0x0006, 0x8800},
+	{0x0011, 0x8801},
+	{0x0006, 0x8800},
+	{0x0012, 0x8801},
+	{0x0000, 0x8800},
+	{0x0013, 0x8801},
+	{0x0001, 0x8800},
+
+	{0x000a, 0x8700},
+	{0x0000, 0x8702},
+	{0x0000, 0x8703},
+	{0x00c2, 0x8704},
+	{0x0001, 0x870c},
+
+	{0x0044, 0x8600},
+	{0x0002, 0x8606},
+	{0x0064, 0x8607},
+	{0x003a, 0x8601},
+	{0x0008, 0x8602},
+	{0x0044, 0x8600},
+	{0x0018, 0x8617},
+	{0x0008, 0x8618},
+	{0x00a1, 0x8656},
+	{0x0004, 0x865b},
+	{0x0002, 0x865c},
+	{0x0058, 0x865d},
+	{0x0048, 0x865e},
+	{0x0012, 0x8608},
+	{0x002c, 0x8609},
+	{0x0002, 0x860a},
+	{0x002c, 0x860b},
+	{0x00db, 0x860c},
+	{0x00f9, 0x860d},
+	{0x00f1, 0x860e},
+	{0x00e3, 0x860f},
+	{0x002c, 0x8610},
+	{0x006c, 0x8651},
+	{0x0041, 0x8652},
+	{0x0059, 0x8653},
+	{0x0040, 0x8654},
+	{0x00fa, 0x8611},
+	{0x00ff, 0x8612},
+	{0x00f8, 0x8613},
+	{0x0000, 0x8614},
+	{0x0001, 0x863f},
+	{0x0000, 0x8640},
+	{0x0026, 0x8641},
+	{0x0045, 0x8642},
+	{0x0060, 0x8643},
+	{0x0075, 0x8644},
+	{0x0088, 0x8645},
+	{0x009b, 0x8646},
+	{0x00b0, 0x8647},
+	{0x00c5, 0x8648},
+	{0x00d2, 0x8649},
+	{0x00dc, 0x864a},
+	{0x00e5, 0x864b},
+	{0x00eb, 0x864c},
+	{0x00f0, 0x864d},
+	{0x00f6, 0x864e},
+	{0x00fa, 0x864f},
+	{0x00ff, 0x8650},
+	{0x0060, 0x8657},
+	{0x0010, 0x8658},
+	{0x0018, 0x8659},
+	{0x0005, 0x865a},
+	{0x0018, 0x8660},
+	{0x0003, 0x8509},
+	{0x0011, 0x850a},
+	{0x0032, 0x850b},
+	{0x0010, 0x850c},
+	{0x0021, 0x850d},
+	{0x0001, 0x8500},
+	{0x0000, 0x8508},
+	{0x0012, 0x8608},
+	{0x002c, 0x8609},
+	{0x0002, 0x860a},
+	{0x0039, 0x860b},
+	{0x00d0, 0x860c},
+	{0x00f7, 0x860d},
+	{0x00ed, 0x860e},
+	{0x00db, 0x860f},
+	{0x0039, 0x8610},
+	{0x0012, 0x8657},
+	{0x000c, 0x8619},
+	{0x0004, 0x861a},
+	{0x00a1, 0x8656},
+	{0x00c8, 0x8615},
+	{0x0032, 0x8616},
+
+	{0x0030, 0x8112},
+	{0x0020, 0x8112},
+	{0x0020, 0x8112},
+	{0x000f, 0x8402},
+	{0x0000, 0x8403},
+
+	{0x0090, 0x8110},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0001, 0x8114},
+	{0x0003, 0x8114},
+	{0x0080, 0x8804},
+
+	{0x0003, 0x8801},
+	{0x0012, 0x8800},
+	{0x0004, 0x8801},
+	{0x0005, 0x8800},
+	{0x0005, 0x8801},
+	{0x0047, 0x8800},
+	{0x0006, 0x8801},
+	{0x0000, 0x8800},
+	{0x0007, 0x8801},
+	{0x00c0, 0x8800},
+	{0x0008, 0x8801},
+	{0x0003, 0x8800},
+	{0x000a, 0x8700},
+	{0x000e, 0x8801},
+	{0x0004, 0x8800},
+	{0x0005, 0x8801},
+	{0x0047, 0x8800},
+	{0x0006, 0x8801},
+	{0x0000, 0x8800},
+	{0x0007, 0x8801},
+	{0x00c0, 0x8800},
+	{0x0008, 0x8801},
+	{0x0003, 0x8800},
+	{0x0013, 0x8801},
+	{0x0001, 0x8800},
+	{0x0009, 0x8801},
+	{0x0000, 0x8800},
+	{0x000a, 0x8801},
+	{0x0000, 0x8800},
+	{0x000b, 0x8801},
+	{0x0000, 0x8800},
+	{0x000c, 0x8801},
+	{0x0000, 0x8800},
+	{0x000e, 0x8801},
+	{0x0004, 0x8800},
+	{0x000f, 0x8801},
+	{0x0000, 0x8800},
+	{0x0010, 0x8801},
+	{0x0006, 0x8800},
+	{0x0011, 0x8801},
+	{0x0006, 0x8800},
+	{0x0012, 0x8801},
+	{0x0000, 0x8800},
+	{0x0013, 0x8801},
+	{0x0001, 0x8800},
+	{0x000a, 0x8700},
+	{0x0000, 0x8702},
+	{0x0000, 0x8703},
+	{0x00c2, 0x8704},
+	{0x0001, 0x870c},
+	{0x0044, 0x8600},
+	{0x0002, 0x8606},
+	{0x0064, 0x8607},
+	{0x003a, 0x8601},
+	{0x0008, 0x8602},
+	{0x0044, 0x8600},
+	{0x0018, 0x8617},
+	{0x0008, 0x8618},
+	{0x00a1, 0x8656},
+	{0x0004, 0x865b},
+	{0x0002, 0x865c},
+	{0x0058, 0x865d},
+	{0x0048, 0x865e},
+	{0x0012, 0x8608},
+	{0x002c, 0x8609},
+	{0x0002, 0x860a},
+	{0x002c, 0x860b},
+	{0x00db, 0x860c},
+	{0x00f9, 0x860d},
+	{0x00f1, 0x860e},
+	{0x00e3, 0x860f},
+	{0x002c, 0x8610},
+	{0x006c, 0x8651},
+	{0x0041, 0x8652},
+	{0x0059, 0x8653},
+	{0x0040, 0x8654},
+	{0x00fa, 0x8611},
+	{0x00ff, 0x8612},
+	{0x00f8, 0x8613},
+	{0x0000, 0x8614},
+	{0x0001, 0x863f},
+	{0x0000, 0x8640},
+	{0x0026, 0x8641},
+	{0x0045, 0x8642},
+	{0x0060, 0x8643},
+	{0x0075, 0x8644},
+	{0x0088, 0x8645},
+	{0x009b, 0x8646},
+	{0x00b0, 0x8647},
+	{0x00c5, 0x8648},
+	{0x00d2, 0x8649},
+	{0x00dc, 0x864a},
+	{0x00e5, 0x864b},
+	{0x00eb, 0x864c},
+	{0x00f0, 0x864d},
+	{0x00f6, 0x864e},
+	{0x00fa, 0x864f},
+	{0x00ff, 0x8650},
+	{0x0060, 0x8657},
+	{0x0010, 0x8658},
+	{0x0018, 0x8659},
+	{0x0005, 0x865a},
+	{0x0018, 0x8660},
+	{0x0003, 0x8509},
+	{0x0011, 0x850a},
+	{0x0032, 0x850b},
+	{0x0010, 0x850c},
+	{0x0021, 0x850d},
+	{0x0001, 0x8500},
+	{0x0000, 0x8508},
+
+	{0x0012, 0x8608},
+	{0x002c, 0x8609},
+	{0x0002, 0x860a},
+	{0x0039, 0x860b},
+	{0x00d0, 0x860c},
+	{0x00f7, 0x860d},
+	{0x00ed, 0x860e},
+	{0x00db, 0x860f},
+	{0x0039, 0x8610},
+	{0x0012, 0x8657},
+	{0x0064, 0x8619},
 
 /* This line starts it all, it is not needed here */
 /* since it has been build into the driver */
 /* jfm: don't start now */
-/* 590  *  {0x0030, 0x8112}, */
+/*	{0x0030, 0x8112}, */
 	{}
 };
 
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = {
 	{0x0008, 0x8200},	/* Clear register */
 	{0x0000, 0x870b},	/* Reset CTL3 */
 	{0x0020, 0x8112},	/* Video Drop packet enable */
-	{0x0003, 0x8111},  /* Soft Reset compression, memory, TG & CDSP */
+	{0x0003, 0x8111},	/* Soft Reset compression, memory, TG & CDSP */
 	{0x0000, 0x8110},	/* Disable everything */
 	{0x0000, 0x8114},	/* Software GPIO output data */
 	{0x0000, 0x8114},
 
 	{0x0003, 0x8111},
 	{0x0000, 0x8111},
-	{0x0090, 0x8110},  /* Enable: SSI output, External 2X clock output */
+	{0x0090, 0x8110},    /* Enable: SSI output, External 2X clock output */
 	{0x0020, 0x8112},
 	{0x0000, 0x8114},
 	{0x0001, 0x8114},
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = {
 	{0x00ba, 0x8804},	/* SSI Slave address */
 	{0x0010, 0x8802},	/* 93.75kHz SSI Clock Two DataByte */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},	/* Will write 2 bytes (DATA1+DATA2) */
 	{0x0020, 0x8801},	/* Register address for SSI read/write */
 	{0x0044, 0x8805},	/* DATA2 */
 	{0x0004, 0x8800},	/* DATA1 -> write triggered */
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0009, 0x8801},
 	{0x0042, 0x8805},
 	{0x0001, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x003c, 0x8801},
 	{0x0001, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0001, 0x8801},
 	{0x000a, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0002, 0x8801},
 	{0x0000, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0003, 0x8801},
 	{0x0027, 0x8805},
 	{0x0001, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0004, 0x8801},
 	{0x0065, 0x8805},
 	{0x0001, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0005, 0x8801},
 	{0x0003, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0006, 0x8801},
 	{0x001c, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0007, 0x8801},
 	{0x002a, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x000e, 0x8801},
 	{0x0000, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0028, 0x8801},
 	{0x002e, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0039, 0x8801},
 	{0x0013, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x003b, 0x8801},
 	{0x000c, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0035, 0x8801},
 	{0x0028, 0x8805},
 	{0x0000, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
-	/* READ { 0, 0x0001, 0x8802 } ->
-		0000: 10  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
+	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
 	{0x0010, 0x8802},
 	{0x0009, 0x8801},
 	{0x0042, 0x8805},
 	{0x0001, 0x8800},
-	/* READ { 0, 0x0001, 0x8803 } ->
-		0000: 00  */
+	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
 
 	{0x0050, 0x8703},
 	{0x0002, 0x8704},	/* External input CKIx1 */
 	{0x0001, 0x870c},	/* Select CKOx2 output */
 	{0x009a, 0x8600},	/* Line memory Read Counter (L) */
-	{0x0001, 0x8606},  /* 1 Line memory Read Counter (H) Result: (d)410 */
+	{0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
 	{0x0023, 0x8601},
 	{0x0010, 0x8602},
 	{0x000a, 0x8603},
-	{0x009A, 0x8600},
+	{0x009a, 0x8600},
 	{0x0001, 0x865b},	/* 1 Horizontal Offset for Valid Pixel(L) */
 	{0x0003, 0x865c},	/* Vertical offset for valid lines (L) */
 	{0x0058, 0x865d},	/* Horizontal valid pixels window (L) */
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = {
 	{0x0005, 0x860a},	/* ... */
 	{0x0025, 0x860b},
 	{0x00e1, 0x860c},
-	{0x00fa, 0x860D},
+	{0x00fa, 0x860d},
 	{0x00f4, 0x860e},
 	{0x00e8, 0x860f},
 	{0x0025, 0x8610},	/* A33 Coef. */
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = {
 	{0x0040, 0x8654},	/* Gb gain for white balance (L) */
 	{0x0001, 0x863f},	/* Enable fixed gamma correction */
 
-	{0x00a1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128 */
-	/* UV division: UV no change, Enable New edge enhancement */
+	{0x00a1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128,
+				 * UV division: UV no change,
+				 * Enable New edge enhancement */
 	{0x0018, 0x8657},	/* Edge gain high threshold */
 	{0x0020, 0x8658},	/* Edge gain low threshold */
-	{0x000A, 0x8659},	/* Edge bandwidth high threshold */
+	{0x000a, 0x8659},	/* Edge bandwidth high threshold */
 	{0x0005, 0x865a},	/* Edge bandwidth low threshold */
 	{0x0064, 0x8607},	/* UV filter enable */
 
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = {
 	{0x0000, 0x86b4},
 	{0x001e, 0x8660},
 
-	/* READ { 0, 0x0000, 0x8608 } ->
-		0000: 13  */
-	/* READ { 0, 0x0000, 0x8609 } ->
-		0000: 28  */
-	/* READ { 0, 0x0000, 0x8610 } ->
-		0000: 05  */
-	/* READ { 0, 0x0000, 0x8611 } ->
-		0000: 25  */
-	/* READ { 0, 0x0000, 0x8612 } ->
-		0000: e1  */
-	/* READ { 0, 0x0000, 0x8613 } ->
-		0000: fa  */
-	/* READ { 0, 0x0000, 0x8614 } ->
-		0000: f4  */
-	/* READ { 0, 0x0000, 0x8615 } ->
-		0000: e8  */
-	/* READ { 0, 0x0000, 0x8616 } ->
-		0000: 25  */
+	/* READ { 0x0000, 0x8608 } -> 0000: 13  */
+	/* READ { 0x0000, 0x8609 } -> 0000: 28  */
+	/* READ { 0x0000, 0x8610 } -> 0000: 05  */
+	/* READ { 0x0000, 0x8611 } -> 0000: 25  */
+	/* READ { 0x0000, 0x8612 } -> 0000: e1  */
+	/* READ { 0x0000, 0x8613 } -> 0000: fa  */
+	/* READ { 0x0000, 0x8614 } -> 0000: f4  */
+	/* READ { 0x0000, 0x8615 } -> 0000: e8  */
+	/* READ { 0x0000, 0x8616 } -> 0000: 25  */
 	{}
 };
 
 static int reg_write(struct usb_device *dev,
-			__u16 index, __u16 value)
+			u16 index, u16 value)
 {
 	int ret;
 
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev,
 /* read 1 byte */
 /* returns: negative is error, pos or zero is data */
 static int reg_read(struct gspca_dev *gspca_dev,
-			__u16 index)	/* wIndex */
+			u16 index)	/* wIndex */
 {
 	int ret;
 
@@ -1521,7 +1379,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-/*	write_vector(gspca_dev, spca508_open_data); */
 	return 0;
 }
 
@@ -1529,7 +1386,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 {
 	int mode;
 
-	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	reg_write(gspca_dev->dev, 0x8500, mode);
 	switch (mode) {
 	case 0:
@@ -1554,7 +1411,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
@@ -1567,7 +1424,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 				data, len);
 		break;
 	case 0xff:			/* drop */
-/*		gspca_dev->last_packet_type = DISCARD_PACKET; */
 		break;
 	default:
 		data += 1;
@@ -1581,7 +1437,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 brightness = sd->brightness;
+	u8 brightness = sd->brightness;
 
 	/* MX seem contrast */
 	reg_write(gspca_dev->dev, 0x8651, brightness);
-- 
cgit v1.2.3-70-g09d2


From 7880f6613814e737de829911b204d7bc1f2ccb49 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Wed, 13 May 2009 14:25:29 -0300
Subject: V4L/DVB (11868): gspca - spca508: Optimize code.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca508.c | 46 +++++++++++++------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 5896bfe2ffd..2ed2669bac3 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1305,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev,
 }
 
 static int write_vector(struct gspca_dev *gspca_dev,
-			const u16 data[][2])
+			const u16 (*data)[2])
 {
 	struct usb_device *dev = gspca_dev->dev;
-	int ret, i = 0;
+	int ret;
 
-	while (data[i][1] != 0) {
-		ret = reg_write(dev, data[i][1], data[i][0]);
+	while ((*data)[1] != 0) {
+		ret = reg_write(dev, (*data)[1], (*data)[0]);
 		if (ret < 0)
 			return ret;
-		i++;
+		data++;
 	}
 	return 0;
 }
@@ -1326,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 	int data1, data2;
+	const u16 (*init_data)[2];
+	static const u16 (*(init_data_tb[]))[2] = {
+		spca508_vista_init_data,	/* CreativeVista 0 */
+		spca508_sightcam_init_data,	/* HamaUSBSightcam 1 */
+		spca508_sightcam2_init_data,	/* HamaUSBSightcam2 2 */
+		spca508cs110_init_data,		/* IntelEasyPCCamera 3 */
+		spca508cs110_init_data,		/* MicroInnovationIC200 4 */
+		spca508_init_data,		/* ViewQuestVQ110 5 */
+	};
 
 	/* Read from global register the USB product and vendor IDs, just to
 	 * prove that we can communicate with the device.  This works, which
@@ -1349,31 +1358,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->subtype = id->driver_info;
 	sd->brightness = BRIGHTNESS_DEF;
 
-	switch (sd->subtype) {
-	case ViewQuestVQ110:
-		if (write_vector(gspca_dev, spca508_init_data))
-			return -1;
-		break;
-	default:
-/*	case MicroInnovationIC200: */
-/*	case IntelEasyPCCamera: */
-		if (write_vector(gspca_dev, spca508cs110_init_data))
-			return -1;
-		break;
-	case HamaUSBSightcam:
-		if (write_vector(gspca_dev, spca508_sightcam_init_data))
-			return -1;
-		break;
-	case HamaUSBSightcam2:
-		if (write_vector(gspca_dev, spca508_sightcam2_init_data))
-			return -1;
-		break;
-	case CreativeVista:
-		if (write_vector(gspca_dev, spca508_vista_init_data))
-			return -1;
-		break;
-	}
-	return 0;			/* success */
+	init_data = init_data_tb[sd->subtype];
+	return write_vector(gspca_dev, init_data);
 }
 
 /* this function is called at probe and resume time */
-- 
cgit v1.2.3-70-g09d2


From 191d0e7fba43d79a73605adcf85441ebe0a2aff7 Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Fri, 22 May 2009 04:16:42 -0300
Subject: V4L/DVB (11869): gspca - ov534: JPEG 320x240 and 640x480 formats for
 ov965x.

The YUYV 640x480 format did not work with ov965x.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov534.c | 245 +++++++++++++++++++++++++++-----------
 1 file changed, 176 insertions(+), 69 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 6d9b102be70..8d2164db3d6 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -60,10 +60,23 @@ struct sd {
 static struct ctrl sd_ctrls[] = {
 };
 
-static const struct v4l2_pix_format vga_mode[] = {
+static const struct v4l2_pix_format vga_yuyv_mode[] = {
 	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 	 .bytesperline = 640 * 2,
 	 .sizeimage = 640 * 480 * 2,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = 0},
+};
+
+static const struct v4l2_pix_format vga_jpeg_mode[] = {
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 320,
+	 .sizeimage = 320 * 240 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 1},
+	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 640,
+	 .sizeimage = 640 * 480 * 3 / 8 + 590,
 	 .colorspace = V4L2_COLORSPACE_JPEG,
 	 .priv = 0},
 };
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = {
 };
 
 static const u8 sensor_init_ov965x[][2] = {
-	{0x12, 0x80},	/* com7 - reset */
+	{0x12, 0x80},	/* com7 - SSCB reset */
 	{0x00, 0x00},	/* gain */
 	{0x01, 0x80},	/* blue */
 	{0x02, 0x80},	/* red */
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x0e, 0x61},	/* com5 */
 	{0x0f, 0x42},	/* com6 */
 	{0x11, 0x00},	/* clkrc */
-	{0x12, 0x02},	/* com7 */
+	{0x12, 0x02},	/* com7 - 15fps VGA YUYV */
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 	{0x14, 0x28},	/* com9 */
-	{0x16, 0x24},	/* rsvd16 */
+	{0x16, 0x24},	/* reg16 */
 	{0x17, 0x1d},	/* hstart*/
 	{0x18, 0xbd},	/* hstop */
 	{0x19, 0x01},	/* vstrt */
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x27, 0x08},	/* bbias */
 	{0x28, 0x08},	/* gbbias */
 	{0x29, 0x15},	/* gr com */
-	{0x2a, 0x00},
-	{0x2b, 0x00},
+	{0x2a, 0x00},	/* exhch */
+	{0x2b, 0x00},	/* exhcl */
 	{0x2c, 0x08},	/* rbias */
 	{0x32, 0xff},	/* href */
 	{0x33, 0x00},	/* chlf */
-	{0x34, 0x3f},	/* arblm */
-	{0x35, 0x00},	/* rsvd35 */
-	{0x36, 0xf8},	/* rsvd36 */
-	{0x38, 0x72},	/* acom38 */
-	{0x39, 0x57},	/* ofon */
-	{0x3a, 0x80},	/* tslb */
-	{0x3b, 0xc4},
+	{0x34, 0x3f},	/* aref1 */
+	{0x35, 0x00},	/* aref2 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x38, 0x72},	/* adc2 */
+	{0x39, 0x57},	/* aref4 */
+	{0x3a, 0x80},	/* tslb - yuyv */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
 	{0x3d, 0x99},	/* com13 */
-	{0x3f, 0xc1},
+	{0x3f, 0xc1},	/* edge */
 	{0x40, 0xc0},	/* com15 */
 	{0x41, 0x40},	/* com16 */
-	{0x42, 0xc0},
-	{0x43, 0x0a},
+	{0x42, 0xc0},	/* com17 */
+	{0x43, 0x0a},	/* rsvd */
 	{0x44, 0xf0},
 	{0x45, 0x46},
 	{0x46, 0x62},
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x4c, 0x7f},
 	{0x4d, 0x7f},
 	{0x4e, 0x7f},
-	{0x4f, 0x98},
+	{0x4f, 0x98},	/* matrix */
 	{0x50, 0x98},
 	{0x51, 0x00},
 	{0x52, 0x28},
 	{0x53, 0x70},
 	{0x54, 0x98},
-	{0x58, 0x1a},
-	{0x59, 0x85},
+	{0x58, 0x1a},	/* matrix coef sign */
+	{0x59, 0x85},	/* AWB control */
 	{0x5a, 0xa9},
 	{0x5b, 0x64},
 	{0x5c, 0x84},
 	{0x5d, 0x53},
 	{0x5e, 0x0e},
-	{0x5f, 0xf0},
-	{0x60, 0xf0},
-	{0x61, 0xf0},
+	{0x5f, 0xf0},	/* AWB blue limit */
+	{0x60, 0xf0},	/* AWB red limit */
+	{0x61, 0xf0},	/* AWB green limit */
 	{0x62, 0x00},	/* lcc1 */
 	{0x63, 0x00},	/* lcc2 */
 	{0x64, 0x02},	/* lcc3 */
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x6d, 0x55},
 	{0x6e, 0x00},
 	{0x6f, 0x9d},
-	{0x70, 0x21},
+	{0x70, 0x21},	/* dnsth */
 	{0x71, 0x78},
-	{0x72, 0x00},
-	{0x73, 0x01},
-	{0x74, 0x3a},
-	{0x75, 0x35},
+	{0x72, 0x00},	/* poidx */
+	{0x73, 0x01},	/* pckdv */
+	{0x74, 0x3a},	/* xindx */
+	{0x75, 0x35},	/* yindx */
 	{0x76, 0x01},
 	{0x77, 0x02},
-	{0x7a, 0x12},
+	{0x7a, 0x12},	/* gamma curve */
 	{0x7b, 0x08},
 	{0x7c, 0x16},
 	{0x7d, 0x30},
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x88, 0xe6},
 	{0x89, 0xf2},
 	{0x8a, 0x03},
-	{0x8c, 0x89},
+	{0x8c, 0x89},	/* com19 */
 	{0x14, 0x28},	/* com9 */
 	{0x90, 0x7d},
 	{0x91, 0x7b},
-	{0x9d, 0x03},
-	{0x9e, 0x04},
+	{0x9d, 0x03},	/* lcc6 */
+	{0x9e, 0x04},	/* lcc7 */
 	{0x9f, 0x7a},
 	{0xa0, 0x79},
 	{0xa1, 0x40},	/* aechm */
-	{0xa4, 0x50},
+	{0xa4, 0x50},	/* com21 */
 	{0xa5, 0x68},	/* com26 */
-	{0xa6, 0x4a},
-	{0xa8, 0xc1},	/* acoma8 */
-	{0xa9, 0xef},	/* acoma9 */
+	{0xa6, 0x4a},	/* AWB green */
+	{0xa8, 0xc1},	/* refa8 */
+	{0xa9, 0xef},	/* refa9 */
 	{0xaa, 0x92},
 	{0xab, 0x04},
-	{0xac, 0x80},
+	{0xac, 0x80},	/* black level control */
 	{0xad, 0x80},
 	{0xae, 0x80},
 	{0xaf, 0x80},
 	{0xb2, 0xf2},
 	{0xb3, 0x20},
-	{0xb4, 0x20},
+	{0xb4, 0x20},	/* ctrlb4 */
 	{0xb5, 0x00},
 	{0xb6, 0xaf},
 	{0xbb, 0xae},
-	{0xbc, 0x7f},
+	{0xbc, 0x7f},	/* ADC channel offsets */
 	{0xdb, 0x7f},
 	{0xbe, 0x7f},
 	{0xbf, 0x7f},
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0xc2, 0x01},
 	{0xc3, 0x4e},
 	{0xc6, 0x85},
-	{0xc7, 0x80},
+	{0xc7, 0x80},	/* com24 */
 	{0xc9, 0xe0},
 	{0xca, 0xe8},
 	{0xcb, 0xf0},
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = {
 	{0x58, 0x1a},
 	{0xff, 0x41},	/* read 41, write ff 00 */
 	{0x41, 0x40},	/* com16 */
-	{0xc5, 0x03},
-	{0x6a, 0x02},
+	{0xc5, 0x03},	/* 60 Hz banding filter */
+	{0x6a, 0x02},	/* 50 Hz banding filter */
 
-	{0x12, 0x62},	/* com7 - VGA + CIF */
-	{0x36, 0xfa},	/* rsvd36 */
+	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
+	{0x36, 0xfa},	/* aref3 */
 	{0x69, 0x0a},	/* hv */
 	{0x8c, 0x89},	/* com22 */
 	{0x14, 0x28},	/* com9 */
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
 	{0x52, 0x3c},
 	{0x53, 0x00},
 	{0x54, 0x00},
-	{0x55, 0x00},
-	{0x57, 0x00},
+	{0x55, 0x00},	/* brightness */
+	{0x57, 0x00},	/* contrast 2 */
 	{0x5c, 0x00},
 	{0x5a, 0xa0},
 	{0x5b, 0x78},
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = {
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 };
 
+static const u8 sensor_start_ov965x[][2] = {
+	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
+	{0x36, 0xfa},	/* aref3 */
+	{0x69, 0x0a},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x00},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x12},	/* vref */
+	{0x17, 0x16},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x3d},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xaa},
+	{}
+};
+
 static const u8 bridge_start_ov965x[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{}
+};
+
+static const u8 bridge_start_ov965x_vga[][2] = {
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x01},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x3c},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0xa0},
+	{0x5b, 0x78},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+	{}
+};
+
+static const u8 bridge_start_ov965x_cif[][2] = {
 	{0xc2, 0x4c},
 	{0xc3, 0xf9},
+	{0xda, 0x00},
 	{0x50, 0x00},
 	{0x51, 0xa0},
 	{0x52, 0x78},
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = {
 	{0x55, 0x00},
 	{0x57, 0x00},
 	{0x5c, 0x00},
-	{0x5a, 0x28},
-	{0x5b, 0x1e},
-	{0x35, 0x00},
-	{0xd9, 0x21},
+	{0x5a, 0x50},
+	{0x5b, 0x3c},
+	{0x35, 0x02},
+	{0xd9, 0x10},
 	{0x94, 0x11},
+	{}
 };
 
-static const u8 sensor_start_ov965x[][2] = {
-	{0x3b, 0xe4},
+static const u8 sensor_start_ov965x_vga[][2] = {
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x03},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x05},	/* 50 Hz banding filter */
+	{0xc5, 0x07},	/* 60 Hz banding filter */
+	{0xa2, 0x4b},	/* bd50 */
+	{0xa3, 0x3e},	/* bd60 */
+
+	{0x2d, 0x00},	/* advfl */
+	{}
+};
+
+static const u8 sensor_start_ov965x_cif[][2] = {
+	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
 	{0x1e, 0x04},	/* mvfp */
 	{0x13, 0xe0},	/* com8 */
 	{0x00, 0x00},
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 	{0x11, 0x01},	/* clkrc */
 	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x02},
-	{0xc5, 0x03},
-	{0xa2, 0x96},
-	{0xa3, 0x7d},
+	{0x6a, 0x02},	/* 50 Hz banding filter */
+	{0xc5, 0x03},	/* 60 Hz banding filter */
+	{0xa2, 0x96},	/* bd50 */
+	{0xa3, 0x7d},	/* bd60 */
+
 	{0xff, 0x13},	/* read 13, write ff 00 */
 	{0x13, 0xe7},
-	{0x3a, 0x80},
+	{0x3a, 0x80},	/* tslb - yuyv */
+	{}
+};
+
+static const u8 sensor_start_ov965x_2[][2] = {
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},
+	{0x42, 0xc1},	/* com17 - 50 Hz filter */
+	{}
 };
 
 
@@ -705,13 +799,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 
-	cam->cam_mode = vga_mode;
-	cam->nmodes = ARRAY_SIZE(vga_mode);
-
 	if (sd->sensor == SENSOR_OV772X) {
+		cam->cam_mode = vga_yuyv_mode;
+		cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
+
 		cam->bulk = 1;
 		cam->bulk_size = 16384;
 		cam->bulk_nurbs = 2;
+	} else {		/* ov965x */
+		cam->cam_mode = vga_jpeg_mode;
+		cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
 	}
 
 	return 0;
@@ -781,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int mode;
 
 	switch (sd->sensor) {
 	case SENSOR_OV772X:
@@ -789,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		break;
 	default:
 /*	case SENSOR_OV965X: */
-		reg_w_array(gspca_dev, bridge_start_ov965x,
-				ARRAY_SIZE(bridge_start_ov965x));
+
 		sccb_w_array(gspca_dev, sensor_start_ov965x,
 				ARRAY_SIZE(sensor_start_ov965x));
+		reg_w_array(gspca_dev, bridge_start_ov965x,
+				ARRAY_SIZE(bridge_start_ov965x));
+		mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+		if (mode != 0) {	/* 320x240 */
+			reg_w_array(gspca_dev, bridge_start_ov965x_cif,
+					ARRAY_SIZE(bridge_start_ov965x_cif));
+			sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
+					ARRAY_SIZE(sensor_start_ov965x_cif));
+		} else {		/* 640x480 */
+			reg_w_array(gspca_dev, bridge_start_ov965x_vga,
+					ARRAY_SIZE(bridge_start_ov965x_vga));
+			sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
+					ARRAY_SIZE(sensor_start_ov965x_vga));
+		}
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2,
+				ARRAY_SIZE(sensor_start_ov965x_2));
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
 		ov534_reg_write(gspca_dev, 0xe0, 0x00);
 		ov534_set_led(gspca_dev, 1);
-/*fixme: other sensor start omitted*/
 	}
 	return 0;
 }
@@ -878,12 +991,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 		/* If this packet is marked as EOF, end the frame */
 		} else if (data[1] & UVC_STREAM_EOF) {
 			sd->last_pts = 0;
-
-			if (frame->data_end - frame->data !=
-			    gspca_dev->width * gspca_dev->height * 2) {
-				PDEBUG(D_PACK, "short frame");
-				goto discard;
-			}
 			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
 						data + 12, len - 12);
 		} else {
-- 
cgit v1.2.3-70-g09d2


From d0848eb2864c0f1ef52d586cd33c68a103b0a2ac Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 25 May 2009 15:20:16 -0300
Subject: V4L/DVB (11871): gspca - spca561: Change the Rev12a controls.

- Extend the gain range
- Adjust the exposure
- Remove the broken autogain

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca561.c | 77 +++++++++++++++----------------------
 1 file changed, 32 insertions(+), 45 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c99c5e34e21..6648ce7e96e 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -34,8 +34,8 @@ struct sd {
 
 	__u16 exposure;			/* rev12a only */
 #define EXPOSURE_MIN 1
-#define EXPOSURE_DEF 200
-#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
+#define EXPOSURE_DEF 700		/* == 10 fps */
+#define EXPOSURE_MAX (2047 + 325)	/* see setexposure */
 
 	__u8 contrast;			/* rev72a only */
 #define CONTRAST_MIN 0x00
@@ -58,9 +58,9 @@ struct sd {
 #define AUTOGAIN_MAX 1
 
 	__u8 gain;			/* rev12a only */
-#define GAIN_MIN 0x0
-#define GAIN_DEF 0x24
-#define GAIN_MAX 0x24
+#define GAIN_MIN 0
+#define GAIN_DEF 63
+#define GAIN_MAX 255
 
 #define EXPO12A_DEF 3
 	__u8 expo12a;		/* expo/gain? for rev 12a */
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int expo;
-	int clock_divider;
+	int i, expo = 0;
 
 	/* Register 0x8309 controls exposure for the spca561,
 	   the basic exposure setting goes from 1-2047, where 1 is completely
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev)
 	   configure a divider for the base framerate which us used at the
 	   exposure setting of 1-300. These bits configure the base framerate
 	   according to the following formula: fps = 60 / (value + 2) */
-	if (sd->exposure < 2048) {
-		expo = sd->exposure;
-		clock_divider = 0;
-	} else {
-		/* Add 900 to make the 0 setting of the second part of the
-		   exposure equal to the 2047 setting of the first part. */
-		expo = (sd->exposure - 2048) + 900;
-		clock_divider = 3;
+
+	/* We choose to use the high bits setting the fixed framerate divisor
+	   asap, as setting high basic exposure setting without the fixed
+	   divider in combination with high gains makes the cam stop */
+	int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
+
+	for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
+		if (sd->exposure <= table[i + 1]) {
+			expo  = sd->exposure - table[i];
+			if (i)
+				expo += 300;
+			expo |= i << 11;
+			break;
+		}
 	}
-	expo |= clock_divider << 11;
+
 	gspca_dev->usb_buf[0] = expo;
 	gspca_dev->usb_buf[1] = expo >> 8;
 	reg_w_buf(gspca_dev, 0x8309, 2);
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	gspca_dev->usb_buf[0] = sd->gain;
+	/* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
+	   sensitivity when set, so 31 + one of them set == 63, and 15
+	   with both of them set == 63 */
+	if (sd->gain < 64)
+		gspca_dev->usb_buf[0] = sd->gain;
+	else if (sd->gain < 128)
+		gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
+	else
+		gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
+
 	gspca_dev->usb_buf[1] = 0;
 	reg_w_buf(gspca_dev, 0x8335, 2);
 }
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
 	reg_w_buf(gspca_dev, 0x8391, 8);
 	reg_w_buf(gspca_dev, 0x8390, 8);
 	setwhite(gspca_dev);
-	setautogain(gspca_dev);
-/*	setgain(gspca_dev);		*/
+	setgain(gspca_dev);
 	setexposure(gspca_dev);
 	return 0;
 }
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
 		}
 		break;
-	case Rev012A:
-		reg_r(gspca_dev, 0x8330, 2);
-		if (gspca_dev->usb_buf[1] > 0x08) {
-			gspca_dev->usb_buf[0] = ++sd->expo12a;
-			gspca_dev->usb_buf[1] = 0;
-			reg_w_buf(gspca_dev, 0x8339, 2);
-		} else if (gspca_dev->usb_buf[1] < 0x02) {
-			gspca_dev->usb_buf[0] = --sd->expo12a;
-			gspca_dev->usb_buf[1] = 0;
-			reg_w_buf(gspca_dev, 0x8339, 2);
-		}
-		break;
 	}
 }
 
@@ -952,19 +953,6 @@ static struct ctrl sd_ctrls_12a[] = {
 	    .set = sd_setexposure,
 	    .get = sd_getexposure,
 	},
-	{
-	    {
-		.id = V4L2_CID_AUTOGAIN,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.name = "Auto Gain",
-		.minimum = AUTOGAIN_MIN,
-		.maximum = AUTOGAIN_MAX,
-		.step = 1,
-		.default_value = AUTOGAIN_DEF,
-	    },
-	    .set = sd_setautogain,
-	    .get = sd_getautogain,
-	},
 	{
 	    {
 		.id = V4L2_CID_GAIN,
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = {
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
-/*	.dq_callback = do_autogain,	 * fixme */
 };
 static const struct sd_desc sd_desc_72a = {
 	.name = MODULE_NAME,
-- 
cgit v1.2.3-70-g09d2


From 9035f2e27a99a7ea702973ab4fd47c0dd94a8c6e Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 25 May 2009 15:26:59 -0300
Subject: V4L/DVB (11872): gspca - spca561: Rename the 'White Balance' control
 to 'Hue'.

Binary files /home/v4l/tokernel/oldtree/Documentation/video4linux/v4lgrab.o and /home/v4l/tokernel/linux/Documentation/video4linux/v4lgrab.o differ

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca561.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 6648ce7e96e..27e82b35f3e 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -48,9 +48,9 @@ struct sd {
 #define BRIGHTNESS_MAX 0x3f
 
 	__u8 white;
-#define WHITE_MIN 1
-#define WHITE_DEF 0x40
-#define WHITE_MAX 0x7f
+#define HUE_MIN 1
+#define HUE_DEF 0x40
+#define HUE_MAX 0x7f
 
 	__u8 autogain;
 #define AUTOGAIN_MIN 0
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	}
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
-	sd->white = WHITE_DEF;
+	sd->white = HUE_DEF;
 	sd->exposure = EXPOSURE_DEF;
 	sd->autogain = AUTOGAIN_DEF;
 	sd->gain = GAIN_DEF;
@@ -929,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
 static struct ctrl sd_ctrls_12a[] = {
 	{
 	    {
-		.id = V4L2_CID_DO_WHITE_BALANCE,
+		.id = V4L2_CID_HUE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "White Balance",
-		.minimum = WHITE_MIN,
-		.maximum = WHITE_MAX,
+		.name = "Hue",
+		.minimum = HUE_MIN,
+		.maximum = HUE_MAX,
 		.step = 1,
-		.default_value = WHITE_DEF,
+		.default_value = HUE_DEF,
 	    },
 	    .set = sd_setwhite,
 	    .get = sd_getwhite,
@@ -971,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = {
 static struct ctrl sd_ctrls_72a[] = {
 	{
 	    {
-		.id = V4L2_CID_DO_WHITE_BALANCE,
+		.id = V4L2_CID_HUE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "White Balance",
-		.minimum = WHITE_MIN,
-		.maximum = WHITE_MAX,
+		.name = "Hue",
+		.minimum = HUE_MIN,
+		.maximum = HUE_MAX,
 		.step = 1,
-		.default_value = WHITE_DEF,
+		.default_value = HUE_DEF,
 	    },
 	    .set = sd_setwhite,
 	    .get = sd_getwhite,
-- 
cgit v1.2.3-70-g09d2


From 3047a17639d499691c657772667f2c1e65edabfb Mon Sep 17 00:00:00 2001
From: Miroslav Sustek <sustmidown@centrum.cz>
Date: Sun, 31 May 2009 16:47:28 -0300
Subject: V4L/DVB (11879): Adds support for Leadtek WinFast DTV-1800H

Enables analog/digital tv, radio and remote control (gpio).

Tested-by: Marcin Wojcikowski <emtees.mts@gmail.com>
Tested-by: Karel Juhanak <karel.juhanak@warnet.cz>
Tested-by: Andrew Goff <goffa72@gmail.com>
Tested-by: Jan Novak <novak-j@seznam.cz>
Signed-off-by: Miroslav Sustek <sustmidown@centrum.cz>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx88 |  1 +
 drivers/media/video/cx88/cx88-cards.c   | 75 +++++++++++++++++++++++++++++++++
 drivers/media/video/cx88/cx88-dvb.c     |  1 +
 drivers/media/video/cx88/cx88-input.c   |  2 +
 drivers/media/video/cx88/cx88.h         |  1 +
 5 files changed, 80 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 80527b292dd..89093f53172 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -79,3 +79,4 @@
  78 -> Prof 6200 DVB-S                                     [b022:3022]
  79 -> Terratec Cinergy HT PCI MKII                        [153b:1177]
  80 -> Hauppauge WinTV-IR Only                             [0070:9290]
+ 81 -> Leadtek WinFast DTV1800 Hybrid                      [107d:6654]
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index d2aa27e90ac..94b7a52629d 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1976,6 +1976,47 @@ static const struct cx88_board cx88_boards[] = {
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 	},
+	[CX88_BOARD_WINFAST_DTV1800H] = {
+		.name           = "Leadtek WinFast DTV1800 Hybrid",
+		.tuner_type     = TUNER_XC2028,
+		.radio_type     = TUNER_XC2028,
+		.tuner_addr     = 0x61,
+		.radio_addr     = 0x61,
+		/*
+		 * GPIO setting
+		 *
+		 *  2: mute (0=off,1=on)
+		 * 12: tuner reset pin
+		 * 13: audio source (0=tuner audio,1=line in)
+		 * 14: FM (0=on,1=off ???)
+		 */
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
+			.gpio1  = 0x6040,       /* pin 13 = 0, pin 14 = 1 */
+			.gpio2  = 0x0000,
+		}, {
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
+			.gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
+			.gpio2  = 0x0000,
+		}, {
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
+			.gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
+			.gpio2  = 0x0000,
+		} },
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
+			.gpio1  = 0x6000,       /* pin 13 = 0, pin 14 = 0 */
+			.gpio2  = 0x0000,
+		},
+		.mpeg           = CX88_MPEG_DVB,
+	},
 };
 
 /* ------------------------------------------------------------------ */
@@ -2393,6 +2434,10 @@ static const struct cx88_subid cx88_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x9290,
 		.card      = CX88_BOARD_HAUPPAUGE_IRONLY,
+	}, {
+		.subvendor = 0x107d,
+		.subdevice = 0x6654,
+		.card      = CX88_BOARD_WINFAST_DTV1800H,
 	},
 };
 
@@ -2591,6 +2636,23 @@ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
 	return -EINVAL;
 }
 
+static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
+					     int command, int arg)
+{
+	switch (command) {
+	case XC2028_TUNER_RESET:
+		/* GPIO 12 (xc3028 tuner reset) */
+		cx_set(MO_GP1_IO, 0x1010);
+		mdelay(50);
+		cx_clear(MO_GP1_IO, 0x10);
+		mdelay(50);
+		cx_set(MO_GP1_IO, 0x10);
+		mdelay(50);
+		return 0;
+	}
+	return -EINVAL;
+}
+
 /* ------------------------------------------------------------------- */
 /* some Divco specific stuff                                           */
 static int cx88_pv_8000gt_callback(struct cx88_core *core,
@@ -2663,6 +2725,8 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		return cx88_dvico_xc2028_callback(core, command, arg);
+	case CX88_BOARD_WINFAST_DTV1800H:
+		return cx88_xc3028_winfast1800h_callback(core, command, arg);
 	}
 
 	switch (command) {
@@ -2849,6 +2913,16 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
 		cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
 		udelay(1000);
 		break;
+
+	case CX88_BOARD_WINFAST_DTV1800H:
+		/* GPIO 12 (xc3028 tuner reset) */
+		cx_set(MO_GP1_IO, 0x1010);
+		mdelay(50);
+		cx_clear(MO_GP1_IO, 0x10);
+		mdelay(50);
+		cx_set(MO_GP1_IO, 0x10);
+		mdelay(50);
+		break;
 	}
 }
 
@@ -2869,6 +2943,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
 			core->i2c_algo.udelay = 16;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
+	case CX88_BOARD_WINFAST_DTV1800H:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
 	case CX88_BOARD_KWORLD_ATSC_120:
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9389cf290c1..c44e8760021 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1014,6 +1014,7 @@ static int dvb_register(struct cx8802_dev *dev)
 		}
 		break;
 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
+	case CX88_BOARD_WINFAST_DTV1800H:
 		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_pinnacle_hybrid_pctv,
 					       &core->i2c_adap);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 8a7c2bc457a..d91f5c51206 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -91,6 +91,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
 		gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
 		break;
 	case CX88_BOARD_WINFAST_DTV1000:
+	case CX88_BOARD_WINFAST_DTV1800H:
 	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 		gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
 		auxgpio = gpio;
@@ -224,6 +225,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 		ir->sampling = 1;
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
+	case CX88_BOARD_WINFAST_DTV1800H:
 		ir_codes = ir_codes_winfast;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 2190b600e2e..f55e4eeed78 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -233,6 +233,7 @@ extern struct sram_channel cx88_sram_channels[];
 #define CX88_BOARD_PROF_6200               78
 #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
 #define CX88_BOARD_HAUPPAUGE_IRONLY        80
+#define CX88_BOARD_WINFAST_DTV1800H        81
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
-- 
cgit v1.2.3-70-g09d2


From 493b7127aa56d0a5c041797639bf543d96f6261b Mon Sep 17 00:00:00 2001
From: David Wong <davidtlwong@gmail.com>
Date: Mon, 18 May 2009 05:25:49 -0300
Subject: V4L/DVB (11880): cx23885: support for card Mygica X8506 DMB-TH

This patch add cx23885 support for card "Mygica X8506 DMB-TH".
It should work on "Magic-Pro ProHDTV Extreme" as well, as they are
same hardware with different branding.

Sign-off-by: David T.L. Wong <davidtlwong@gmail.com>

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx23885  |  1 +
 drivers/media/video/cx23885/cx23885-cards.c | 22 ++++++++++++++++++
 drivers/media/video/cx23885/cx23885-dvb.c   | 35 ++++++++++++++++++++++++++++-
 drivers/media/video/cx23885/cx23885.h       |  1 +
 4 files changed, 58 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 948e436108b..450b8f8c389 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -20,3 +20,4 @@
  19 -> Hauppauge WinTV-HVR1275                             [0070:2215]
  20 -> Hauppauge WinTV-HVR1255                             [0070:2251]
  21 -> Hauppauge WinTV-HVR1210                             [0070:2291,0070:2295]
+ 22 -> Mygica X8506 DMB-TH                                 [14f1:8651]
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 057ef36d5a6..ce29b5e34a1 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -197,6 +197,10 @@ struct cx23885_board cx23885_boards[] = {
 		.name		= "Hauppauge WinTV-HVR1210",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_MYGICA_X8506] = {
+		.name		= "Mygica X8506 DMB-TH",
+		.portb		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -316,6 +320,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x2295,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1210,
+	}, {
+		.subvendor = 0x14f1,
+		.subdevice = 0x8651,
+		.card      = CX23885_BOARD_MYGICA_X8506,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -706,6 +714,15 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		mdelay(20);
 		cx23885_gpio_set(dev, GPIO_9);
 		break;
+	case CX23885_BOARD_MYGICA_X8506:
+		/* GPIO-1 reset XC5000 */
+		/* GPIO-2 reset LGS8GL5 */
+		cx_set(GP0_IO, 0x00060000);
+		cx_clear(GP0_IO, 0x00000006);
+		mdelay(100);
+		cx_set(GP0_IO, 0x00060006);
+		mdelay(100);
+		break;
 	}
 }
 
@@ -809,6 +826,11 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
+	case CX23885_BOARD_MYGICA_X8506:
+		ts1->gen_ctrl_val  = 0x5; /* Parallel */
+		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 45784a38430..e236df23370 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -49,6 +49,7 @@
 #include "lnbh24.h"
 #include "cx24116.h"
 #include "cimax2.h"
+#include "lgs8gxx.h"
 #include "netup-eeprom.h"
 #include "netup-init.h"
 #include "lgdt3305.h"
@@ -420,10 +421,29 @@ static struct cx24116_config dvbworld_cx24116_config = {
 	.demod_address = 0x05,
 };
 
+static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = {
+	.prod = LGS8GXX_PROD_LGS8GL5,
+	.demod_address = 0x19,
+	.serial_ts = 0,
+	.ts_clk_pol = 1,
+	.ts_clk_gated = 1,
+	.if_clk_freq = 30400, /* 30.4 MHz */
+	.if_freq = 5380, /* 5.38 MHz */
+	.if_neg_center = 1,
+	.ext_adc = 0,
+	.adc_signed = 0,
+	.if_neg_edge = 0,
+};
+
+static struct xc5000_config mygica_x8506_xc5000_config = {
+	.i2c_address = 0x61,
+	.if_khz = 5380,
+};
+
 static int dvb_register(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
-	struct cx23885_i2c *i2c_bus = NULL;
+	struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
 	struct videobuf_dvb_frontend *fe0;
 	int ret;
 
@@ -745,6 +765,19 @@ static int dvb_register(struct cx23885_tsport *port)
 			break;
 		}
 		break;
+	case CX23885_BOARD_MYGICA_X8506:
+		i2c_bus = &dev->i2c_bus[0];
+		i2c_bus2 = &dev->i2c_bus[1];
+		fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
+			&mygica_x8506_lgs8gl5_config,
+			&i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(xc5000_attach,
+				fe0->dvb.frontend,
+				&i2c_bus2->i2c_adap,
+				&mygica_x8506_xc5000_config);
+		}
+		break;
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
 			" isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 5067c19b659..1a2ac518a3f 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -75,6 +75,7 @@
 #define CX23885_BOARD_HAUPPAUGE_HVR1275        19
 #define CX23885_BOARD_HAUPPAUGE_HVR1255        20
 #define CX23885_BOARD_HAUPPAUGE_HVR1210        21
+#define CX23885_BOARD_MYGICA_X8506             22
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
cgit v1.2.3-70-g09d2


From f41b6961566b2cd038ad91568882f8fc1feac160 Mon Sep 17 00:00:00 2001
From: Filipe Rosset <rosset.filipe@gmail.com>
Date: Thu, 28 May 2009 11:11:53 -0300
Subject: V4L/DVB (11895): bt8xx: remove always false if

Remove always false if over unsigned int variable

Signed-off-by: Filipe Rosset <rosset.filipe@gmail.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/bt8xx/bttv-driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 539ae45bebd..7c1f82661ee 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4628,7 +4628,7 @@ static int __init bttv_init_module(void)
 #endif
 	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
 		gbuffers = 2;
-	if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
+	if (gbufsize > BTTV_MAX_FBUF)
 		gbufsize = BTTV_MAX_FBUF;
 	gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
 	if (bttv_verbose)
-- 
cgit v1.2.3-70-g09d2


From 75c74d1c78ec3b713a986e0efc645ed558384cdf Mon Sep 17 00:00:00 2001
From: Robert Krakora <rob.krakora@messagenetsystems.com>
Date: Thu, 28 May 2009 11:16:19 -0300
Subject: V4L/DVB (11896): em28xx: Fix for Slow Memory Leak

Test Code:  (Provided by Douglas)

v4l-dvb/v4l2-apps/test/stress-buffer.c

The audio DMA area was never being freed and would slowly leak over
time as the v4l device was opened and closed by an application.

Thanks again to Douglas for generating the test code to help locate
memory leaks!!!

Signed-off-by: Robert Krakora <rob.krakora@messagenetsystems.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-audio.c | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 0131322475b..7bd8a70f0a0 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -339,6 +339,11 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
 	mutex_lock(&dev->lock);
 	dev->adev.users--;
 	em28xx_audio_analog_set(dev);
+	if (substream->runtime->dma_area) {
+		dprintk("freeing\n");
+		vfree(substream->runtime->dma_area);
+		substream->runtime->dma_area = NULL;
+	}
 	mutex_unlock(&dev->lock);
 
 	return 0;
-- 
cgit v1.2.3-70-g09d2


From 9ad4c6551b8540054f51b483ce513ccb87f8181b Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Fri, 29 May 2009 20:54:02 -0300
Subject: V4L/DVB (11898): cx18: Perform 64 bit divide so it works for 32 bit
 systems

Thanks to David Ward and Mike Krufky for reporting the problem and
debugging this as an unresolved symbol due to a 64 bit divide on a 32 bit
system.  David Ward provided the content of this patch; Andy Walls only
performed some cosmetic edits.

Reported-by: David Ward <david.ward@gatech.edu>
Signed-off-by: David Ward <david.ward@gatech.edu>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-av-core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 0b3d840cc2e..536dedb23ba 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -447,6 +447,7 @@ void cx18_av_std_setup(struct cx18 *cx)
 
 	if (pll_post) {
 		int fsc, pll;
+		u64 tmp;
 
 		pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
 		pll /= pll_post;
@@ -459,7 +460,9 @@ void cx18_av_std_setup(struct cx18 *cx)
 				    "= %d.%03d\n", src_decimation / 256,
 				    ((src_decimation % 256) * 1000) / 256);
 
-		fsc = ((((u64)sc) * 28636360)/src_decimation) >> 13L;
+		tmp = 28636360 * (u64) sc;
+		do_div(tmp, src_decimation);
+		fsc = tmp >> 13;
 		CX18_DEBUG_INFO_DEV(sd,
 				    "Chroma sub-carrier initial freq = %d.%06d "
 				    "MHz\n", fsc / 1000000, fsc % 1000000);
-- 
cgit v1.2.3-70-g09d2


From 64a00b43e63c916f1bf4f6b7f519db0e198ba9d4 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:23:37 -0300
Subject: V4L/DVB (11923): em28xx: Don't let device work unless connected to a
 high speed USB port

The em28xx basically just doesn't work at 12 Mbps.  The isoc pipe needs
nearly 200 Mbps for analog support, so users would see garbage video, and on
the DVB/ATSC side scanning is likely to work but if the user tried to tune it
would certainly appear to have failed.

It's better to fail explicity up front and tell the user to plug into a USB 2.0
port, than to let the driver load and the user have weird problems with tuning
and garbage video.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index fe2a471e5f6..72cab9bcdf9 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2365,6 +2365,20 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 		ifnum,
 		interface->altsetting->desc.bInterfaceNumber);
 
+	/*
+	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
+	 * video stream wouldn't likely work, since 12 Mbps is generally
+	 * not enough even for most Digital TV streams.
+	 */
+	if (udev->speed != USB_SPEED_HIGH) {
+		printk(DRIVER_NAME ": Device initialization failed.\n");
+		printk(DRIVER_NAME ": Device must be connected to a high-speed"
+		       " USB 2.0 port.\n");
+		em28xx_devused &= ~(1<<nr);
+		retval = -ENODEV;
+		goto err;
+	}
+
 	if (nr >= EM28XX_MAXBOARDS) {
 		printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
 				EM28XX_MAXBOARDS);
-- 
cgit v1.2.3-70-g09d2


From ee3436b82886c0cb295354fb7ebbeadf3ff22105 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:25:36 -0300
Subject: V4L/DVB (11924): au0828: Don't let device work unless connected to a
 high speed USB port

The au0828 basically just doesn't work at 12 Mbps.  The isoc pipe needs
nearly 200 Mbps for analog support, so users would see garbage video, and on
the DVB/ATSC side scanning is likely to work but if the user tried to tune it
would certainly appear to have failed.

It's better to fail explicity up front and tell the user to plug into a USB 2.0
port, than to let the driver load and the user have weird problems with tuning
and garbage video.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/au0828/au0828-core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index a1e4c0d769a..2b3f64d7a7f 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -181,6 +181,18 @@ static int au0828_usb_probe(struct usb_interface *interface,
 		le16_to_cpu(usbdev->descriptor.idProduct),
 		ifnum);
 
+	/*
+	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
+	 * video stream wouldn't likely work, since 12 Mbps is generally
+	 * not enough even for most Digital TV streams.
+	 */
+	if (usbdev->speed != USB_SPEED_HIGH) {
+		printk(KERN_ERR "au0828: Device initialization failed.\n");
+		printk(KERN_ERR "au0828: Device must be connected to a "
+		       "high-speed USB 2.0 port.\n");
+		return -ENODEV;
+	}
+
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
 		printk(KERN_ERR "%s() Unable to allocate memory\n", __func__);
-- 
cgit v1.2.3-70-g09d2


From 3ed58baf5db4eab553803916a990a3dbca4dc611 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:27:26 -0300
Subject: V4L/DVB (11925): em28xx: Add support for the K-World 2800d

Make the KWorld 2800d work properly.  In this case, that means making the
profile more generic so that it works for both the Pointnix Intra-Oral USB
camera and the KWorld device.

The device provides the audio through a pass-thru cable, so we don't need
an actual audio capture profile (neither the K-World device nor the Pointnix
have an onboard audio decoder).

Thanks to Paul Thomas for providing sample hardware.

Cc: Paul Thomas <pthomas8589@gmail.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.em28xx |  2 +-
 drivers/media/video/em28xx/em28xx-cards.c | 11 ++++++-----
 drivers/media/video/em28xx/em28xx.h       |  2 +-
 3 files changed, 8 insertions(+), 7 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 20aa65a7059..b03a68586eb 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -17,7 +17,7 @@
  16 -> Hauppauge WinTV HVR 950                  (em2883)        [2040:6513,2040:6517,2040:651b]
  17 -> Pinnacle PCTV HD Pro Stick               (em2880)        [2304:0227]
  18 -> Hauppauge WinTV HVR 900 (R2)             (em2880)        [2040:6502]
- 19 -> PointNix Intra-Oral Camera               (em2860)
+ 19 -> EM2860/SAA711X Reference Design          (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]
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 72cab9bcdf9..b2c26293b19 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1002,16 +1002,17 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 	},
-	[EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
-		.name                = "PointNix Intra-Oral Camera",
+	[EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
+		.name                = "EM2860/SAA711X Reference Design",
 		.has_snapshot_button = 1,
-		.tda9887_conf        = TDA9887_PRESENT,
 		.tuner_type          = TUNER_ABSENT,
 		.decoder             = EM28XX_SAA711X,
 		.input               = { {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = SAA7115_SVIDEO3,
-			.amux     = EM28XX_AMUX_VIDEO,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
 		} },
 	},
 	[EM2880_BOARD_MSI_DIGIVOX_AD] = {
@@ -1519,7 +1520,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
 static struct em28xx_hash_table em28xx_i2c_hash[] = {
 	{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
 	{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
-	{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
+	{0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
 	{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
 };
 
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 8db797fedb7..2ddd59d2109 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -58,7 +58,7 @@
 #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 EM2860_BOARD_SAA711X_REFERENCE_DESIGN	19
 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600   20
 #define EM2800_BOARD_GRABBEEX_USB2800           21
 #define EM2750_BOARD_UNKNOWN			  22
-- 
cgit v1.2.3-70-g09d2


From 0f9fba3129541822b1d75330406e62e838bf4fc1 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:28:46 -0300
Subject: V4L/DVB (11926): tuner-core: fix warning introduced when cleaning up
 xc5000 init routine

This patch removes some remaining dead code.  Warning showed up in Hans
Verkuil's daily report after I committed hg changeset 7f2eea75118b.

Thanks to Michael Krufky for bringing the warning to my attention.

Cc: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tuner-core.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 4018eacb3a4..537594211a9 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -412,8 +412,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		break;
 	case TUNER_XC5000:
 	{
-		struct dvb_tuner_ops *xc_tuner_ops;
-
 		xc5000_cfg.i2c_address	  = t->i2c->addr;
 		/* if_khz will be set when the digital dvb_attach() occurs */
 		xc5000_cfg.if_khz	  = 0;
-- 
cgit v1.2.3-70-g09d2


From e2a1b79f7dc54a6f1cc8821e0c7fd68ba7568d81 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:44:10 -0300
Subject: V4L/DVB (11927): em28xx: provide module option to disable USB speed
 check

Add an em28xx module option that allows a user to override the USB speed check.
Intended for advanced users who understand the consequences of trying to use
the device with a 12Mbps bus.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index b2c26293b19..36abb352b99 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -49,6 +49,11 @@ static unsigned int disable_ir;
 module_param(disable_ir, int, 0444);
 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
 
+static unsigned int disable_usb_speed_check;
+module_param(disable_usb_speed_check, int, 0444);
+MODULE_PARM_DESC(disable_usb_speed_check,
+		 "override min bandwidth requirement of 480M bps");
+
 static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
 module_param_array(card,  int, NULL, 0444);
 MODULE_PARM_DESC(card,     "card type");
@@ -2371,7 +2376,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 	 * video stream wouldn't likely work, since 12 Mbps is generally
 	 * not enough even for most Digital TV streams.
 	 */
-	if (udev->speed != USB_SPEED_HIGH) {
+	if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
 		printk(DRIVER_NAME ": Device initialization failed.\n");
 		printk(DRIVER_NAME ": Device must be connected to a high-speed"
 		       " USB 2.0 port.\n");
-- 
cgit v1.2.3-70-g09d2


From d6a9a430a63adac71f2d23d4eb8f4eb467fc82c2 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Wed, 27 May 2009 23:46:17 -0300
Subject: V4L/DVB (11928): au0828: provide module option to disable USB speed
 check

Add an au0828 module option that allows a user to override the USB speed check.
Intended for advanced users who understand the consequences of trying to use
the device with a 12Mbps bus.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/au0828/au0828-core.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 2b3f64d7a7f..3544a2f12f1 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -36,6 +36,11 @@ int au0828_debug;
 module_param_named(debug, au0828_debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable debug messages");
 
+static unsigned int disable_usb_speed_check;
+module_param(disable_usb_speed_check, int, 0444);
+MODULE_PARM_DESC(disable_usb_speed_check,
+		 "override min bandwidth requirement of 480M bps");
+
 #define _AU0828_BULKPIPE 0x03
 #define _BULKPIPESIZE 0xffff
 
@@ -186,7 +191,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
 	 * video stream wouldn't likely work, since 12 Mbps is generally
 	 * not enough even for most Digital TV streams.
 	 */
-	if (usbdev->speed != USB_SPEED_HIGH) {
+	if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
 		printk(KERN_ERR "au0828: Device initialization failed.\n");
 		printk(KERN_ERR "au0828: Device must be connected to a "
 		       "high-speed USB 2.0 port.\n");
-- 
cgit v1.2.3-70-g09d2


From 7360055aa31f5f732af4d0ed23517f1b6adfa573 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Fri, 22 May 2009 21:12:00 -0300
Subject: V4L/DVB (11932): ivtv: Add missing newline

Reported-by: Martin Dauskardt <martin.dauskardt@gmx.de>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ivtv/ivtv-driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e9ca9a064ae..558f8a837ff 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -455,7 +455,7 @@ static void ivtv_process_eeprom(struct ivtv *itv)
 			break;
 	}
 	if (tv.tuner_type == TUNER_ABSENT)
-		IVTV_ERR("tveeprom cannot autodetect tuner!");
+		IVTV_ERR("tveeprom cannot autodetect tuner!\n");
 
 	if (itv->options.tuner == -1)
 		itv->options.tuner = tv.tuner_type;
-- 
cgit v1.2.3-70-g09d2


From 5ddc9b100fc96e8f3c6d435cecd9d09e5b9673f9 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Sun, 7 Jun 2009 21:39:03 -0300
Subject: V4L/DVB (11933): tuner-simple, tveeprom: Add Philips FQ1216LME MK3
 analog tuner

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.tuner   |  1 +
 drivers/media/common/tuners/tuner-simple.c | 38 +++++++++++++++++++++---------
 drivers/media/common/tuners/tuner-types.c  | 29 +++++++++++++++++++++++
 drivers/media/video/tveeprom.c             |  4 ++--
 include/media/tuner.h                      |  1 +
 5 files changed, 60 insertions(+), 13 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 22c1c55979c..be67844074d 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -77,3 +77,4 @@ tuner=76 - Xceive 5000 tuner
 tuner=77 - TCL tuner MF02GIP-5N-E
 tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
 tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
+tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 78412c9c424..a5eb6592abe 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -416,6 +416,24 @@ static int simple_std_setup(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
+{
+	struct tuner_simple_priv *priv = fe->tuner_priv;
+	int rc;
+	u8 buffer[2];
+
+	buffer[0] = (config & ~0x38) | 0x18;
+	buffer[1] = aux;
+
+	tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
+
+	rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
+	if (2 != rc)
+		tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
+
+	return rc == 2 ? 0 : rc;
+}
+
 static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
 			    u16 div, u8 config, u8 cb)
 {
@@ -424,17 +442,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
 
 	switch (priv->type) {
 	case TUNER_LG_TDVS_H06XF:
-		/* Set the Auxiliary Byte. */
-		buffer[0] = buffer[2];
-		buffer[0] &= ~0x20;
-		buffer[0] |= 0x18;
-		buffer[1] = 0x20;
-		tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
-
-		rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
-		if (2 != rc)
-			tuner_warn("i2c i/o error: rc == %d "
-				   "(should be 2)\n", rc);
+		simple_set_aux_byte(fe, config, 0x20);
+		break;
+	case TUNER_PHILIPS_FQ1216LME_MK3:
+		simple_set_aux_byte(fe, config, 0x60); /* External AGC */
 		break;
 	case TUNER_MICROTUNE_4042FI5:
 	{
@@ -506,6 +517,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
 	case TUNER_THOMSON_DTT761X:
 		buffer[3] = 0x39;
 		break;
+	case TUNER_PHILIPS_FQ1216LME_MK3:
+		tuner_err("This tuner doesn't have FM\n");
+		/* Set the low band for sanity, since it covers 88-108 MHz */
+		buffer[3] = 0x01;
+		break;
 	case TUNER_MICROTUNE_4049FM5:
 	default:
 		buffer[3] = 0xa4;
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index a9ce5b2ce08..6a7f1a417c2 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1279,6 +1279,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
 	},
 };
 
+/* 80-89 */
+/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
+
+static struct tuner_params tuner_fq1216lme_mk3_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_PAL,
+		.ranges = tuner_fm1216me_mk3_pal_ranges,
+		.count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
+		.cb_first_if_lower_freq = 1, /* not specified, but safe to do */
+		.has_tda9887 = 1, /* TDA9886 */
+		.port1_active = 1,
+		.port2_active = 1,
+		.port2_invert_for_secam_lc = 1,
+		.default_top_low = 4,
+		.default_top_mid = 4,
+		.default_top_high = 4,
+		.default_top_secam_low = 4,
+		.default_top_secam_mid = 4,
+		.default_top_secam_high = 4,
+	},
+};
+
 /* --------------------------------------------------------------------- */
 
 struct tunertype tuners[] = {
@@ -1724,6 +1746,13 @@ struct tunertype tuners[] = {
 		.params = tuner_fm1216mk5_params,
 		.count  = ARRAY_SIZE(tuner_fm1216mk5_params),
 	},
+
+	/* 80-89 */
+	[TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
+		.name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
+		.params = tuner_fq1216lme_mk3_params,
+		.count  = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
+	},
 };
 EXPORT_SYMBOL(tuners);
 
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index d0de03c6e68..ac02808106c 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -184,7 +184,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        		"Silicon TDA8275C1 8290 FM"},
 	{ TUNER_ABSENT,        		"Thompson DTT757"},
 	/* 80-89 */
-	{ TUNER_PHILIPS_FM1216ME_MK3, 	"Philips FQ1216LME MK3"},
+	{ TUNER_PHILIPS_FQ1216LME_MK3, 	"Philips FQ1216LME MK3"},
 	{ TUNER_LG_PAL_NEW_TAPC, 	"LG TAPC G701D"},
 	{ TUNER_LG_NTSC_NEW_TAPC, 	"LG TAPC H791F"},
 	{ TUNER_LG_PAL_NEW_TAPC, 	"TCL 2002MB 3"},
@@ -229,7 +229,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        		"Samsung THPD5222FG30A"},
 	/* 120-129 */
 	{ TUNER_XC2028,        		"Xceive XC3028"},
-	{ TUNER_ABSENT,        		"Philips FQ1216LME MK5"},
+	{ TUNER_PHILIPS_FQ1216LME_MK3,	"Philips FQ1216LME MK5"},
 	{ TUNER_ABSENT,        		"Philips FQD1216LME"},
 	{ TUNER_ABSENT,        		"Conexant CX24118A"},
 	{ TUNER_ABSENT,        		"TCL DMF11WIP"},
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 735a2a94116..cbf97f45fbe 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -125,6 +125,7 @@
 #define TUNER_TCL_MF02GIP_5N		77	/* TCL MF02GIP_5N */
 #define TUNER_PHILIPS_FMD1216MEX_MK3	78
 #define TUNER_PHILIPS_FM1216MK5		79
+#define TUNER_PHILIPS_FQ1216LME_MK3	80	/* Active loopthrough, no FM */
 
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)
-- 
cgit v1.2.3-70-g09d2


From ef5b5168e58021f87af53283002795ce5a787c2b Mon Sep 17 00:00:00 2001
From: Randy Dunlap <randy.dunlap@oracle.com>
Date: Wed, 10 Jun 2009 11:58:22 -0300
Subject: V4L/DVB (11936): Fix v4l2-device usage of i2c_unregister_device()

Fix v4l2-device usage of i2c_unregister_device() and handle the case of
CONFIG_I2C=m & CONFIG_MEDIA_VIDEO=y.

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 772833b69bb..0d06e7cbd5b 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -85,7 +85,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
 	/* Unregister subdevs */
 	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
 		v4l2_device_unregister_subdev(sd);
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 		if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
 			struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-- 
cgit v1.2.3-70-g09d2


From 028bbfedcc00225d4a1d700e75658d773523005d Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Wed, 27 May 2009 22:10:43 -0300
Subject: V4L/DVB (11937): vino: replace dma_sync_single with
 dma_sync_single_for_cpu

This replaces dma_sync_single() with dma_sync_single_for_cpu() because
dma_sync_single() is an obsolete API; include/linux/dma-mapping.h says:

/* Backwards compat, remove in 2.7.x */

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/vino.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 43e0998adb5..97b082fe447 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -868,9 +868,9 @@ static void vino_sync_buffer(struct vino_framebuffer *fb)
 	dprintk("vino_sync_buffer():\n");
 
 	for (i = 0; i < fb->desc_table.page_count; i++)
-		dma_sync_single(NULL,
-				fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
-				PAGE_SIZE, DMA_FROM_DEVICE);
+		dma_sync_single_for_cpu(NULL,
+					fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
+					PAGE_SIZE, DMA_FROM_DEVICE);
 }
 
 /* Framebuffer fifo functions (need to be locked externally) */
-- 
cgit v1.2.3-70-g09d2


From 6b6b75432caf87b8b7834ad8eb9acd75e383e20f Mon Sep 17 00:00:00 2001
From: Dmitri Belimov <d.belimov@gmail.com>
Date: Thu, 28 May 2009 01:58:57 -0300
Subject: V4L/DVB (11938): big rework of TS for saa7134

1. Add start/stop TS function.
2. Move setup DMA of TS to DMA function.
3. Write support cupture via MMAP
4. Rework startup and finish process, remove simple FSM.

Tested-by: Hermann Pitton <hermann-pitton@arcor.de>
Tested-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Alexey Osipov <lion-simba@pridelands.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-cards.c   |   2 +
 drivers/media/video/saa7134/saa7134-core.c    |  17 ++++
 drivers/media/video/saa7134/saa7134-empress.c |  11 +++
 drivers/media/video/saa7134/saa7134-ts.c      | 120 ++++++++++++++------------
 drivers/media/video/saa7134/saa7134.h         |  12 +--
 5 files changed, 100 insertions(+), 62 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 73482eb8d38..229ba93bcc9 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4458,6 +4458,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Igor Kuznetsov <igk@igk.ru> */
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		/* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+		/* Alexey Osipov <lion-simba@pridelands.ru> */
 		.name           = "Beholder BeholdTV M6",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
@@ -4532,6 +4533,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Igor Kuznetsov <igk@igk.ru> */
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		/* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+		/* Alexey Osipov <lion-simba@pridelands.ru> */
 		.name           = "Beholder BeholdTV M6 Extra",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 37b14526a09..94a023a14bb 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -331,6 +331,10 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
 		dprintk("buffer_next %p\n",NULL);
 		saa7134_set_dmabits(dev);
 		del_timer(&q->timeout);
+
+		if (card_has_mpeg(dev))
+			if (dev->ts_started)
+				saa7134_ts_stop(dev);
 	}
 }
 
@@ -416,6 +420,19 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
 		ctrl |= SAA7134_MAIN_CTRL_TE5;
 		irq  |= SAA7134_IRQ1_INTE_RA2_1 |
 			SAA7134_IRQ1_INTE_RA2_0;
+
+		/* dma: setup channel 5 (= TS) */
+
+		saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
+		saa_writeb(SAA7134_TS_DMA1,
+			((dev->ts.nr_packets - 1) >> 8) & 0xff);
+		/* TSNOPIT=0, TSCOLAP=0 */
+		saa_writeb(SAA7134_TS_DMA2,
+			(((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
+		saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
+		saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
+						  SAA7134_RS_CONTROL_ME |
+						  (dev->ts.pt_ts.dma >> 12));
 	}
 
 	/* set task conditions + field handling */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 097c2dfebd2..add1757f893 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -255,6 +255,16 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
+static int empress_try_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct saa7134_dev *dev = file->private_data;
+
+	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
+	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+
+	return 0;
+}
 
 static int empress_reqbufs(struct file *file, void *priv,
 					struct v4l2_requestbuffers *p)
@@ -450,6 +460,7 @@ static const struct v4l2_file_operations ts_fops =
 static const struct v4l2_ioctl_ops ts_ioctl_ops = {
 	.vidioc_querycap		= empress_querycap,
 	.vidioc_enum_fmt_vid_cap	= empress_enum_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap		= empress_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap		= empress_g_fmt_vid_cap,
 	.vidioc_reqbufs			= empress_reqbufs,
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index b8ff459d0d3..3fa652279ac 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -67,33 +67,8 @@ static int buffer_activate(struct saa7134_dev *dev,
 
 	mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
 
-	if (dev->ts_state == SAA7134_TS_BUFF_DONE) {
-		/* Clear TS cache */
-		dev->buff_cnt = 0;
-		saa_writeb(SAA7134_TS_SERIAL1, 0x00);
-		saa_writeb(SAA7134_TS_SERIAL1, 0x03);
-		saa_writeb(SAA7134_TS_SERIAL1, 0x00);
-		saa_writeb(SAA7134_TS_SERIAL1, 0x01);
-
-		/* TS clock non-inverted */
-		saa_writeb(SAA7134_TS_SERIAL1, 0x00);
-
-		/* Start TS stream */
-		switch (saa7134_boards[dev->board].ts_type) {
-		case SAA7134_MPEG_TS_PARALLEL:
-			saa_writeb(SAA7134_TS_SERIAL0, 0x40);
-			saa_writeb(SAA7134_TS_PARALLEL, 0xec);
-			break;
-		case SAA7134_MPEG_TS_SERIAL:
-			saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
-			saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
-			saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
-			saa_writeb(SAA7134_TS_SERIAL1, 0x02);
-			break;
-		}
-
-		dev->ts_state = SAA7134_TS_STARTED;
-	}
+	if (!dev->ts_started)
+		saa7134_ts_start(dev);
 
 	return 0;
 }
@@ -104,7 +79,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	struct saa7134_dev *dev = q->priv_data;
 	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
 	unsigned int lines, llength, size;
-	u32 control;
 	int err;
 
 	dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -121,8 +95,11 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	}
 
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+
 		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
+		dprintk("buffer_prepare: needs_init\n");
+
 		buf->vb.width  = llength;
 		buf->vb.height = lines;
 		buf->vb.size   = size;
@@ -139,23 +116,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 			goto oops;
 	}
 
-	dev->buff_cnt++;
-
-	if (dev->buff_cnt == dev->ts.nr_bufs) {
-		dev->ts_state = SAA7134_TS_BUFF_DONE;
-		/* dma: setup channel 5 (= TS) */
-		control = SAA7134_RS_CONTROL_BURST_16 |
-			SAA7134_RS_CONTROL_ME |
-			(buf->pt->dma >> 12);
-
-		saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff);
-		saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff);
-		/* TSNOPIT=0, TSCOLAP=0 */
-		saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00);
-		saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
-		saa_writel(SAA7134_RS_CONTROL(5), control);
-	}
-
 	buf->vb.state = VIDEOBUF_PREPARED;
 	buf->activate = buffer_activate;
 	buf->vb.field = field;
@@ -175,8 +135,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 	if (0 == *count)
 		*count = dev->ts.nr_bufs;
 	*count = saa7134_buffer_count(*size,*count);
-	dev->buff_cnt = 0;
-	dev->ts_state = SAA7134_TS_STOPPED;
+
 	return 0;
 }
 
@@ -193,11 +152,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
 	struct saa7134_dev *dev = q->priv_data;
 
-	if (dev->ts_state == SAA7134_TS_STARTED) {
-		/* Stop TS transport */
-		saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
-		dev->ts_state = SAA7134_TS_STOPPED;
-	}
+	if (dev->ts_started)
+		saa7134_ts_stop(dev);
+
 	saa7134_dma_free(q,buf);
 }
 
@@ -214,7 +171,7 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
 
 static unsigned int tsbufs = 8;
 module_param(tsbufs, int, 0444);
-MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
+MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32");
 
 static unsigned int ts_nr_packets = 64;
 module_param(ts_nr_packets, int, 0444);
@@ -256,6 +213,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
 	dev->ts_q.timeout.data     = (unsigned long)(&dev->ts_q);
 	dev->ts_q.dev              = dev;
 	dev->ts_q.need_two         = 1;
+	dev->ts_started            = 0;
 	saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
 
 	/* init TS hw */
@@ -264,13 +222,67 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
 	return 0;
 }
 
+/* Function for stop TS */
+int saa7134_ts_stop(struct saa7134_dev *dev)
+{
+	dprintk("TS stop\n");
+
+	BUG_ON(!dev->ts_started);
+
+	/* Stop TS stream */
+	switch (saa7134_boards[dev->board].ts_type) {
+	case SAA7134_MPEG_TS_PARALLEL:
+		saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+		dev->ts_started = 0;
+		break;
+	case SAA7134_MPEG_TS_SERIAL:
+		saa_writeb(SAA7134_TS_SERIAL0, 0x40);
+		dev->ts_started = 0;
+		break;
+	}
+	return 0;
+}
+
+/* Function for start TS */
+int saa7134_ts_start(struct saa7134_dev *dev)
+{
+	dprintk("TS start\n");
+
+	BUG_ON(dev->ts_started);
+
+	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
+	saa_writeb(SAA7134_TS_SERIAL1, 0x03);
+	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
+	saa_writeb(SAA7134_TS_SERIAL1, 0x01);
+
+	/* TS clock non-inverted */
+	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
+
+	/* Start TS stream */
+	switch (saa7134_boards[dev->board].ts_type) {
+	case SAA7134_MPEG_TS_PARALLEL:
+		saa_writeb(SAA7134_TS_SERIAL0, 0x40);
+		saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+		break;
+	case SAA7134_MPEG_TS_SERIAL:
+		saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
+		saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+		saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
+		saa_writeb(SAA7134_TS_SERIAL1, 0x02);
+		break;
+	}
+
+	dev->ts_started = 1;
+
+	return 0;
+}
+
 int saa7134_ts_fini(struct saa7134_dev *dev)
 {
 	saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
 	return 0;
 }
 
-
 void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
 {
 	enum v4l2_field field;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index ae7602d343c..82268848f26 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -493,12 +493,6 @@ struct saa7134_mpeg_ops {
 	void                       (*signal_change)(struct saa7134_dev *dev);
 };
 
-enum saa7134_ts_status {
-	SAA7134_TS_STOPPED,
-	SAA7134_TS_BUFF_DONE,
-	SAA7134_TS_STARTED,
-};
-
 /* global device status */
 struct saa7134_dev {
 	struct list_head           devlist;
@@ -593,8 +587,7 @@ struct saa7134_dev {
 	/* SAA7134_MPEG_* */
 	struct saa7134_ts          ts;
 	struct saa7134_dmaqueue    ts_q;
-	enum saa7134_ts_status 	   ts_state;
-	unsigned int 		   buff_cnt;
+	int                        ts_started;
 	struct saa7134_mpeg_ops    *mops;
 
 	/* SAA7134_MPEG_EMPRESS only */
@@ -752,6 +745,9 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
 
 int saa7134_ts_init_hw(struct saa7134_dev *dev);
 
+int saa7134_ts_start(struct saa7134_dev *dev);
+int saa7134_ts_stop(struct saa7134_dev *dev);
+
 /* ----------------------------------------------------------- */
 /* saa7134-vbi.c                                               */
 
-- 
cgit v1.2.3-70-g09d2


From f02c3944c1331f0b41c5d75b6d5d69d8858b169f Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Wed, 6 May 2009 17:44:45 -0300
Subject: V4L/DVB (11940): gspca - m5602-s5k4aa: Add vflip quirk for the Lenovo
 Y300
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The Lenovo Y300 has its sensor upside down. Quirk it to gain normal functionality.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index e5fed5b89ff..191bcd71897 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -65,6 +65,12 @@ static
 			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
 		}
+	}, {
+		.ident = "Lenovo Y300",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Y300")
+		}
 	},
 	{ }
 };
-- 
cgit v1.2.3-70-g09d2


From 40a4f2fc6525f621f6f855e1d5506c3b14acf3cc Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Mon, 1 Jun 2009 16:22:18 -0300
Subject: V4L/DVB (11941): gspca - m5602-ov9650: Add vflip quirk for the ASUS
 A6VA
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add vflip quirk for the ASUS A6VA. Thanks to Salvo Di Rosa for reporting.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index e0ec7a6ffa6..a441f8c06ab 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -94,6 +94,13 @@ static
 			DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
 		}
 	},
+	{
+		.ident = "ASUS A6VA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
+		}
+	},
 	{
 		.ident = "Alienware Aurora m9700",
 		.matches = {
-- 
cgit v1.2.3-70-g09d2


From 926b3b4122e4ebca52e67eecf9beb9a517e593f4 Mon Sep 17 00:00:00 2001
From: Erik Andrén <erik.andren@gmail.com>
Date: Thu, 11 Jun 2009 17:20:23 -0300
Subject: V4L/DVB (11942): gspca - m5602-ov9650: Reorder quirk list and add A7V
 quirk
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The quirk list has grown and was in need of sorting. This is now done. Add a new vflip quirk for the ASUS A7V while we're at it. Thanks to Carsten Menzel for reporting.

Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/m5602/m5602_ov9650.c | 34 +++++++++++++-------------
 1 file changed, 17 insertions(+), 17 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index a441f8c06ab..c2739d6605a 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -45,60 +45,60 @@ static
     const
 	struct dmi_system_id ov9650_flip_dmi_table[] = {
 	{
-		.ident = "ASUS A6VA",
+		.ident = "ASUS A6Ja",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
 		}
 	},
 	{
-
-		.ident = "ASUS A6VC",
+		.ident = "ASUS A6JC",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
 		}
 	},
 	{
-		.ident = "ASUS A6VM",
+		.ident = "ASUS A6K",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
 		}
 	},
 	{
-		.ident = "ASUS A6JC",
+		.ident = "ASUS A6Kt",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
 		}
 	},
 	{
-		.ident = "ASUS A6Ja",
+		.ident = "ASUS A6VA",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
 		}
 	},
 	{
-		.ident = "ASUS A6Kt",
+
+		.ident = "ASUS A6VC",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
 		}
 	},
 	{
-		.ident = "ASUS A6K",
+		.ident = "ASUS A6VM",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
 		}
 	},
 	{
-		.ident = "ASUS A6VA",
+		.ident = "ASUS A7V",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
+			DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
 		}
 	},
 	{
-- 
cgit v1.2.3-70-g09d2


From d732c44c1a4b54e3c59ad92069bc2fd848aca5f3 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Sun, 31 May 2009 17:05:55 -0300
Subject: V4L/DVB (11944): uvcvideo: Add generic control blacklist.

Another device (5986:0241) has been reported to advertise a UVC control it
does not support. Rework the control blacklist to match devices by their
VID:PID instead of trying to be clever about which controls might not be
supported properly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_ctrl.c   | 35 +++++++++++++++--------------------
 drivers/media/video/uvc/uvc_driver.c |  3 +--
 drivers/media/video/uvc/uvcvideo.h   |  1 -
 3 files changed, 16 insertions(+), 23 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 0d7e38d6ff6..36a6ba92df2 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1372,21 +1372,19 @@ end:
 }
 
 /*
- * Prune an entity of its bogus controls. This currently includes processing
- * unit auto controls for which no corresponding manual control is available.
- * Such auto controls make little sense if any, and are known to crash at
- * least the SiGma Micro webcam.
+ * Prune an entity of its bogus controls using a blacklist. Bogus controls
+ * are currently the ones that crash the camera or unconditionally return an
+ * error when queried.
  */
 static void
-uvc_ctrl_prune_entity(struct uvc_entity *entity)
+uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
 {
 	static const struct {
-		u8 idx_manual;
-		u8 idx_auto;
+		struct usb_device_id id;
+		u8 index;
 	} blacklist[] = {
-		{ 2, 11 }, /* Hue */
-		{ 6, 12 }, /* White Balance Temperature */
-		{ 7, 13 }, /* White Balance Component */
+		{ { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
+		{ { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
 	};
 
 	u8 *controls;
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity)
 	size = entity->processing.bControlSize;
 
 	for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
-		if (blacklist[i].idx_auto >= 8 * size ||
-		    blacklist[i].idx_manual >= 8 * size)
+		if (!usb_match_id(dev->intf, &blacklist[i].id))
 			continue;
 
-		if (!uvc_test_bit(controls, blacklist[i].idx_auto) ||
-		     uvc_test_bit(controls, blacklist[i].idx_manual))
+		if (blacklist[i].index >= 8 * size ||
+		    !uvc_test_bit(controls, blacklist[i].index))
 			continue;
 
-		uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no "
-			"matching manual control, removing it.\n", entity->id,
-			blacklist[i].idx_auto);
+		uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
+			"removing it.\n", entity->id, blacklist[i].index);
 
-		uvc_clear_bit(controls, blacklist[i].idx_auto);
+		uvc_clear_bit(controls, blacklist[i].index);
 	}
 }
 
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
 			bControlSize = entity->camera.bControlSize;
 		}
 
-		if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
-			uvc_ctrl_prune_entity(entity);
+		uvc_ctrl_prune_entity(dev, entity);
 
 		for (i = 0; i < bControlSize; ++i)
 			ncontrols += hweight8(bmControls[i]);
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 46bfecb194e..838585990ee 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1946,8 +1946,7 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_IGNORE_SELECTOR_UNIT
-				| UVC_QUIRK_PRUNE_CONTROLS },
+				| UVC_QUIRK_IGNORE_SELECTOR_UNIT },
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
 	{}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index daf07444730..f435e8eeccd 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -313,7 +313,6 @@ struct uvc_xu_control {
 #define UVC_QUIRK_BUILTIN_ISIGHT	0x00000008
 #define UVC_QUIRK_STREAM_NO_FID		0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
-#define UVC_QUIRK_PRUNE_CONTROLS	0x00000040
 #define UVC_QUIRK_FIX_BANDWIDTH		0x00000080
 
 /* Format flags */
-- 
cgit v1.2.3-70-g09d2


From 23ff6043add670713bbf2f6ee5d520459cfdfae9 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Thu, 4 Jun 2009 09:26:39 -0300
Subject: V4L/DVB (11945): uvcvideo: Don't accept to change the format when
 buffers are allocated.

Setting a new frame format or size will likely change the buffer size required
to store a complete video frame. To avoid a buffer overflow, don't allow
VIDIOC_S_FMT calls when video buffers are already allocated.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_queue.c | 14 ++++++++++++++
 drivers/media/video/uvc/uvc_v4l2.c  |  2 +-
 drivers/media/video/uvc/uvcvideo.h  |  1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 0155752e4a5..f854698c406 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -172,6 +172,20 @@ int uvc_free_buffers(struct uvc_video_queue *queue)
 	return 0;
 }
 
+/*
+ * Check if buffers have been allocated.
+ */
+int uvc_queue_allocated(struct uvc_video_queue *queue)
+{
+	int allocated;
+
+	mutex_lock(&queue->mutex);
+	allocated = queue->count != 0;
+	mutex_unlock(&queue->mutex);
+
+	return allocated;
+}
+
 static void __uvc_query_buffer(struct uvc_buffer *buf,
 		struct v4l2_buffer *v4l2_buf)
 {
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 507542dcbda..f8b94d608a1 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -251,7 +251,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
 	if (fmt->type != video->streaming->type)
 		return -EINVAL;
 
-	if (uvc_queue_streaming(&video->queue))
+	if (uvc_queue_allocated(&video->queue))
 		return -EBUSY;
 
 	ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index f435e8eeccd..3c78d3c1e4c 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -747,6 +747,7 @@ extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
 		struct uvc_buffer *buf);
 extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
 		struct file *file, poll_table *wait);
+extern int uvc_queue_allocated(struct uvc_video_queue *queue);
 static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
 {
 	return queue->flags & UVC_QUEUE_STREAMING;
-- 
cgit v1.2.3-70-g09d2


From 2d2bf2a3a6c84f0b316764e521d5dcee557e9c65 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Tue, 9 Jun 2009 12:40:59 -0300
Subject: V4L/DVB (11946): uvcvideo: Add support for Aveo Technology webcams

The Aveo Technology USB 2.0 Camera (1871:0306) requires the
PROBE_EXTRAFIELDS quirk. Add a corresponding entry in the device IDs list.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 838585990ee..f6c5026df18 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1917,6 +1917,15 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* Aveo Technology USB 2.0 Camera */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1871,
+	  .idProduct		= 0x0306,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_EXTRAFIELDS },
 	/* Ecamm Pico iMage */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
-- 
cgit v1.2.3-70-g09d2


From ca4a3456858775081f172e89077aa65cf5dbc52a Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Tue, 9 Jun 2009 12:46:43 -0300
Subject: V4L/DVB (11947): uvcvideo: Add support for FSC V30S webcams

The FSC WebCam V30S (18ec:3288) requires the MINMAX quirk. Add a corresponding
entry in the device IDs list.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index f6c5026df18..f7545126951 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1935,6 +1935,15 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_EXTRAFIELDS },
+	/* FSC WebCam V30S */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x18ec,
+	  .idProduct		= 0x3288,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Bodelin ProScopeHR */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_DEV_HI
-- 
cgit v1.2.3-70-g09d2


From 3b27740c7de0fd59032c723ad326926c97383e95 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@skynet.be>
Date: Tue, 9 Jun 2009 13:07:44 -0300
Subject: V4L/DVB (11948): uvcvideo: Ignore non-UVC trailing interface
 descriptors.

Herton Ronaldo Krzesinski from Mandriva reported that one Bison Electronics
webcam exposes a non-UVC interface descriptor. Instead of failing completely,
ignore trailing non-UVC descriptors and move on.

Thanks to Herton for reporting the problem and submitting a patch proposal.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_driver.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index f7545126951..89927b7aec2 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -644,7 +644,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	_buflen = buflen;
 
 	/* Count the format and frame descriptors. */
-	while (_buflen > 2) {
+	while (_buflen > 2 && _buffer[1] == CS_INTERFACE) {
 		switch (_buffer[2]) {
 		case VS_FORMAT_UNCOMPRESSED:
 		case VS_FORMAT_MJPEG:
@@ -709,7 +709,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	streaming->nformats = nformats;
 
 	/* Parse the format descriptors. */
-	while (buflen > 2) {
+	while (buflen > 2 && buffer[1] == CS_INTERFACE) {
 		switch (buffer[2]) {
 		case VS_FORMAT_UNCOMPRESSED:
 		case VS_FORMAT_MJPEG:
-- 
cgit v1.2.3-70-g09d2


From 9d5af8629255ef6e62481ee7dea8c6787facc579 Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Tue, 9 Jun 2009 20:37:24 -0300
Subject: V4L/DVB (11950): cx18: Split LeadTek PVR2100 and DVR3100 H into 2
 separate card entries

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-cards.c  | 61 ++++++++++++++++++++++++++++++++--
 drivers/media/video/cx18/cx18-driver.c |  3 +-
 drivers/media/video/cx18/cx18-driver.h |  5 +--
 3 files changed, 63 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 9bc22183784..ae631aa2cd3 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -340,13 +340,12 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
 
 static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
 	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100   */
-	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
 	{ 0, 0, 0 }
 };
 
 static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 	.type = CX18_CARD_LEADTEK_PVR2100,
-	.name = "Leadtek WinFast PVR2100/DVR3100 H",
+	.name = "Leadtek WinFast PVR2100",
 	.comment = "Experimenters and photos needed for device to work well.\n"
 		  "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
@@ -365,7 +364,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
 	},
 	.tuners = {
-		/* XC3028 tuner */
+		/* XC2028 tuner */
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
@@ -392,6 +391,61 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 
 /* ------------------------------------------------------------------------- */
 
+/* Leadtek WinFast DVR3100 H */
+
+static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
+	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
+	{ 0, 0, 0 }
+};
+
+static const struct cx18_card cx18_card_leadtek_dvr3100h = {
+	.type = CX18_CARD_LEADTEK_DVR3100H,
+	.name = "Leadtek WinFast DVR3100 H",
+	.comment = "Experimenters and photos needed for device to work well.\n"
+		  "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
+	.v4l2_capabilities = CX18_CAP_ENCODER,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_muxer = CX18_HW_GPIO_MUX,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
+		  CX18_HW_GPIO_RESET_CTRL,
+	.video_inputs = {
+		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
+		{ CX18_CARD_INPUT_SVIDEO1,    1,
+			CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
+	},
+	.audio_inputs = {
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
+	},
+	.tuners = {
+		/* XC3028 tuner */
+		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+	},
+	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
+	.ddr = {
+		/*
+		 * Pointer to proper DDR config values provided by
+		 * Terry Wu <terrywu at leadtek.com.tw>
+		 */
+		.chip_config = 0x303,
+		.refresh = 0x3bb,
+		.timing1 = 0x24220e83,
+		.timing2 = 0x1f,
+		.tune_lane = 0,
+		.initial_emrs = 0x2,
+	},
+	.gpio_init.initial_value = 0x6,
+	.gpio_init.direction = 0x7,
+	.gpio_audio_input = { .mask   = 0x7,
+			      .tuner  = 0x6, .linein = 0x2, .radio  = 0x2 },
+	.xceive_pin = 15,
+	.pci_list = cx18_pci_leadtek_dvr3100h,
+	.i2c = &cx18_i2c_std,
+};
+
+/* ------------------------------------------------------------------------- */
+
 static const struct cx18_card *cx18_card_list[] = {
 	&cx18_card_hvr1600_esmt,
 	&cx18_card_hvr1600_samsung,
@@ -400,6 +454,7 @@ static const struct cx18_card *cx18_card_list[] = {
 	&cx18_card_cnxt_raptor_pal,
 	&cx18_card_toshiba_qosmio_dvbt,
 	&cx18_card_leadtek_pvr2100,
+	&cx18_card_leadtek_dvr3100h,
 };
 
 const struct cx18_card *cx18_get_card(u16 index)
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index bc6a8f9abd3..92026e82e10 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -152,7 +152,8 @@ MODULE_PARM_DESC(cardtype,
 		 "\t\t\t 4 = Yuan MPC718\n"
 		 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
 		 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
-		 "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n"
+		 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
+		 "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
 		 "\t\t\t 0 = Autodetect (default)\n"
 		 "\t\t\t-1 = Ignore this card\n\t\t");
 MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index f89b8236796..c6a1e907f63 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -80,8 +80,9 @@
 #define CX18_CARD_YUAN_MPC718 	      3	/* Yuan MPC718 */
 #define CX18_CARD_CNXT_RAPTOR_PAL     4	/* Conexant Raptor PAL */
 #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100     6 /* Leadtek WinFast PVR2100/DVR3100 H */
-#define CX18_CARD_LAST 		      6
+#define CX18_CARD_LEADTEK_PVR2100     6 /* Leadtek WinFast PVR2100 */
+#define CX18_CARD_LEADTEK_DVR3100H    7 /* Leadtek WinFast DVR3100 H */
+#define CX18_CARD_LAST 		      7
 
 #define CX18_ENC_STREAM_TYPE_MPG  0
 #define CX18_ENC_STREAM_TYPE_TS   1
-- 
cgit v1.2.3-70-g09d2


From 8bb09db375fe4f15d16315947500e827caa0fe9c Mon Sep 17 00:00:00 2001
From: Andy Walls <awalls@radix.net>
Date: Tue, 9 Jun 2009 20:47:21 -0300
Subject: V4L/DVB (11951): cx18: Add DVB-T support for the Leadtek WinFast
 DVR3100 H

This adds support for DVB-T on the Leadtek DVR3100 H and should also get analog
TV capture from the tuner working properly as well.

DVB-T 6 MHz and 8 MHz have been tested and verified to work by Terry Wu of
Leadtek.  DVB-T 7 MHz has also been verified working with a change developed by
Terry to the tuner-xc2028.c driver.

Special thanks go to Terry Wu <terrywu2009@gmail.com> of Leadtek who provided
the needed information and testing to get digital TV working for the Leadtek
DVR3100 H.

Reported-by: Terry Wu <terrywu2009@gmail.com>
Tested-by: Terry Wu <terrywu2009@gmail.com>
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-cards.c | 18 ++++--------
 drivers/media/video/cx18/cx18-dvb.c   | 53 +++++++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index ae631aa2cd3..c92a25036f0 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -369,10 +369,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
 	.ddr = {
-		/*
-		 * Pointer to proper DDR config values provided by
-		 * Terry Wu <terrywu at leadtek.com.tw>
-		 */
+		/* Pointer to proper DDR config values provided by Terry Wu */
 		.chip_config = 0x303,
 		.refresh = 0x3bb,
 		.timing1 = 0x24220e83,
@@ -401,13 +398,13 @@ static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
 static const struct cx18_card cx18_card_leadtek_dvr3100h = {
 	.type = CX18_CARD_LEADTEK_DVR3100H,
 	.name = "Leadtek WinFast DVR3100 H",
-	.comment = "Experimenters and photos needed for device to work well.\n"
-		  "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
+	.comment = "Simultaneous DVB-T and Analog capture supported,\n"
+		  "\texcept when capturing Analog from the antenna input.\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_GPIO_MUX,
 	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
-		  CX18_HW_GPIO_RESET_CTRL,
+		  CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
@@ -424,10 +421,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = {
 	},
 	.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
 	.ddr = {
-		/*
-		 * Pointer to proper DDR config values provided by
-		 * Terry Wu <terrywu at leadtek.com.tw>
-		 */
+		/* Pointer to proper DDR config values provided by Terry Wu */
 		.chip_config = 0x303,
 		.refresh = 0x3bb,
 		.timing1 = 0x24220e83,
@@ -439,7 +433,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = {
 	.gpio_init.direction = 0x7,
 	.gpio_audio_input = { .mask   = 0x7,
 			      .tuner  = 0x6, .linein = 0x2, .radio  = 0x2 },
-	.xceive_pin = 15,
+	.xceive_pin = 1,
 	.pci_list = cx18_pci_leadtek_dvr3100h,
 	.i2c = &cx18_i2c_std,
 };
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index e7285a1096f..6ea3fe623ef 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -26,12 +26,17 @@
 #include "cx18-queue.h"
 #include "cx18-streams.h"
 #include "cx18-cards.h"
+#include "cx18-gpio.h"
 #include "s5h1409.h"
 #include "mxl5005s.h"
+#include "zl10353.h"
+#include "tuner-xc2028.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
+#define CX18_CLOCK_ENABLE2		 0xc71024
+#define CX18_DMUX_CLK_MASK		 0x0080
 
 static struct mxl5005s_config hauppauge_hvr1600_tuner = {
 	.i2c_address     = 0xC6 >> 1,
@@ -58,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
 	.inversion     = S5H1409_INVERSION_OFF,
 	.status_mode   = S5H1409_DEMODLOCKING,
 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+};
 
+/* Information/confirmation of proper config values provided by Terry Wu */
+static struct zl10353_config leadtek_dvr3100h_demod = {
+	.demod_address         = 0x1e >> 1, /* Datasheet suggested straps */
+	.if2                   = 45600,     /* 4.560 MHz IF from the XC3028 */
+	.parallel_ts           = 1,         /* Not a serial TS */
+	.no_tuner              = 1,         /* XC3028 is not behind the gate */
+	.disable_i2c_gate_ctrl = 1,         /* Disable the I2C gate */
 };
 
 static int dvb_register(struct cx18_stream *stream);
@@ -99,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
 		cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
 		break;
 
+	case CX18_CARD_LEADTEK_DVR3100H:
 	default:
 		/* Assumption - Parallel transport - Signalling
 		 * undefined or default.
@@ -268,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
 }
 
 /* All the DVB attach calls go here, this function get's modified
- * for each new card. No other function in this file needs
- * to change.
+ * for each new card. cx18_dvb_start_feed() will also need changes.
  */
 static int dvb_register(struct cx18_stream *stream)
 {
@@ -290,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream)
 			ret = 0;
 		}
 		break;
+	case CX18_CARD_LEADTEK_DVR3100H:
+		dvb->fe = dvb_attach(zl10353_attach,
+				     &leadtek_dvr3100h_demod,
+				     &cx->i2c_adap[1]);
+		if (dvb->fe != NULL) {
+			struct dvb_frontend *fe;
+			struct xc2028_config cfg = {
+				.i2c_adap = &cx->i2c_adap[1],
+				.i2c_addr = 0xc2 >> 1,
+				.ctrl = NULL,
+			};
+			static struct xc2028_ctrl ctrl = {
+				.fname   = XC2028_DEFAULT_FIRMWARE,
+				.max_len = 64,
+				.demod   = XC3028_FE_ZARLINK456,
+				.type    = XC2028_AUTO,
+			};
+
+			fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
+			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
+				fe->ops.tuner_ops.set_config(fe, &ctrl);
+		}
+		break;
 	default:
 		/* No Digital Tv Support */
 		break;
@@ -300,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream)
 		return -1;
 	}
 
+	dvb->fe->callback = cx18_reset_tuner_gpio;
+
 	ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
 	if (ret < 0) {
 		if (dvb->fe->ops.release)
@@ -307,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream)
 		return ret;
 	}
 
+	/*
+	 * The firmware seems to enable the TS DMUX clock
+	 * under various circumstances.  However, since we know we
+	 * might use it, let's just turn it on ourselves here.
+	 */
+	cx18_write_reg_expect(cx,
+			      (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
+			      CX18_CLOCK_ENABLE2,
+			      CX18_DMUX_CLK_MASK,
+			      (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
+
 	return ret;
 }
-- 
cgit v1.2.3-70-g09d2


From 92051b285b12855255f0213d9a25153d917e262c Mon Sep 17 00:00:00 2001
From: "Figo.zhang" <figo1802@gmail.com>
Date: Wed, 10 Jun 2009 23:17:27 -0300
Subject: V4L/DVB (11953): videobuf-dma-sg: return -ENOMEM if vmalloc fails

it is better return -ENOMEM than -EIO

Signed-off-by: Figo.zhang <figo1802@gmail.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/videobuf-dma-sg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index c9a5d7edbe4..a8dd22ace3f 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -252,7 +252,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
 			vfree(dma->sglist);
 			dma->sglist = NULL;
 			dma->sglen = 0;
-			return -EIO;
+			return -ENOMEM;
 		}
 	}
 	return 0;
-- 
cgit v1.2.3-70-g09d2


From 5e2c217eee18a4627a32c49f57f47dbac67dcf23 Mon Sep 17 00:00:00 2001
From: "Figo.zhang" <figo1802@gmail.com>
Date: Thu, 11 Jun 2009 10:33:31 -0300
Subject: V4L/DVB (11958): usbvision-core.c: vfree does its own NULL check

vfree() does it's own NULL checking,so no need for check before
calling it.

Signed-off-by: Figo.zhang <figo1802@gmail.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/usbvision/usbvision-core.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 8bc03b9e131..6ba16abeebd 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -390,10 +390,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
 
 void usbvision_scratch_free(struct usb_usbvision *usbvision)
 {
-	if (usbvision->scratch != NULL) {
-		vfree(usbvision->scratch);
-		usbvision->scratch = NULL;
-	}
+	vfree(usbvision->scratch);
+	usbvision->scratch = NULL;
+
 }
 
 /*
@@ -506,10 +505,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
  */
 void usbvision_decompress_free(struct usb_usbvision *usbvision)
 {
-	if (usbvision->IntraFrameBuffer != NULL) {
-		vfree(usbvision->IntraFrameBuffer);
-		usbvision->IntraFrameBuffer = NULL;
-	}
+	vfree(usbvision->IntraFrameBuffer);
+	usbvision->IntraFrameBuffer = NULL;
+
 }
 
 /************************************************************
-- 
cgit v1.2.3-70-g09d2


From 6f4d72392d76b8f78f646805ba2be995b3f77992 Mon Sep 17 00:00:00 2001
From: Alan Cox <alan@linux.intel.com>
Date: Thu, 11 Jun 2009 11:04:11 -0300
Subject: V4L/DVB (11959): se401: Fix unsafe use of sprintf with identical
 source/destination

Closes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=13435

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/se401.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 5990ab38a12..08129a830d6 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1244,17 +1244,18 @@ static int se401_init(struct usb_se401 *se401, int button)
 	int i=0, rc;
 	unsigned char cp[0x40];
 	char temp[200];
+	int slen;
 
 	/* led on */
 	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
 
 	/* get camera descriptor */
 	rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
-	if (cp[1]!=0x41) {
+	if (cp[1] != 0x41) {
 		err("Wrong descriptor type");
 		return 1;
 	}
-	sprintf (temp, "ExtraFeatures: %d", cp[3]);
+	slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
 
 	se401->sizes=cp[4]+cp[5]*256;
 	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
@@ -1269,9 +1270,10 @@ static int se401_init(struct usb_se401 *se401, int button)
 		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
 		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
 	}
-	sprintf (temp, "%s Sizes:", temp);
+	slen += snprintf (temp + slen, 200 - slen, " Sizes:");
 	for (i=0; i<se401->sizes; i++) {
-		sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
+		slen += snprintf(temp + slen, 200 - slen,
+			" %dx%d", se401->width[i], se401->height[i]);
 	}
 	dev_info(&se401->dev->dev, "%s\n", temp);
 	se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
-- 
cgit v1.2.3-70-g09d2


From bcd3e4b3190f0cc4e0702785220f0269f8537175 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mzxreary@0pointer.de>
Date: Thu, 11 Jun 2009 11:19:33 -0300
Subject: V4L/DVB (11960): v4l: generate KEY_CAMERA instead of BTN_0 key events
 on input devices

A bunch of V4L drivers generate BTN_0 instead of KEY_CAMERA key presses.

X11 is able to handle KEY_CAMERA automatically these days while BTN_0 is
not treated at all.  Thus it would be of big benefit if the camera drivers
would consistently generate KEY_CAMERA.  Some drivers (uvc) already do,
this patch updates the remaining drivers to do the same.

I only possess a limited set of webcams, so this isn't tested with all
cameras.  The patch is rather trivial and compile tested, so I'd say it's
still good enough to get merged.

Signed-off-by: Lennart Poettering <mzxreary@0pointer.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pwc/pwc-if.c                  | 4 ++--
 drivers/media/video/usbvideo/konicawc.c           | 4 ++--
 drivers/media/video/usbvideo/quickcam_messenger.c | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 7c542caf248..519a965de23 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -601,7 +601,7 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down)
 
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 	if (pdev->button_dev) {
-		input_report_key(pdev->button_dev, BTN_0, down);
+		input_report_key(pdev->button_dev, KEY_CAMERA, down);
 		input_sync(pdev->button_dev);
 	}
 #endif
@@ -1847,7 +1847,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	usb_to_input_id(pdev->udev, &pdev->button_dev->id);
 	pdev->button_dev->dev.parent = &pdev->udev->dev;
 	pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
-	pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+	pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
 
 	rc = input_register_device(pdev->button_dev);
 	if (rc) {
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 900ec2129ca..31d57f2d09e 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -240,7 +240,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
 	input_dev->dev.parent = &dev->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY);
-	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+	input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
 
 	error = input_register_device(cam->input);
 	if (error) {
@@ -263,7 +263,7 @@ static void konicawc_unregister_input(struct konicawc *cam)
 static void konicawc_report_buttonstat(struct konicawc *cam)
 {
 	if (cam->input) {
-		input_report_key(cam->input, BTN_0, cam->buttonsts);
+		input_report_key(cam->input, KEY_CAMERA, cam->buttonsts);
 		input_sync(cam->input);
 	}
 }
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index fd112f0b9d3..803d3e4e29a 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -103,7 +103,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
 	input_dev->dev.parent = &dev->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY);
-	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+	input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
 
 	error = input_register_device(cam->input);
 	if (error) {
@@ -126,7 +126,7 @@ static void qcm_unregister_input(struct qcm *cam)
 static void qcm_report_buttonstat(struct qcm *cam)
 {
 	if (cam->input) {
-		input_report_key(cam->input, BTN_0, cam->button_sts);
+		input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
 		input_sync(cam->input);
 	}
 }
-- 
cgit v1.2.3-70-g09d2


From 76b08116458c4dbc1e1c40f78bc087fc4f3c8969 Mon Sep 17 00:00:00 2001
From: Roel Kluin <roel.kluin@gmail.com>
Date: Thu, 11 Jun 2009 11:28:17 -0300
Subject: V4L/DVB (11961): tvp514x: try_count off by one

With `while (try_count-- > 0)' try_count reaches -1 after the loop.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tvp514x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 4262e60b811..3750f7fadb1 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -692,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
 			break;	/* Input detected */
 	}
 
-	if ((current_std == STD_INVALID) || (try_count <= 0))
+	if ((current_std == STD_INVALID) || (try_count < 0))
 		return -EINVAL;
 
 	decoder->current_std = current_std;
-- 
cgit v1.2.3-70-g09d2


From 163fe744c3283fd267268629afff4cfc846ed0e0 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Mon, 15 Jun 2009 10:04:00 -0300
Subject: V4L/DVB (11966): ov511: Fix unit_video parameter behavior

Fix a regression caused by changeset 9133:64aed7485a43 - v4l: disconnect
kernel number from minor

Before the above changeset, ov511_probe used to allow forcing to use a
certain specific set of video devices, like:

modprobe ov511 unit_video=4,1,3 num_uv=3

So, assuming that you have 5 ov511 devices, and connect they one by one,
they'll gain the following device numbers (at the connection order):
/dev/video4
/dev/video1
/dev/video3
/dev/video0
/dev/video2

However, this was changed due to this change at video_register_device():

+ nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr);

With the previous behavior, a trial to register on an already allocated mirror
would fail, and a loop would get the next requested minor. However, the current
behavior is to get the next available minor instead of failing. Due to that,
this means that the above modprobe parameter will give, instead:

/dev/video5
/dev/video6
/dev/video7
/dev/video8
/dev/video9

In order to restore the original behavior, a static var were added,
storing the amount of already registered devices.

While there, it also fixes the locking of the probe/disconnect functions.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ov511.c | 45 +++++++++++++++++++++++++++++++--------------
 drivers/media/video/ov511.h |  3 +++
 2 files changed, 34 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 9af5532db14..08cfd3e4ae8 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -112,6 +112,8 @@ static int framedrop		= -1;
 static int fastset;
 static int force_palette;
 static int backlight;
+/* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */
+static unsigned long ov511_devused;
 static int unit_video[OV511_MAX_UNIT_VIDEO];
 static int remove_zeros;
 static int mirror;
@@ -5720,7 +5722,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *idesc;
 	struct usb_ov511 *ov;
-	int i;
+	int i, rc, nr;
 
 	PDEBUG(1, "probing for device...");
 
@@ -5845,33 +5847,41 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	ov->vdev->parent = &intf->dev;
 	video_set_drvdata(ov->vdev, ov);
 
-	for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
-		/* Minor 0 cannot be specified; assume user wants autodetect */
-		if (unit_video[i] == 0)
-			break;
+	mutex_lock(&ov->lock);
 
-		if (video_register_device(ov->vdev, VFL_TYPE_GRABBER,
-			unit_video[i]) >= 0) {
-			break;
-		}
-	}
+	/* Check to see next free device and mark as used */
+	nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO);
+
+	/* Registers device */
+	if (unit_video[nr] != 0)
+		rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER,
+					   unit_video[nr]);
+	else
+		rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1);
 
-	/* Use the next available one */
-	if ((ov->vdev->minor == -1) &&
-	    video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
+	if (rc < 0) {
 		err("video_register_device failed");
+		mutex_unlock(&ov->lock);
 		goto error;
 	}
 
+	/* Mark device as used */
+	ov511_devused |= 1 << nr;
+	ov->nr = nr;
+
 	dev_info(&intf->dev, "Device at %s registered to minor %d\n",
 		 ov->usb_path, ov->vdev->minor);
 
 	usb_set_intfdata(intf, ov);
 	if (ov_create_sysfs(ov->vdev)) {
 		err("ov_create_sysfs failed");
+		ov511_devused &= ~(1 << nr);
+		mutex_unlock(&ov->lock);
 		goto error;
 	}
 
+	mutex_lock(&ov->lock);
+
 	return 0;
 
 error:
@@ -5906,10 +5916,16 @@ ov51x_disconnect(struct usb_interface *intf)
 
 	PDEBUG(3, "");
 
+	mutex_lock(&ov->lock);
 	usb_set_intfdata (intf, NULL);
 
-	if (!ov)
+	if (!ov) {
+		mutex_unlock(&ov->lock);
 		return;
+	}
+
+	/* Free device number */
+	ov511_devused &= ~(1 << ov->nr);
 
 	if (ov->vdev)
 		video_unregister_device(ov->vdev);
@@ -5927,6 +5943,7 @@ ov51x_disconnect(struct usb_interface *intf)
 
 	ov->streaming = 0;
 	ov51x_unlink_isoc(ov);
+	mutex_unlock(&ov->lock);
 
 	ov->dev = NULL;
 
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 70d99e52329..c450c92468d 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -494,6 +494,9 @@ struct usb_ov511 {
 	int has_decoder;	/* Device has a video decoder */
 	int pal;		/* Device is designed for PAL resolution */
 
+	/* ov511 device number ID */
+	int nr;			/* Stores a device number */
+
 	/* I2C interface */
 	struct mutex i2c_lock;	  /* Protect I2C controller regs */
 	unsigned char primary_i2c_slave;  /* I2C write id of sensor */
-- 
cgit v1.2.3-70-g09d2


From df59f0b3df3cc35fa03ea395f5106d1625e3726a Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Fri, 12 Jun 2009 03:38:15 -0300
Subject: V4L/DVB (11967): v4l: i2c modules must be linked before the v4l2
 drivers

Since i2c autoprobing is no longer supported by v4l2 we need to make sure
that the i2c modules are linked before the v4l2 modules. The v4l2 modules
now rely on the presence of the i2c modules, so these must have initialized
themselves before the v4l2 modules.

The exception is the ir-kbd-i2c module, which is the only one still using
autoprobing. This one should be loaded at the end of the v4l2 module. Loading
it earlier actually causes problems with tveeprom. Once ir-kbd-i2c is no
longer autoprobing, then it has to move up as well.

This is only an issue when everything is compiled into the kernel.

Thanks to Marcus Swoboda for reporting this and Udo Steinberg for testing
this patch.

Tested-by: Udo A. Steinberg <udo@hypervisor.org>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Makefile         | 70 +++++++++++++++++++-----------------
 drivers/media/video/saa7134/Makefile |  3 +-
 2 files changed, 38 insertions(+), 35 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index f7d9a4c6f45..7fb3add1b38 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -12,6 +12,8 @@ omap2cam-objs	:=	omap24xxcam.o omap24xxcam-dma.o
 
 videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o
 
+# V4L2 core modules
+
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
 ifeq ($(CONFIG_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
 endif
 
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+# All i2c modules must come first:
 
-obj-$(CONFIG_VIDEO_BT848) += bt8xx/
-obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
 obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
 obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
-
 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
 obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
 obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_W9966) += w9966.o
-
 obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
 obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
 obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
@@ -56,11 +52,40 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
 obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_VINO) += indycam.o
+obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
+obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
+obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
+obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+obj-$(CONFIG_VIDEO_M52790) += m52790.o
+obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
+obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
+obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
+obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
+obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
+obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
+obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
+obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
+obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
+
+# And now the v4l2 drivers:
 
+obj-$(CONFIG_VIDEO_BT848) += bt8xx/
+obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
+obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
+obj-$(CONFIG_VIDEO_W9966) += w9966.o
 obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
+obj-$(CONFIG_VIDEO_VINO) += vino.o
 obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
@@ -71,17 +96,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
-obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
-obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
-obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
-obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
-obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
-obj-$(CONFIG_VIDEO_M52790) += m52790.o
-obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
-obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
-obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
-obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
 obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
 obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
 obj-$(CONFIG_VIDEO_MXB) += mxb.o
@@ -94,19 +109,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
 obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
 obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
-obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
-obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
-obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
 
 obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
-obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
-
-obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
 
 obj-$(CONFIG_USB_DABUSB)        += dabusb.o
 obj-$(CONFIG_USB_OV511)         += ov511.o
@@ -138,13 +146,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
 obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
-obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
-obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
-obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
-obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
-obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
 obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
-obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
 # soc-camera host drivers have to be linked after camera drivers
 obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
 obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
@@ -155,6 +157,8 @@ obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)	+= uvc/
 
+obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index 3dbaa19a6d0..604158a8c23 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,8 +3,7 @@ saa7134-objs :=	saa7134-cards.o saa7134-core.o saa7134-i2c.o	\
 		saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o    \
 		saa7134-video.o saa7134-input.o
 
-obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o \
-				saa6752hs.o
+obj-$(CONFIG_VIDEO_SAA7134) +=  saa6752hs.o saa7134.o saa7134-empress.o
 
 obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
 
-- 
cgit v1.2.3-70-g09d2


From 253f13d5cd05204aa3174ffb53490f2b0fad055c Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Fri, 29 May 2009 04:46:12 -0300
Subject: V4L/DVB (11969): gspca - spca505: Reinitialize the webcam at resume
 time.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/spca505.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2acec58b1b9..ea8c9fe2e96 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
 	sd->brightness = BRIGHTNESS_DEF;
 
-	if (sd->subtype == Nxultra) {
-		if (write_vector(gspca_dev, spca505b_init_data))
-			return -EIO;
-	} else {
-		if (write_vector(gspca_dev, spca505_init_data))
-			return -EIO;
-	}
 	return 0;
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (write_vector(gspca_dev,
+			 sd->subtype == Nxultra
+				? spca505b_init_data
+				: spca505_init_data))
+		return -EIO;
 	return 0;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 49809d6a511960e5ccfb85b780894f45ac119065 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 7 Jun 2009 12:10:39 -0300
Subject: V4L/DVB (11970): gspca - ov519: Add support for the ov518 bridge.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 520 +++++++++++++++++++++++++++++++++++---
 include/linux/videodev2.h         |   3 +-
 2 files changed, 488 insertions(+), 35 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1fff37b7989..188866ac6ce 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10;
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
+	char bridge;
+#define BRIDGE_OV511		0
+#define BRIDGE_OV511PLUS	1
+#define BRIDGE_OV518		2
+#define BRIDGE_OV518PLUS	3
+#define BRIDGE_OV519		4
+
 	/* Determined by sensor type */
 	__u8 sif;
 
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static void setbrightness(struct gspca_dev *gspca_dev);
+static void setcontrast(struct gspca_dev *gspca_dev);
+static void setcolors(struct gspca_dev *gspca_dev);
 
 static struct ctrl sd_ctrls[] = {
 	{
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
 	},
 };
 
-static const struct v4l2_pix_format vga_mode[] = {
+static const struct v4l2_pix_format ov519_vga_mode[] = {
 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 320,
 		.sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = {
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
 };
-static const struct v4l2_pix_format sif_mode[] = {
+static const struct v4l2_pix_format ov519_sif_mode[] = {
 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 176,
 		.sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = {
 		.priv = 0},
 };
 
+static const struct v4l2_pix_format ov518_vga_mode[] = {
+	{320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 1},
+	{640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ov518_sif_mode[] = {
+	{176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 40000,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 1},
+	{352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+
+
+/* Registers common to OV511 / OV518 */
+#define R51x_SYS_RESET          	0x50
+#define R51x_SYS_INIT         		0x53
+#define R51x_SYS_SNAP			0x52
+#define R51x_SYS_CUST_ID		0x5F
+#define R51x_COMP_LUT_BEGIN		0x80
+
+/* OV511 Camera interface register numbers */
+#define R511_SYS_LED_CTL		0x55	/* OV511+ only */
+#define	OV511_RESET_NOREGS		0x3F	/* All but OV511 & regs */
+
+/* OV518 Camera interface register numbers */
+#define R518_GPIO_OUT			0x56	/* OV518(+) only */
+#define R518_GPIO_CTL			0x57	/* OV518(+) only */
+
 /* OV519 Camera interface register numbers */
 #define OV519_R10_H_SIZE		0x10
 #define OV519_R11_V_SIZE		0x11
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = {
 
 /* OV7610 registers */
 #define OV7610_REG_GAIN		0x00	/* gain setting (5:0) */
+#define OV7610_REG_BLUE		0x01	/* blue channel balance */
+#define OV7610_REG_RED		0x02	/* red channel balance */
 #define OV7610_REG_SAT		0x03	/* saturation */
 #define OV8610_REG_HUE		0x04	/* 04 reserved */
 #define OV7610_REG_CNT		0x05	/* Y contrast */
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
 static int reg_w(struct sd *sd, __u16 index, __u8 value)
 {
 	int ret;
+	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
 
 	sd->gspca_dev.usb_buf[0] = value;
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
-			1,			/* REQ_IO (ov518/519) */
+			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			sd->gspca_dev.usb_buf, 1, 500);
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
 static int reg_r(struct sd *sd, __u16 index)
 {
 	int ret;
+	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
 
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
-			1,			/* REQ_IO */
+			req,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, sd->gspca_dev.usb_buf, 1, 500);
 
@@ -923,6 +978,28 @@ static int reg_w_mask(struct sd *sd,
 	return reg_w(sd, index, value);
 }
 
+/*
+ * Writes multiple (n) byte value to a single register. Only valid with certain
+ * registers (0x30 and 0xc4 - 0xce).
+ */
+static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
+{
+	int ret;
+
+	*((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
+
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+			1 /* REG_IO */,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, index,
+			sd->gspca_dev.usb_buf, n, 500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
+	return ret;
+}
+
+
 /*
  * The OV518 I2C I/O procedure is different, hence, this function.
  * This is normally only called from i2c_w(). Note that this function
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd)
 {
 	PDEBUG(D_STREAM, "stopping");
 	sd->stopped = 1;
-	return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		return reg_w(sd, R51x_SYS_RESET, 0x3d);
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+	case BRIDGE_OV519:
+		return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+	}
+
+	return 0;
 }
 
 /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
  * actually stopped (for performance). */
 static inline int ov51x_restart(struct sd *sd)
 {
+	int rc;
+
 	PDEBUG(D_STREAM, "restarting");
 	if (!sd->stopped)
 		return 0;
 	sd->stopped = 0;
 
 	/* Reinitialize the stream */
-	return reg_w(sd, OV519_SYS_RESET1, 0x00);
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		return reg_w(sd, R51x_SYS_RESET, 0x00);
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		rc = reg_w(sd, 0x2f, 0x80);
+		if (rc < 0)
+			return rc;
+		return reg_w(sd, R51x_SYS_RESET, 0x00);
+	case BRIDGE_OV519:
+		return reg_w(sd, OV519_SYS_RESET1, 0x00);
+	}
+
+	return 0;
 }
 
 /* This does an initial reset of an OmniVision sensor and ensures that I2C
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd)
 /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
 static void ov51x_led_control(struct sd *sd, int on)
 {
-	reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1);	/* 0 / 1 */
+	switch (sd->bridge) {
+	/* OV511 has no LED control */
+	case BRIDGE_OV511PLUS:
+		reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
+		break;
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
+		break;
+	case BRIDGE_OV519:
+		reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1);	/* 0 / 1 */
+		break;
+	}
 }
 
-/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
-			const struct usb_device_id *id)
+/* OV518 quantization tables are 8x4 (instead of 8x8) */
+static int ov518_upload_quan_tables(struct sd *sd)
+{
+	const unsigned char yQuanTable518[] = {
+		5, 4, 5, 6, 6, 7, 7, 7,
+		5, 5, 5, 5, 6, 7, 7, 7,
+		6, 6, 6, 6, 7, 7, 7, 8,
+		7, 7, 6, 7, 7, 7, 8, 8
+	};
+
+	const unsigned char uvQuanTable518[] = {
+		6, 6, 6, 7, 7, 7, 7, 7,
+		6, 6, 6, 7, 7, 7, 7, 7,
+		6, 6, 6, 7, 7, 7, 7, 8,
+		7, 7, 7, 7, 7, 7, 8, 8
+	};
+
+	const unsigned char *pYTable = yQuanTable518;
+	const unsigned char *pUVTable = uvQuanTable518;
+	unsigned char val0, val1;
+	int i, rc, reg = R51x_COMP_LUT_BEGIN;
+
+	PDEBUG(D_PROBE, "Uploading quantization tables");
+
+	for (i = 0; i < 16; i++) {
+		val0 = *pYTable++;
+		val1 = *pYTable++;
+		val0 &= 0x0f;
+		val1 &= 0x0f;
+		val0 |= val1 << 4;
+		rc = reg_w(sd, reg, val0);
+		if (rc < 0)
+			return rc;
+
+		val0 = *pUVTable++;
+		val1 = *pUVTable++;
+		val0 &= 0x0f;
+		val1 &= 0x0f;
+		val0 |= val1 << 4;
+		rc = reg_w(sd, reg + 16, val0);
+		if (rc < 0)
+			return rc;
+
+		reg++;
+	}
+
+	return 0;
+}
+
+/* This initializes the OV518/OV518+ and the sensor */
+static int ov518_configure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct cam *cam;
+	int rc;
+
+	/* For 518 and 518+ */
+	static struct ov_regvals init_518[] = {
+		{ R51x_SYS_RESET,	0x40 },
+		{ R51x_SYS_INIT,	0xe1 },
+		{ R51x_SYS_RESET,	0x3e },
+		{ R51x_SYS_INIT,	0xe1 },
+		{ R51x_SYS_RESET,	0x00 },
+		{ R51x_SYS_INIT,	0xe1 },
+		{ 0x46,			0x00 },
+		{ 0x5d,			0x03 },
+	};
+
+	static struct ov_regvals norm_518[] = {
+		{ R51x_SYS_SNAP,	0x02 }, /* Reset */
+		{ R51x_SYS_SNAP,	0x01 }, /* Enable */
+		{ 0x31, 		0x0f },
+		{ 0x5d,			0x03 },
+		{ 0x24,			0x9f },
+		{ 0x25,			0x90 },
+		{ 0x20,			0x00 },
+		{ 0x51,			0x04 },
+		{ 0x71,			0x19 },
+		{ 0x2f,			0x80 },
+	};
+
+	static struct ov_regvals norm_518_p[] = {
+		{ R51x_SYS_SNAP,	0x02 }, /* Reset */
+		{ R51x_SYS_SNAP,	0x01 }, /* Enable */
+		{ 0x31, 		0x0f },
+		{ 0x5d,			0x03 },
+		{ 0x24,			0x9f },
+		{ 0x25,			0x90 },
+		{ 0x20,			0x60 },
+		{ 0x51,			0x02 },
+		{ 0x71,			0x19 },
+		{ 0x40,			0xff },
+		{ 0x41,			0x42 },
+		{ 0x46,			0x00 },
+		{ 0x33,			0x04 },
+		{ 0x21,			0x19 },
+		{ 0x3f,			0x10 },
+		{ 0x2f,			0x80 },
+	};
+
+	/* First 5 bits of custom ID reg are a revision ID on OV518 */
+	PDEBUG(D_PROBE, "Device revision %d",
+	       0x1F & reg_r(sd, R51x_SYS_CUST_ID));
+
+	rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
+	if (rc < 0)
+		return rc;
+
+	/* Set LED GPIO pin to output mode */
+	rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
+	if (rc < 0)
+		return rc;
 
+	switch (sd->bridge) {
+	case BRIDGE_OV518:
+		rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
+		if (rc < 0)
+			return rc;
+		break;
+	case BRIDGE_OV518PLUS:
+		rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
+		if (rc < 0)
+			return rc;
+		break;
+	}
+
+	rc = ov518_upload_quan_tables(sd);
+	if (rc < 0) {
+		PDEBUG(D_ERR, "Error uploading quantization tables");
+		return rc;
+	}
+
+	rc = reg_w(sd, 0x2f, 0x80);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static int ov519_configure(struct sd *sd)
+{
 	static const struct ov_regvals init_519[] = {
 		{ 0x5a,  0x6d }, /* EnableSystem */
 		{ 0x53,  0x9b },
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		/* windows reads 0x55 at this point*/
 	};
 
-	if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
+	return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam;
+	int ret = 0;
+
+	sd->bridge = id->driver_info;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		ret = ov518_configure(gspca_dev);
+		break;
+	case BRIDGE_OV519:
+		ret = ov519_configure(sd);
+		break;
+	}
+
+	if (ret)
 		goto error;
+
 	ov51x_led_control(sd, 0);	/* turn LED off */
 
 	/* Test for 76xx */
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	}
 
 	cam = &gspca_dev->cam;
-	if (!sd->sif) {
-		cam->cam_mode = vga_mode;
-		cam->nmodes = ARRAY_SIZE(vga_mode);
-	} else {
-		cam->cam_mode = sif_mode;
-		cam->nmodes = ARRAY_SIZE(sif_mode);
+	switch (sd->bridge) {
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		if (!sd->sif) {
+			cam->cam_mode = ov518_vga_mode;
+			cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
+		} else {
+			cam->cam_mode = ov518_sif_mode;
+			cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
+		}
+		break;
+	case BRIDGE_OV519:
+		if (!sd->sif) {
+			cam->cam_mode = ov519_vga_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+		} else {
+			cam->cam_mode = ov519_sif_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
+		}
+		break;
 	}
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	return 0;
 }
 
+/* Sets up the OV518/OV518+ with the given image parameters
+ *
+ * OV518 needs a completely different approach, until we can figure out what
+ * the individual registers do. Also, only 15 FPS is supported now.
+ *
+ * Do not put any sensor-specific code in here (including I2C I/O functions)
+ */
+static int ov518_mode_init_regs(struct sd *sd)
+{
+	int hsegs, vsegs;
+
+	/******** Set the mode ********/
+
+	reg_w(sd, 0x2b, 0);
+	reg_w(sd, 0x2c, 0);
+	reg_w(sd, 0x2d, 0);
+	reg_w(sd, 0x2e, 0);
+	reg_w(sd, 0x3b, 0);
+	reg_w(sd, 0x3c, 0);
+	reg_w(sd, 0x3d, 0);
+	reg_w(sd, 0x3e, 0);
+
+	if (sd->bridge == BRIDGE_OV518) {
+		/* Set 8-bit (YVYU) input format */
+		reg_w_mask(sd, 0x20, 0x08, 0x08);
+
+		/* Set 12-bit (4:2:0) output format */
+		reg_w_mask(sd, 0x28, 0x80, 0xf0);
+		reg_w_mask(sd, 0x38, 0x80, 0xf0);
+	} else {
+		reg_w(sd, 0x28, 0x80);
+		reg_w(sd, 0x38, 0x80);
+	}
+
+	hsegs = sd->gspca_dev.width / 16;
+	vsegs = sd->gspca_dev.height / 4;
+
+	reg_w(sd, 0x29, hsegs);
+	reg_w(sd, 0x2a, vsegs);
+
+	reg_w(sd, 0x39, hsegs);
+	reg_w(sd, 0x3a, vsegs);
+
+	/* Windows driver does this here; who knows why */
+	reg_w(sd, 0x2f, 0x80);
+
+	/******** Set the framerate (to 30 FPS) ********/
+	if (sd->bridge == BRIDGE_OV518PLUS)
+		sd->clockdiv = 1;
+	else
+		sd->clockdiv = 0;
+
+	/* Mode independent, but framerate dependent, regs */
+	reg_w(sd, 0x51, 0x04);	/* Clock divider; lower==faster */
+	reg_w(sd, 0x22, 0x18);
+	reg_w(sd, 0x23, 0xff);
+
+	if (sd->bridge == BRIDGE_OV518PLUS)
+		reg_w(sd, 0x21, 0x19);
+	else
+		reg_w(sd, 0x71, 0x17);	/* Compression-related? */
+
+	/* FIXME: Sensor-specific */
+	/* Bit 5 is what matters here. Of course, it is "reserved" */
+	i2c_w(sd, 0x54, 0x23);
+
+	reg_w(sd, 0x2f, 0x80);
+
+	if (sd->bridge == BRIDGE_OV518PLUS) {
+		reg_w(sd, 0x24, 0x94);
+		reg_w(sd, 0x25, 0x90);
+		ov518_reg_w32(sd, 0xc4,    400, 2);	/* 190h   */
+		ov518_reg_w32(sd, 0xc6,    540, 2);	/* 21ch   */
+		ov518_reg_w32(sd, 0xc7,    540, 2);	/* 21ch   */
+		ov518_reg_w32(sd, 0xc8,    108, 2);	/* 6ch    */
+		ov518_reg_w32(sd, 0xca, 131098, 3);	/* 2001ah */
+		ov518_reg_w32(sd, 0xcb,    532, 2);	/* 214h   */
+		ov518_reg_w32(sd, 0xcc,   2400, 2);	/* 960h   */
+		ov518_reg_w32(sd, 0xcd,     32, 2);	/* 20h    */
+		ov518_reg_w32(sd, 0xce,    608, 2);	/* 260h   */
+	} else {
+		reg_w(sd, 0x24, 0x9f);
+		reg_w(sd, 0x25, 0x90);
+		ov518_reg_w32(sd, 0xc4,    400, 2);	/* 190h   */
+		ov518_reg_w32(sd, 0xc6,    381, 2);	/* 17dh   */
+		ov518_reg_w32(sd, 0xc7,    381, 2);	/* 17dh   */
+		ov518_reg_w32(sd, 0xc8,    128, 2);	/* 80h    */
+		ov518_reg_w32(sd, 0xca, 183331, 3);	/* 2cc23h */
+		ov518_reg_w32(sd, 0xcb,    746, 2);	/* 2eah   */
+		ov518_reg_w32(sd, 0xcc,   1750, 2);	/* 6d6h   */
+		ov518_reg_w32(sd, 0xcd,     45, 2);	/* 2dh    */
+		ov518_reg_w32(sd, 0xce,    851, 2);	/* 353h   */
+	}
+
+	reg_w(sd, 0x2f, 0x80);
+
+	return 0;
+}
+
+
 /* Sets up the OV519 with the given image parameters
  *
  * OV519 needs a completely different approach, until we can figure out what
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd)
 		hwebase = 0x3a;
 		vwsbase = 0x05;
 		vwebase = 0x06;
+		if (qvga) {
+			/* HDG: this fixes U and V getting swapped */
+			hwsbase--;
+			vwsbase--;
+		}
 		break;
 	case SEN_OV7620:
 		hwsbase = 0x2f;		/* From 7620.SET (spec is wrong) */
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd)
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
+	int ret = 0;
 
-	ret = ov519_mode_init_regs(sd);
+	switch (sd->bridge) {
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		ret = ov518_mode_init_regs(sd);
+		break;
+	case BRIDGE_OV519:
+		ret = ov519_mode_init_regs(sd);
+		break;
+	}
 	if (ret < 0)
 		goto out;
+
 	ret = set_ov_sensor_window(sd);
 	if (ret < 0)
 		goto out;
 
+	setcontrast(gspca_dev);
+	setbrightness(gspca_dev);
+	setcolors(gspca_dev);
+
 	ret = ov51x_restart(sd);
 	if (ret < 0)
 		goto out;
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 	ov51x_led_control(sd, 0);
 }
 
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
+			struct gspca_frame *frame,	/* target */
+			__u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len);
+
+	if (len & 7) {
+		len--;
+		PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]);
+	}
+
+	/* A false positive here is likely, until OVT gives me
+	 * the definitive SOF/EOF format */
+	if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
+		gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+	}
+
+	/* intermediate packet */
+	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			data, len);
 }
 
+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 (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		break;
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+		ov518_pkt_scan(gspca_dev, frame, data, len);
+		break;
+	case BRIDGE_OV519:
+		ov519_pkt_scan(gspca_dev, frame, data, len);
+		break;
+	}
+}
+
 /* -- management routines -- */
 
 static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 		break;
 	case SEN_OV6630:
 		i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
+		break;
 	case SEN_OV8610: {
 		static const __u8 ctab[] = {
 			0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
-	{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)},
+	{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
+	{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
 	{}
 };
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index ebb2ea6b499..f24eceecc5a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -347,7 +347,8 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
 #define V4L2_PIX_FMT_SQ905C   v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
 #define V4L2_PIX_FMT_PJPG     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
-#define V4L2_PIX_FMT_YVYU    v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16  YVU 4:2:2     */
+#define V4L2_PIX_FMT_YVYU     v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
+#define V4L2_PIX_FMT_OV518    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
-- 
cgit v1.2.3-70-g09d2


From a0001a289f667e254eba51f2f729ec677daba503 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Jun 2009 04:52:18 -0300
Subject: V4L/DVB (11972): gspca - main: Skip disabled controls.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 122 +++++++++++++++++++-------------------
 1 file changed, 61 insertions(+), 61 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index ae0e14033d6..f1108f1be83 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -983,43 +983,54 @@ out:
 	return ret;
 }
 
+static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev,
+				   int id)
+{
+	const struct ctrl *ctrls;
+	int i;
+
+	for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
+	     i < gspca_dev->sd_desc->nctrls;
+	     i++, ctrls++) {
+		if (gspca_dev->ctrl_dis & (1 << i))
+			continue;
+		if (id == ctrls->qctrl.id)
+			return ctrls;
+	}
+	return NULL;
+}
+
 static int vidioc_queryctrl(struct file *file, void *priv,
 			   struct v4l2_queryctrl *q_ctrl)
 {
 	struct gspca_dev *gspca_dev = priv;
-	int i, ix;
+	const struct ctrl *ctrls;
+	int i;
 	u32 id;
 
-	ix = -1;
+	ctrls = NULL;
 	id = q_ctrl->id;
 	if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
 		id &= V4L2_CTRL_ID_MASK;
 		id++;
 		for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
-			if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
+			if (gspca_dev->ctrl_dis & (1 << i))
 				continue;
-			if (ix < 0) {
-				ix = i;
+			if (ctrls->qctrl.id < id)
 				continue;
+			if (ctrls != NULL) {
+				if (gspca_dev->sd_desc->ctrls[i].qctrl.id
+					    > ctrls->qctrl.id)
+					continue;
 			}
-			if (gspca_dev->sd_desc->ctrls[i].qctrl.id
-				    > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
-				continue;
-			ix = i;
-		}
-	}
-	for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
-		if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
-			ix = i;
-			break;
+			ctrls = &gspca_dev->sd_desc->ctrls[i];
 		}
+	} else {
+		ctrls = get_ctrl(gspca_dev, id);
 	}
-	if (ix < 0)
+	if (ctrls == NULL)
 		return -EINVAL;
-	memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl,
-		sizeof *q_ctrl);
-	if (gspca_dev->ctrl_dis & (1 << ix))
-		q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+	memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
 	return 0;
 }
 
@@ -1028,56 +1039,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 {
 	struct gspca_dev *gspca_dev = priv;
 	const struct ctrl *ctrls;
-	int i, ret;
+	int ret;
 
-	for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
-	     i < gspca_dev->sd_desc->nctrls;
-	     i++, ctrls++) {
-		if (ctrl->id != ctrls->qctrl.id)
-			continue;
-		if (gspca_dev->ctrl_dis & (1 << i))
-			return -EINVAL;
-		if (ctrl->value < ctrls->qctrl.minimum
-		    || ctrl->value > ctrls->qctrl.maximum)
-			return -ERANGE;
-		PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
-		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
-			return -ERESTARTSYS;
-		if (gspca_dev->present)
-			ret = ctrls->set(gspca_dev, ctrl->value);
-		else
-			ret = -ENODEV;
-		mutex_unlock(&gspca_dev->usb_lock);
-		return ret;
-	}
-	return -EINVAL;
+	ctrls = get_ctrl(gspca_dev, ctrl->id);
+	if (ctrls == NULL)
+		return -EINVAL;
+
+	if (ctrl->value < ctrls->qctrl.minimum
+	    || ctrl->value > ctrls->qctrl.maximum)
+		return -ERANGE;
+	PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
+	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+		return -ERESTARTSYS;
+	if (gspca_dev->present)
+		ret = ctrls->set(gspca_dev, ctrl->value);
+	else
+		ret = -ENODEV;
+	mutex_unlock(&gspca_dev->usb_lock);
+	return ret;
 }
 
 static int vidioc_g_ctrl(struct file *file, void *priv,
 			 struct v4l2_control *ctrl)
 {
 	struct gspca_dev *gspca_dev = priv;
-
 	const struct ctrl *ctrls;
-	int i, ret;
+	int ret;
 
-	for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
-	     i < gspca_dev->sd_desc->nctrls;
-	     i++, ctrls++) {
-		if (ctrl->id != ctrls->qctrl.id)
-			continue;
-		if (gspca_dev->ctrl_dis & (1 << i))
-			return -EINVAL;
-		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
-			return -ERESTARTSYS;
-		if (gspca_dev->present)
-			ret = ctrls->get(gspca_dev, &ctrl->value);
-		else
-			ret = -ENODEV;
-		mutex_unlock(&gspca_dev->usb_lock);
-		return ret;
-	}
-	return -EINVAL;
+	ctrls = get_ctrl(gspca_dev, ctrl->id);
+	if (ctrls == NULL)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+		return -ERESTARTSYS;
+	if (gspca_dev->present)
+		ret = ctrls->get(gspca_dev, &ctrl->value);
+	else
+		ret = -ENODEV;
+	mutex_unlock(&gspca_dev->usb_lock);
+	return ret;
 }
 
 /*fixme: have an audio flag in gspca_dev?*/
-- 
cgit v1.2.3-70-g09d2


From c874f3aa7e66158dccb2b9f3cfc46c65af6c223d Mon Sep 17 00:00:00 2001
From: Jean-Francois Moine <moinejf@free.fr>
Date: Fri, 12 Jun 2009 03:20:46 -0300
Subject: V4L/DVB (11973): gspca - ov534: Do the ov772x work again.

The scan of the image packets of the sensor ov772x was broken when
the sensor ov965x was added.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov534.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 8d2164db3d6..4b528b37291 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -948,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 	__u32 this_pts;
 	u16 this_fid;
 	int remaining_len = len;
+	int payload_len;
 
+	payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
 	do {
-		len = min(remaining_len, 2040);		/*fixme: was 2048*/
+		len = min(remaining_len, payload_len);
 
 		/* Payloads are prefixed with a UVC-style header.  We
 		   consider a frame to start when the FID toggles, or the PTS
-- 
cgit v1.2.3-70-g09d2


From ae3340cbf59ea362c2016eea762456cc0969fd9e Mon Sep 17 00:00:00 2001
From: Franklin Meng <fmeng2002@yahoo.com>
Date: Sat, 6 Jun 2009 16:34:01 -0300
Subject: V4L/DVB (11976): em28xx: set up tda9887_conf in em28xx_card_setup()

Added tda9887_conf set up into em28xx_card_setup()

Signed-off-by: Franklin Meng <fmeng2002@yahoo.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 36abb352b99..d3b0eb3bdf6 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1978,6 +1978,9 @@ void em28xx_card_setup(struct em28xx *dev)
 	if (em28xx_boards[dev->model].tuner_addr)
 		dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
 
+	if (em28xx_boards[dev->model].tda9887_conf)
+		dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
+
 	/* request some modules */
 	switch (dev->model) {
 	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
-- 
cgit v1.2.3-70-g09d2


From d7de5d8ff74efd01916b01af875a0e87419a3599 Mon Sep 17 00:00:00 2001
From: Franklin Meng <fmeng2002@yahoo.com>
Date: Sat, 6 Jun 2009 17:05:02 -0300
Subject: V4L/DVB (11977): em28xx: Add Kworld 315 entry

Added an entry for Kworld 315 (for while, dvb only)

Signed-off-by: Franklin Meng <fmeng2002@yahoo.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.em28xx |  1 +
 drivers/media/video/em28xx/em28xx-cards.c | 69 +++++++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx-dvb.c   | 14 +++++++
 drivers/media/video/em28xx/em28xx.h       |  1 +
 4 files changed, 85 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index b03a68586eb..a98a688c11b 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -64,3 +64,4 @@
  66 -> Empire dual TV                           (em2880)
  67 -> Terratec Grabby                          (em2860)        [0ccd:0096]
  68 -> Terratec AV350                           (em2860)        [0ccd:0084]
+ 69 -> KWorld ATSC 315U HDTV TV Box             (em2882)        [eb1a:a313]
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index d3b0eb3bdf6..00cc791a9e4 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -109,6 +109,24 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
 /* Board  - EM2870 Kworld 355u
    Analog - No input analog */
 
+/* Board - EM2882 Kworld 315U digital */
+static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
+	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
+	{EM2880_R04_GPO,	0x04,	0xff,		10},
+	{EM2880_R04_GPO,	0x0c,	0xff,		10},
+	{EM28XX_R08_GPIO,	0x7e,	0xff,		10},
+	{  -1,			-1,	-1,		-1},
+};
+
+static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = {
+	{EM2880_R04_GPO,	0x08,	0xff,		10},
+	{EM2880_R04_GPO,	0x0c,	0xff,		10},
+	{EM2880_R04_GPO,	0x08,	0xff,		10},
+	{EM2880_R04_GPO,	0x0c,	0xff,		10},
+	{  -1,			-1,	-1,		-1},
+};
+
 static struct em28xx_reg_seq kworld_330u_analog[] = {
 	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x00,	0xff,		10},
@@ -1111,6 +1129,38 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = default_analog,
 		} },
 	},
+	[EM2882_BOARD_KWORLD_ATSC_315U] = {
+		.name		= "KWorld ATSC 315U HDTV TV Box",
+		.valid		= EM28XX_BOARD_NOT_VALIDATED,
+		.tuner_type	= TUNER_THOMSON_DTT761X,
+		.tuner_gpio	= em2882_kworld_315u_tuner_gpio,
+		.tda9887_conf	= TDA9887_PRESENT,
+		.decoder	= EM28XX_SAA711X,
+		.has_dvb	= 1,
+		.dvb_gpio	= em2882_kworld_315u_digital,
+		.xclk		= EM28XX_XCLK_FREQUENCY_12MHZ,
+		.i2c_speed	= EM28XX_I2C_CLK_WAIT_ENABLE,
+		/* Analog mode - still not ready */
+		/*.input        = { {
+			.type = EM28XX_VMUX_TELEVISION,
+			.vmux = SAA7115_COMPOSITE2,
+			.amux = EM28XX_AMUX_VIDEO,
+			.gpio = em2882_kworld_315u_analog,
+			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
+		}, {
+			.type = EM28XX_VMUX_COMPOSITE1,
+			.vmux = SAA7115_COMPOSITE0,
+			.amux = EM28XX_AMUX_LINE_IN,
+			.gpio = em2882_kworld_315u_analog1,
+			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
+		}, {
+			.type = EM28XX_VMUX_SVIDEO,
+			.vmux = SAA7115_SVIDEO3,
+			.amux = EM28XX_AMUX_LINE_IN,
+			.gpio = em2882_kworld_315u_analog1,
+			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
+		} }, */
+	},
 	[EM2880_BOARD_EMPIRE_DUAL_TV] = {
 		.name = "Empire dual TV",
 		.tuner_type = TUNER_XC2028,
@@ -1432,6 +1482,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
 	{ USB_DEVICE(0xeb1a, 0xe310),
 			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
+	{ USB_DEVICE(0xeb1a, 0xa313),
+		.driver_info = EM2882_BOARD_KWORLD_ATSC_315U },
 	{ USB_DEVICE(0xeb1a, 0xa316),
 			.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
 	{ USB_DEVICE(0xeb1a, 0xe320),
@@ -1701,6 +1753,17 @@ void em28xx_pre_card_setup(struct em28xx *dev)
 		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
 		break;
 
+	case EM2882_BOARD_KWORLD_ATSC_315U:
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		msleep(10);
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		msleep(10);
+		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
+		msleep(10);
+		em28xx_write_reg(dev, EM2880_R04_GPO, 0x08);
+		msleep(10);
+		break;
+
 	case EM2860_BOARD_KAIOMY_TVNPC_U2:
 		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
 		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
@@ -2010,6 +2073,12 @@ void em28xx_card_setup(struct em28xx *dev)
 #endif
 		break;
 	}
+	case EM2882_BOARD_KWORLD_ATSC_315U:
+		em28xx_write_reg(dev, 0x0d, 0x42);
+		msleep(10);
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		msleep(10);
+		break;
 	case EM2820_BOARD_KWORLD_PVRTV2800RF:
 		/* GPIO enables sound on KWORLD PVR TV 2800RF */
 		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index e0438acf122..563dd2b1c8e 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -25,6 +25,8 @@
 #include "em28xx.h"
 #include <media/v4l2-common.h>
 #include <media/videobuf-vmalloc.h>
+#include <media/tuner.h>
+#include "tuner-simple.h"
 
 #include "lgdt330x.h"
 #include "zl10353.h"
@@ -451,6 +453,18 @@ static int dvb_init(struct em28xx *dev)
 			goto out_free;
 		}
 		break;
+	case EM2882_BOARD_KWORLD_ATSC_315U:
+		dvb->frontend = dvb_attach(lgdt330x_attach,
+					   &em2880_lgdt3303_dev,
+					   &dev->i2c_adap);
+		if (dvb->frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, dvb->frontend,
+				&dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
+				result = -EINVAL;
+				goto out_free;
+			}
+		}
+		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
 #ifdef EM28XX_DRX397XD_SUPPORT
 		/* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 2ddd59d2109..8bf81be1da6 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -105,6 +105,7 @@
 #define EM2880_BOARD_EMPIRE_DUAL_TV		  66
 #define EM2860_BOARD_TERRATEC_GRABBY		  67
 #define EM2860_BOARD_TERRATEC_AV350		  68
+#define EM2882_BOARD_KWORLD_ATSC_315U		  69
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
-- 
cgit v1.2.3-70-g09d2


From 1cdc6392b74246be333e2c88b61beedbf9991422 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Tue, 9 Jun 2009 23:40:39 -0300
Subject: V4L/DVB (11979): em28xx: don't create audio device if not supported

In cases where the device does not actually provide a USB audio class *or*
vendor audio, do not load the driver that provides vendor audio support (such
as the KWorld 2800d).  Otherwise, the /dev/audio1 device file gets created and
users get confused.

Also, reworks the logic a bit so that we don't try to inspect the register
content if the register read failed entirely.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-core.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index b7a2fedc390..c8d7ce8fbd3 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -500,18 +500,21 @@ int em28xx_audio_setup(struct em28xx *dev)
 
 	/* See how this device is configured */
 	cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
-	if (cfg < 0)
+	em28xx_info("Config register raw data: 0x%02x\n", cfg);
+	if (cfg < 0) {
+		/* Register read error?  */
 		cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */
-	else
-		em28xx_info("Config register raw data: 0x%02x\n", cfg);
-
-	if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
-		    EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
+	} else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) {
+		/* The device doesn't have vendor audio at all */
+		dev->has_alsa_audio = 0;
+		dev->audio_mode.has_audio = 0;
+		return 0;
+	} else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
+		   EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
 		em28xx_info("I2S Audio (3 sample rates)\n");
 		dev->audio_mode.i2s_3rates = 1;
-	}
-	if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
-		    EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
+	} else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
+		   EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
 		em28xx_info("I2S Audio (5 sample rates)\n");
 		dev->audio_mode.i2s_5rates = 1;
 	}
-- 
cgit v1.2.3-70-g09d2


From d5709a0e3dfe22e24d871ef1e0eec9ae04055997 Mon Sep 17 00:00:00 2001
From: "figo.zhang" <figo.zhang@kolorific.com>
Date: Thu, 7 May 2009 23:31:02 -0300
Subject: V4L/DVB (11990): saa7134-video.c: fix the block bug

when re-open or re-start (video_streamon), the q->curr would not be NULL in saa7134_buffer_queue(),
and all the qbuf will add to q->queue list,no one to do activate to start DMA,and then no interrupt
would happened,so it will be block.

In VIDEOBUF_NEEDS_INIT state, initialize the curr pointer to be NULL in the buffer_prepare().

Signed-off-by: Figo.zhang <figo.zhang@kolorific.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-video.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index ceae3c88f93..e305c1674ce 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1057,6 +1057,7 @@ static int buffer_prepare(struct videobuf_queue *q,
 		buf->vb.field  = field;
 		buf->fmt       = fh->fmt;
 		buf->pt        = &fh->pt_cap;
+		dev->video_q.curr = NULL;
 
 		err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
 		if (err)
-- 
cgit v1.2.3-70-g09d2


From 96ceea2734d922d07000e98606231f3d675e09f8 Mon Sep 17 00:00:00 2001
From: "Figo.zhang" <figo1802@gmail.com>
Date: Tue, 2 Jun 2009 23:01:04 -0300
Subject: V4L/DVB (11991): buf-core.c: add pointer check

add poiter check for videobuf_queue_core_init().

any guys who write a v4l driver, pass a NULL pointer or a non-inintial
pointer to the first parameter such as videobuf_queue_sg_init() , it
would be crashed.

Signed-off-by: Figo.zhang <figo1802@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/videobuf-core.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 48c3ebdb415..f1ccf98c0a6 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -118,6 +118,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
 			 void *priv,
 			 struct videobuf_qtype_ops *int_ops)
 {
+	BUG_ON(!q);
 	memset(q, 0, sizeof(*q));
 	q->irqlock   = irqlock;
 	q->dev       = dev;
-- 
cgit v1.2.3-70-g09d2


From e36bc31f823d6089bedc935fea82b6d36793412a Mon Sep 17 00:00:00 2001
From: Jean Delvare <khali@linux-fr.org>
Date: Thu, 4 Jun 2009 11:07:16 -0300
Subject: V4L/DVB (11992): Add missing __devexit_p()

Add missing __devexit_p() to several drivers. Also add a few missing
__init, __devinit and __exit markers. These errors could result in
build failures depending on the kernel configuration.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/dvb/bt8xx/bt878.c                 | 8 +-------
 drivers/media/video/cx88/cx88-alsa.c            | 7 +++----
 drivers/media/video/mx3_camera.c                | 6 +++---
 drivers/media/video/pxa_camera.c                | 6 +++---
 drivers/media/video/soc_camera.c                | 2 +-
 drivers/media/video/usbvision/usbvision-video.c | 2 +-
 drivers/media/video/zoran/zoran_card.c          | 2 +-
 7 files changed, 13 insertions(+), 20 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 56d8fab688b..a24c125331f 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -508,12 +508,6 @@ static int __devinit bt878_probe(struct pci_dev *dev,
 	pci_set_master(dev);
 	pci_set_drvdata(dev, bt);
 
-/*        if(init_bt878(btv) < 0) {
-		bt878_remove(dev);
-		return -EIO;
-	}
-*/
-
 	if ((result = bt878_mem_alloc(bt))) {
 		printk(KERN_ERR "bt878: failed to allocate memory!\n");
 		goto fail2;
@@ -579,7 +573,7 @@ static struct pci_driver bt878_pci_driver = {
       .name	= "bt878",
       .id_table = bt878_pci_tbl,
       .probe	= bt878_probe,
-      .remove	= bt878_remove,
+      .remove	= __devexit_p(bt878_remove),
 };
 
 static int bt878_pci_driver_registered;
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 0ccdf36626e..5a67445dd6e 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -871,7 +871,7 @@ static struct pci_driver cx88_audio_pci_driver = {
 	.name     = "cx88_audio",
 	.id_table = cx88_audio_pci_tbl,
 	.probe    = cx88_audio_initdev,
-	.remove   = cx88_audio_finidev,
+	.remove   = __devexit_p(cx88_audio_finidev),
 };
 
 /****************************************************************************
@@ -881,7 +881,7 @@ static struct pci_driver cx88_audio_pci_driver = {
 /*
  * module init
  */
-static int cx88_audio_init(void)
+static int __init cx88_audio_init(void)
 {
 	printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",
 	       (CX88_VERSION_CODE >> 16) & 0xff,
@@ -897,9 +897,8 @@ static int cx88_audio_init(void)
 /*
  * module remove
  */
-static void cx88_audio_fini(void)
+static void __exit cx88_audio_fini(void)
 {
-
 	pci_unregister_driver(&cx88_audio_pci_driver);
 }
 
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 4d47eeb1445..e605c076ed8 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -1074,7 +1074,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
 	.set_bus_param	= mx3_camera_set_bus_param,
 };
 
-static int mx3_camera_probe(struct platform_device *pdev)
+static int __devinit mx3_camera_probe(struct platform_device *pdev)
 {
 	struct mx3_camera_dev *mx3_cam;
 	struct resource *res;
@@ -1194,11 +1194,11 @@ static struct platform_driver mx3_camera_driver = {
 		.name	= MX3_CAM_DRV_NAME,
 	},
 	.probe		= mx3_camera_probe,
-	.remove		= __exit_p(mx3_camera_remove),
+	.remove		= __devexit_p(mx3_camera_remove),
 };
 
 
-static int __devinit mx3_camera_init(void)
+static int __init mx3_camera_init(void)
 {
 	return platform_driver_register(&mx3_camera_driver);
 }
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 2da5eef19b7..f60de40fd21 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1551,7 +1551,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
 	.set_bus_param	= pxa_camera_set_bus_param,
 };
 
-static int pxa_camera_probe(struct platform_device *pdev)
+static int __devinit pxa_camera_probe(struct platform_device *pdev)
 {
 	struct pxa_camera_dev *pcdev;
 	struct resource *res;
@@ -1726,11 +1726,11 @@ static struct platform_driver pxa_camera_driver = {
 		.name	= PXA_CAM_DRV_NAME,
 	},
 	.probe		= pxa_camera_probe,
-	.remove		= __exit_p(pxa_camera_remove),
+	.remove		= __devexit_p(pxa_camera_remove),
 };
 
 
-static int __devinit pxa_camera_init(void)
+static int __init pxa_camera_init(void)
 {
 	return platform_driver_register(&pxa_camera_driver);
 }
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 2014e9e32b3..16f595d4337 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -1205,7 +1205,7 @@ static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
 
 static struct platform_driver __refdata soc_camera_pdrv = {
 	.probe	= soc_camera_pdrv_probe,
-	.remove	= __exit_p(soc_camera_pdrv_remove),
+	.remove	= __devexit_p(soc_camera_pdrv_remove),
 	.driver	= {
 		.name = "soc-camera-pdrv",
 		.owner = THIS_MODULE,
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d03e5922d3b..90b58914f98 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1794,7 +1794,7 @@ static struct usb_driver usbvision_driver = {
 	.name		= "usbvision",
 	.id_table	= usbvision_table,
 	.probe		= usbvision_probe,
-	.disconnect	= usbvision_disconnect
+	.disconnect	= __devexit_p(usbvision_disconnect),
 };
 
 /*
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index ea9de8b47db..03dc2f3cf84 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1477,7 +1477,7 @@ static struct pci_driver zoran_driver = {
 	.name = "zr36067",
 	.id_table = zr36067_pci_tbl,
 	.probe = zoran_probe,
-	.remove = zoran_remove,
+	.remove = __devexit_p(zoran_remove),
 };
 
 static int __init zoran_init(void)
-- 
cgit v1.2.3-70-g09d2


From 52a85e17091d2fe9ade6a5d94063e70c5d2a9d5b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mzxreary@0pointer.de>
Date: Thu, 4 Jun 2009 16:18:13 -0300
Subject: V4L/DVB (11993): V4L/pwc - use usb_interface as parent, not
 usb_device

The current code creates a sysfs device path where the video4linux
device is child of the usb device itself instead of the interface it
belongs to. That is evil and confuses udev.

This patch does basically the same thing as Kay's similar patch for the
ov511 driver:

at git commit ce96d0a44a4f8d1bb3dc12b5e98cb688c1bc730d

Signed-off-by: Lennart Poettering <mzxreary@0pointer.de>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pwc/pwc-if.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 519a965de23..db25c3034c1 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1783,7 +1783,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 		return -ENOMEM;
 	}
 	memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
-	pdev->vdev->parent = &(udev->dev);
+	pdev->vdev->parent = &intf->dev;
 	strcpy(pdev->vdev->name, name);
 	video_set_drvdata(pdev->vdev, pdev);
 
-- 
cgit v1.2.3-70-g09d2


From de99d76aa19994f0d1140b1397fc439525e147c0 Mon Sep 17 00:00:00 2001
From: "Figo.zhang" <figo1802@gmail.com>
Date: Sat, 6 Jun 2009 06:16:21 -0300
Subject: V4L/DVB (11995): zr364xx.c: vfree does its own NULL check

vfree() does it's own NULL checking, no need for explicit check before
calling it.

Signed-off-by: Figo.zhang <figo1802@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/zr364xx.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index ac169c9eb18..fc976f42f43 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -882,9 +882,11 @@ static void zr364xx_disconnect(struct usb_interface *intf)
 		video_unregister_device(cam->vdev);
 	cam->vdev = NULL;
 	kfree(cam->buffer);
-	if (cam->framebuf)
-		vfree(cam->framebuf);
+	cam->buffer = NULL;
+	vfree(cam->framebuf);
+	cam->framebuf = NULL;
 	kfree(cam);
+	cam = NULL;
 }
 
 
-- 
cgit v1.2.3-70-g09d2


From 27049dc30152ad0401082f32c33859821b4be029 Mon Sep 17 00:00:00 2001
From: Barry Kitson <b.kitson@gmail.com>
Date: Sun, 7 Jun 2009 10:41:03 -0300
Subject: V4L/DVB (11996): saa7134: add support for AVerMedia M103 (f736)

Add 1461:f736 to the list of identifiers corresponding to the
SAA7134_BOARD_AVERMEDIA_M103 board.  This patch adds support for
a variant of the AVerMedia M103 MiniPCI DVB-T Hybrid card.

Signed-off-by: Barry Kitson <b.kitson@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.saa7134  | 2 +-
 drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index e56934e501b..15562427e8a 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -143,7 +143,7 @@
 142 -> Beholder BeholdTV H6                     [5ace:6290]
 143 -> Beholder BeholdTV M63                    [5ace:6191]
 144 -> Beholder BeholdTV M6 Extra               [5ace:6193]
-145 -> AVerMedia MiniPCI DVB-T Hybrid M103      [1461:f636]
+145 -> AVerMedia MiniPCI DVB-T Hybrid M103      [1461:f636,1461:f736]
 146 -> ASUSTeK P7131 Analog
 147 -> Asus Tiger 3in1                          [1043:4878]
 148 -> Encore ENLTV-FM v5.3                     [1a7f:2008]
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 229ba93bcc9..06861b782b9 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -6199,6 +6199,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
 		.subdevice    = 0xf636,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_M103,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xf736,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_M103,
 	}, {
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-- 
cgit v1.2.3-70-g09d2


From 226a040e6a95fbedff0c82a10fea4dd42320e79f Mon Sep 17 00:00:00 2001
From: Alexey Klimov <klimov.linux@gmail.com>
Date: Tue, 9 Jun 2009 07:59:40 -0300
Subject: V4L/DVB (11997): gspca - stv06xx: remove needless if check and goto
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Patch removes needless if check and goto.

Signed-off-by: Alexey Klimov <klimov.linux@gmail.com>
Reviewed-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/stv06xx/stv06xx.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 9dff2e65b11..e573c340632 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev)
 		goto out;
 
 	err = sd->sensor->stop(sd);
-	if (err < 0)
-		goto out;
 
 out:
 	if (err < 0)
-- 
cgit v1.2.3-70-g09d2


From aae40fd21906f051ce1ee5f623b8d70a2f32b7fc Mon Sep 17 00:00:00 2001
From: Alan Cox <alan@linux.intel.com>
Date: Tue, 9 Jun 2009 10:02:11 -0300
Subject: V4L/DVB (11998): se401: Fix coding style

Having fixed the sprintfs I decided a quick clean wouldn't do any harm so
it was actually easy to read in future.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/se401.c | 876 ++++++++++++++++++++++----------------------
 drivers/media/video/se401.h |   7 +-
 2 files changed, 452 insertions(+), 431 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 08129a830d6..c8f05297d0f 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -38,7 +38,7 @@ static const char version[] = "0.24";
 static int flickerless;
 static int video_nr = -1;
 
-static struct usb_device_id device_table [] = {
+static struct usb_device_id device_table[] = {
 	{ USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
 	{ USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
 	{ USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
@@ -53,7 +53,8 @@ MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
 MODULE_DESCRIPTION("SE401 USB Camera Driver");
 MODULE_LICENSE("GPL");
 module_param(flickerless, int, 0);
-MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
+MODULE_PARM_DESC(flickerless,
+		"Net frequency to adjust exposure time to (0/50/60)");
 module_param(video_nr, int, 0);
 
 static struct usb_driver se401_driver;
@@ -78,8 +79,8 @@ static void *rvmalloc(unsigned long size)
 	adr = (unsigned long) mem;
 	while (size > 0) {
 		SetPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
+		adr +=  PAGE_SIZE;
+		size -=  PAGE_SIZE;
 	}
 
 	return mem;
@@ -95,8 +96,8 @@ static void rvfree(void *mem, unsigned long size)
 	adr = (unsigned long) mem;
 	while ((long) size > 0) {
 		ClearPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
+		adr +=  PAGE_SIZE;
+		size -=  PAGE_SIZE;
 	}
 	vfree(mem);
 }
@@ -112,7 +113,7 @@ static void rvfree(void *mem, unsigned long size)
 static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
 			 unsigned short value, unsigned char *cp, int size)
 {
-	return usb_control_msg (
+	return usb_control_msg(
 		se401->dev,
 		set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
 		req,
@@ -132,7 +133,7 @@ static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
 	   and the param in index, but in the logs of the windows driver they do
 	   this the other way around...
 	 */
-	return usb_control_msg (
+	return usb_control_msg(
 		se401->dev,
 		usb_sndctrlpipe(se401->dev, 0),
 		SE401_REQ_SET_EXT_FEATURE,
@@ -152,7 +153,7 @@ static unsigned short se401_get_feature(struct usb_se401 *se401,
 	   wrong here to....
 	 */
 	unsigned char cp[2];
-	usb_control_msg (
+	usb_control_msg(
 		se401->dev,
 		usb_rcvctrlpipe(se401->dev, 0),
 		SE401_REQ_GET_EXT_FEATURE,
@@ -175,46 +176,51 @@ static unsigned short se401_get_feature(struct usb_se401 *se401,
 
 static int se401_send_pict(struct usb_se401 *se401)
 {
-	se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
-	se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
-	se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
-	se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
-	se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
-	se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
-	se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
+	/* integration time low */
+	se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);
+	/* integration time mid */
+	se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);
+	/* integration time mid */
+	se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);
+	/* reset level value */
+	se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
+	/* red color gain */
+	se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);
+	/* green color gain */
+	se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);
+	/* blue color gain */
+	se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);
 
 	return 0;
 }
 
 static void se401_set_exposure(struct usb_se401 *se401, int brightness)
 {
-	int integration=brightness<<5;
-
-	if (flickerless==50) {
-		integration=integration-integration%106667;
-	}
-	if (flickerless==60) {
-		integration=integration-integration%88889;
-	}
-	se401->brightness=integration>>5;
-	se401->expose_h=(integration>>16)&0xff;
-	se401->expose_m=(integration>>8)&0xff;
-	se401->expose_l=integration&0xff;
+	int integration = brightness << 5;
+
+	if (flickerless == 50)
+		integration = integration-integration % 106667;
+	if (flickerless == 60)
+		integration = integration-integration % 88889;
+	se401->brightness = integration >> 5;
+	se401->expose_h = (integration >> 16) & 0xff;
+	se401->expose_m = (integration >> 8) & 0xff;
+	se401->expose_l = integration & 0xff;
 }
 
 static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
 {
-	p->brightness=se401->brightness;
-	if (se401->enhance) {
-		p->whiteness=32768;
-	} else {
-		p->whiteness=0;
-	}
-	p->colour=65535;
-	p->contrast=65535;
-	p->hue=se401->rgain<<10;
-	p->palette=se401->palette;
-	p->depth=3; /* rgb24 */
+	p->brightness = se401->brightness;
+	if (se401->enhance)
+		p->whiteness = 32768;
+	else
+		p->whiteness = 0;
+
+	p->colour = 65535;
+	p->contrast = 65535;
+	p->hue = se401->rgain << 10;
+	p->palette = se401->palette;
+	p->depth = 3; /* rgb24 */
 	return 0;
 }
 
@@ -223,20 +229,19 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
 {
 	if (p->palette != VIDEO_PALETTE_RGB24)
 		return 1;
-	se401->palette=p->palette;
-	if (p->hue!=se401->hue) {
-		se401->rgain= p->hue>>10;
-		se401->bgain= 0x40-(p->hue>>10);
-		se401->hue=p->hue;
+	se401->palette = p->palette;
+	if (p->hue != se401->hue) {
+		se401->rgain =  p->hue >> 10;
+		se401->bgain =  0x40-(p->hue >> 10);
+		se401->hue = p->hue;
 	}
-	if (p->brightness!=se401->brightness) {
+	if (p->brightness != se401->brightness)
 		se401_set_exposure(se401, p->brightness);
-	}
-	if (p->whiteness>=32768) {
-		se401->enhance=1;
-	} else {
-		se401->enhance=0;
-	}
+
+	if (p->whiteness >= 32768)
+		se401->enhance = 1;
+	else
+		se401->enhance = 0;
 	se401_send_pict(se401);
 	se401_send_pict(se401);
 	return 0;
@@ -249,7 +254,7 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
 static void se401_auto_resetlevel(struct usb_se401 *se401)
 {
 	unsigned int ahrc, alrc;
-	int oldreset=se401->resetlevel;
+	int oldreset = se401->resetlevel;
 
 	/* For some reason this normally read-only register doesn't get reset
 	   to zero after reading them just once...
@@ -258,24 +263,24 @@ static void se401_auto_resetlevel(struct usb_se401 *se401)
 	se401_get_feature(se401, HV7131_REG_HIREFNOL);
 	se401_get_feature(se401, HV7131_REG_LOREFNOH);
 	se401_get_feature(se401, HV7131_REG_LOREFNOL);
-	ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
+	ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
 	    se401_get_feature(se401, HV7131_REG_HIREFNOL);
-	alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
+	alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
 	    se401_get_feature(se401, HV7131_REG_LOREFNOL);
 
 	/* Not an exact science, but it seems to work pretty well... */
 	if (alrc > 10) {
-		while (alrc>=10 && se401->resetlevel < 63) {
+		while (alrc >= 10 && se401->resetlevel < 63) {
 			se401->resetlevel++;
-			alrc /=2;
+			alrc /= 2;
 		}
 	} else if (ahrc > 20) {
-		while (ahrc>=20 && se401->resetlevel > 0) {
+		while (ahrc >= 20 && se401->resetlevel > 0) {
 			se401->resetlevel--;
-			ahrc /=2;
+			ahrc /= 2;
 		}
 	}
-	if (se401->resetlevel!=oldreset)
+	if (se401->resetlevel != oldreset)
 		se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
 
 	return;
@@ -300,21 +305,22 @@ static void se401_button_irq(struct urb *urb)
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dbg("%s - urb shutting down with status: %d",
+							__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dbg("%s - nonzero urb status received: %d",
+							__func__, urb->status);
 		goto exit;
 	}
 
-	if (urb->actual_length >=2) {
+	if (urb->actual_length  >= 2)
 		if (se401->button)
-			se401->buttonpressed=1;
-	}
+			se401->buttonpressed = 1;
 exit:
-	status = usb_submit_urb (urb, GFP_ATOMIC);
+	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status)
-		err ("%s - usb_submit_urb failed with result %d",
+		err("%s - usb_submit_urb failed with result %d",
 		     __func__, status);
 }
 
@@ -336,55 +342,52 @@ static void se401_video_irq(struct urb *urb)
 	   keeps sending them forever...
 	 */
 	if (length && !urb->status) {
-		se401->nullpackets=0;
-		switch(se401->scratch[se401->scratch_next].state) {
-			case BUFFER_READY:
-			case BUFFER_BUSY: {
-				se401->dropped++;
-				break;
-			}
-			case BUFFER_UNUSED: {
-				memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
-				se401->scratch[se401->scratch_next].state=BUFFER_READY;
-				se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
-				se401->scratch[se401->scratch_next].length=length;
-				if (waitqueue_active(&se401->wq)) {
-					wake_up_interruptible(&se401->wq);
-				}
-				se401->scratch_overflow=0;
-				se401->scratch_next++;
-				if (se401->scratch_next>=SE401_NUMSCRATCH)
-					se401->scratch_next=0;
-				break;
-			}
-		}
-		se401->bayeroffset+=length;
-		if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
-			se401->bayeroffset=0;
+		se401->nullpackets = 0;
+		switch (se401->scratch[se401->scratch_next].state) {
+		case BUFFER_READY:
+		case BUFFER_BUSY:
+			se401->dropped++;
+			break;
+		case BUFFER_UNUSED:
+			memcpy(se401->scratch[se401->scratch_next].data,
+				(unsigned char *)urb->transfer_buffer, length);
+			se401->scratch[se401->scratch_next].state
+							= BUFFER_READY;
+			se401->scratch[se401->scratch_next].offset
+							= se401->bayeroffset;
+			se401->scratch[se401->scratch_next].length = length;
+			if (waitqueue_active(&se401->wq))
+				wake_up_interruptible(&se401->wq);
+			se401->scratch_overflow = 0;
+			se401->scratch_next++;
+			if (se401->scratch_next >= SE401_NUMSCRATCH)
+				se401->scratch_next = 0;
+			break;
 		}
+		se401->bayeroffset += length;
+		if (se401->bayeroffset >= se401->cheight * se401->cwidth)
+			se401->bayeroffset = 0;
 	} else {
 		se401->nullpackets++;
-		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
-			if (waitqueue_active(&se401->wq)) {
+		if (se401->nullpackets > SE401_MAX_NULLPACKETS)
+			if (waitqueue_active(&se401->wq))
 				wake_up_interruptible(&se401->wq);
-			}
-		}
 	}
 
 	/* Resubmit urb for new data */
-	urb->status=0;
-	urb->dev=se401->dev;
-	if(usb_submit_urb(urb, GFP_KERNEL))
+	urb->status = 0;
+	urb->dev = se401->dev;
+	if (usb_submit_urb(urb, GFP_KERNEL))
 		dev_info(&urb->dev->dev, "urb burned down\n");
 	return;
 }
 
 static void se401_send_size(struct usb_se401 *se401, int width, int height)
 {
-	int i=0;
-	int mode=0x03; /* No compression */
-	int sendheight=height;
-	int sendwidth=width;
+	int i = 0;
+	int mode = 0x03; /* No compression */
+	int sendheight = height;
+	int sendwidth = width;
 
 	/* JangGu compression can only be used with the camera supported sizes,
 	   but bayer seems to work with any size that fits on the sensor.
@@ -392,18 +395,21 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
 	   4 or 16 times subcapturing, if not we use uncompressed bayer data
 	   but this will result in cutouts of the maximum size....
 	 */
-	while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
+	while (i < se401->sizes && !(se401->width[i] == width &&
+						se401->height[i] == height))
 		i++;
-	while (i<se401->sizes) {
-		if (se401->width[i]==width*2 && se401->height[i]==height*2) {
-			sendheight=se401->height[i];
-			sendwidth=se401->width[i];
-			mode=0x40;
+	while (i < se401->sizes) {
+		if (se401->width[i] == width * 2 &&
+				se401->height[i] == height * 2) {
+			sendheight = se401->height[i];
+			sendwidth = se401->width[i];
+			mode = 0x40;
 		}
-		if (se401->width[i]==width*4 && se401->height[i]==height*4) {
-			sendheight=se401->height[i];
-			sendwidth=se401->width[i];
-			mode=0x42;
+		if (se401->width[i] == width * 4 &&
+				se401->height[i] == height * 4) {
+			sendheight = se401->height[i];
+			sendwidth = se401->width[i];
+			mode = 0x42;
 		}
 		i++;
 	}
@@ -412,13 +418,10 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
 	se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
 	se401_set_feature(se401, SE401_OPERATINGMODE, mode);
 
-	if (mode==0x03) {
-		se401->format=FMT_BAYER;
-	} else {
-		se401->format=FMT_JANGGU;
-	}
-
-	return;
+	if (mode == 0x03)
+		se401->format = FMT_BAYER;
+	else
+		se401->format = FMT_JANGGU;
 }
 
 /*
@@ -429,29 +432,31 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
 static int se401_start_stream(struct usb_se401 *se401)
 {
 	struct urb *urb;
-	int err=0, i;
-	se401->streaming=1;
+	int err = 0, i;
+	se401->streaming = 1;
 
 	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
 	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
 
 	/* Set picture settings */
-	se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
+	/* windowed + pix intg */
+	se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);
 	se401_send_pict(se401);
 
 	se401_send_size(se401, se401->cwidth, se401->cheight);
 
-	se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
+	se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE,
+								0, NULL, 0);
 
 	/* Do some memory allocation */
-	for (i=0; i<SE401_NUMFRAMES; i++) {
-		se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
-		se401->frame[i].curpix=0;
+	for (i = 0; i < SE401_NUMFRAMES; i++) {
+		se401->frame[i].data = se401->fbuf + i * se401->maxframesize;
+		se401->frame[i].curpix = 0;
 	}
-	for (i=0; i<SE401_NUMSBUF; i++) {
-		se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+	for (i = 0; i < SE401_NUMSBUF; i++) {
+		se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
 		if (!se401->sbuf[i].data) {
-			for(i = i - 1; i >= 0; i--) {
+			for (i = i - 1; i >= 0; i--) {
 				kfree(se401->sbuf[i].data);
 				se401->sbuf[i].data = NULL;
 			}
@@ -459,26 +464,26 @@ static int se401_start_stream(struct usb_se401 *se401)
 		}
 	}
 
-	se401->bayeroffset=0;
-	se401->scratch_next=0;
-	se401->scratch_use=0;
-	se401->scratch_overflow=0;
-	for (i=0; i<SE401_NUMSCRATCH; i++) {
-		se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+	se401->bayeroffset = 0;
+	se401->scratch_next = 0;
+	se401->scratch_use = 0;
+	se401->scratch_overflow = 0;
+	for (i = 0; i < SE401_NUMSCRATCH; i++) {
+		se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
 		if (!se401->scratch[i].data) {
-			for(i = i - 1; i >= 0; i--) {
+			for (i = i - 1; i >= 0; i--) {
 				kfree(se401->scratch[i].data);
 				se401->scratch[i].data = NULL;
 			}
 			goto nomem_sbuf;
 		}
-		se401->scratch[i].state=BUFFER_UNUSED;
+		se401->scratch[i].state = BUFFER_UNUSED;
 	}
 
-	for (i=0; i<SE401_NUMSBUF; i++) {
-		urb=usb_alloc_urb(0, GFP_KERNEL);
-		if(!urb) {
-			for(i = i - 1; i >= 0; i--) {
+	for (i = 0; i < SE401_NUMSBUF; i++) {
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			for (i = i - 1; i >= 0; i--) {
 				usb_kill_urb(se401->urb[i]);
 				usb_free_urb(se401->urb[i]);
 				se401->urb[i] = NULL;
@@ -492,24 +497,24 @@ static int se401_start_stream(struct usb_se401 *se401)
 			se401_video_irq,
 			se401);
 
-		se401->urb[i]=urb;
+		se401->urb[i] = urb;
 
-		err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
-		if(err)
+		err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
+		if (err)
 			err("urb burned down");
 	}
 
-	se401->framecount=0;
+	se401->framecount = 0;
 
 	return 0;
 
  nomem_scratch:
-	for (i=0; i<SE401_NUMSCRATCH; i++) {
+	for (i = 0; i < SE401_NUMSCRATCH; i++) {
 		kfree(se401->scratch[i].data);
 		se401->scratch[i].data = NULL;
 	}
  nomem_sbuf:
-	for (i=0; i<SE401_NUMSBUF; i++) {
+	for (i = 0; i < SE401_NUMSBUF; i++) {
 		kfree(se401->sbuf[i].data);
 		se401->sbuf[i].data = NULL;
 	}
@@ -523,22 +528,23 @@ static int se401_stop_stream(struct usb_se401 *se401)
 	if (!se401->streaming || !se401->dev)
 		return 1;
 
-	se401->streaming=0;
+	se401->streaming = 0;
 
 	se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
 
 	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
 	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
 
-	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
-		usb_kill_urb(se401->urb[i]);
-		usb_free_urb(se401->urb[i]);
-		se401->urb[i]=NULL;
-		kfree(se401->sbuf[i].data);
-	}
-	for (i=0; i<SE401_NUMSCRATCH; i++) {
+	for (i = 0; i < SE401_NUMSBUF; i++)
+		if (se401->urb[i]) {
+			usb_kill_urb(se401->urb[i]);
+			usb_free_urb(se401->urb[i]);
+			se401->urb[i] = NULL;
+			kfree(se401->sbuf[i].data);
+		}
+	for (i = 0; i < SE401_NUMSCRATCH; i++) {
 		kfree(se401->scratch[i].data);
-		se401->scratch[i].data=NULL;
+		se401->scratch[i].data = NULL;
 	}
 
 	return 0;
@@ -546,9 +552,9 @@ static int se401_stop_stream(struct usb_se401 *se401)
 
 static int se401_set_size(struct usb_se401 *se401, int width, int height)
 {
-	int wasstreaming=se401->streaming;
+	int wasstreaming = se401->streaming;
 	/* Check to see if we need to change */
-	if (se401->cwidth==width && se401->cheight==height)
+	if (se401->cwidth == width && se401->cheight == height)
 		return 0;
 
 	/* Check for a valid mode */
@@ -556,16 +562,16 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height)
 		return 1;
 	if ((width & 1) || (height & 1))
 		return 1;
-	if (width>se401->width[se401->sizes-1])
+	if (width > se401->width[se401->sizes-1])
 		return 1;
-	if (height>se401->height[se401->sizes-1])
+	if (height > se401->height[se401->sizes-1])
 		return 1;
 
 	/* Stop a current stream and start it again at the new size */
 	if (wasstreaming)
 		se401_stop_stream(se401);
-	se401->cwidth=width;
-	se401->cheight=height;
+	se401->cwidth = width;
+	se401->cheight = height;
 	if (wasstreaming)
 		se401_start_stream(se401);
 	return 0;
@@ -586,68 +592,68 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height)
 static inline void enhance_picture(unsigned char *frame, int len)
 {
 	while (len--) {
-		*frame=(((*frame^255)*(*frame^255))/255)^255;
+		*frame = (((*frame^255)*(*frame^255))/255)^255;
 		frame++;
 	}
 }
 
 static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
 {
-	struct se401_frame *frame=&se401->frame[se401->curframe];
-	int linelength=se401->cwidth*3;
+	struct se401_frame *frame = &se401->frame[se401->curframe];
+	int linelength = se401->cwidth * 3;
 
 	if (frame->curlinepix >= linelength) {
-		frame->curlinepix=0;
-		frame->curline+=linelength;
+		frame->curlinepix = 0;
+		frame->curline += linelength;
 	}
 
 	/* First three are absolute, all others relative.
 	 * Format is rgb from right to left (mirrorred image),
 	 * we flip it to get bgr from left to right. */
-	if (frame->curlinepix < 3) {
-		*(frame->curline-frame->curlinepix)=1+data*4;
-	} else {
-		*(frame->curline-frame->curlinepix)=
-		    *(frame->curline-frame->curlinepix+3)+data*4;
-	}
+	if (frame->curlinepix < 3)
+		*(frame->curline-frame->curlinepix) = 1 + data * 4;
+	else
+		*(frame->curline-frame->curlinepix) =
+		    *(frame->curline-frame->curlinepix + 3) + data * 4;
 	frame->curlinepix++;
 }
 
-static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
+static inline void decode_JangGu_vlc(struct usb_se401 *se401,
+			unsigned char *data, int bit_exp, int packetlength)
 {
-	int pos=0;
-	int vlc_cod=0;
-	int vlc_size=0;
-	int vlc_data=0;
+	int pos = 0;
+	int vlc_cod = 0;
+	int vlc_size = 0;
+	int vlc_data = 0;
 	int bit_cur;
 	int bit;
-	data+=4;
+	data += 4;
 	while (pos < packetlength) {
-		bit_cur=8;
+		bit_cur = 8;
 		while (bit_cur && bit_exp) {
-			bit=((*data)>>(bit_cur-1))&1;
+			bit = ((*data) >> (bit_cur-1))&1;
 			if (!vlc_cod) {
 				if (bit) {
 					vlc_size++;
 				} else {
-					if (!vlc_size) {
+					if (!vlc_size)
 						decode_JangGu_integrate(se401, 0);
-					} else {
-						vlc_cod=2;
-						vlc_data=0;
+					else {
+						vlc_cod = 2;
+						vlc_data = 0;
 					}
 				}
 			} else {
-				if (vlc_cod==2) {
+				if (vlc_cod == 2) {
 					if (!bit)
-						vlc_data =  -(1<<vlc_size) + 1;
+						vlc_data =  -(1 << vlc_size) + 1;
 					vlc_cod--;
 				}
 				vlc_size--;
-				vlc_data+=bit<<vlc_size;
+				vlc_data += bit << vlc_size;
 				if (!vlc_size) {
 					decode_JangGu_integrate(se401, vlc_data);
-					vlc_cod=0;
+					vlc_cod = 0;
 				}
 			}
 			bit_cur--;
@@ -658,186 +664,188 @@ static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *da
 	}
 }
 
-static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
+static inline void decode_JangGu(struct usb_se401 *se401,
+						struct se401_scratch *buffer)
 {
-	unsigned char *data=buffer->data;
-	int len=buffer->length;
-	int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
-	int datapos=0;
+	unsigned char *data = buffer->data;
+	int len = buffer->length;
+	int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size;
+	int datapos = 0;
 
 	/* New image? */
 	if (!se401->frame[se401->curframe].curpix) {
-		se401->frame[se401->curframe].curlinepix=0;
-		se401->frame[se401->curframe].curline=
+		se401->frame[se401->curframe].curlinepix = 0;
+		se401->frame[se401->curframe].curline =
 		    se401->frame[se401->curframe].data+
-		    se401->cwidth*3-1;
-		if (se401->frame[se401->curframe].grabstate==FRAME_READY)
-			se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
-		se401->vlcdatapos=0;
+		    se401->cwidth * 3 - 1;
+		if (se401->frame[se401->curframe].grabstate == FRAME_READY)
+			se401->frame[se401->curframe].grabstate = FRAME_GRABBING;
+		se401->vlcdatapos = 0;
 	}
 	while (datapos < len) {
-		size=1024-se401->vlcdatapos;
+		size = 1024 - se401->vlcdatapos;
 		if (size+datapos > len)
-			size=len-datapos;
+			size = len-datapos;
 		memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
-		se401->vlcdatapos+=size;
-		packetlength=0;
+		se401->vlcdatapos += size;
+		packetlength = 0;
 		if (se401->vlcdatapos >= 4) {
-			bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
-			pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
-			frameinfo=se401->vlcdata[0]&0xc0;
-			packetlength=((bit_exp+47)>>4)<<1;
+			bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8);
+			pix_exp = se401->vlcdata[1] +
+					((se401->vlcdata[0] & 0x3f) << 8);
+			frameinfo = se401->vlcdata[0] & 0xc0;
+			packetlength = ((bit_exp + 47) >> 4) << 1;
 			if (packetlength > 1024) {
-				se401->vlcdatapos=0;
-				datapos=len;
-				packetlength=0;
+				se401->vlcdatapos = 0;
+				datapos = len;
+				packetlength = 0;
 				se401->error++;
-				se401->frame[se401->curframe].curpix=0;
+				se401->frame[se401->curframe].curpix = 0;
 			}
 		}
 		if (packetlength && se401->vlcdatapos >= packetlength) {
-			decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
-			se401->frame[se401->curframe].curpix+=pix_exp*3;
-			datapos+=size-(se401->vlcdatapos-packetlength);
-			se401->vlcdatapos=0;
-			if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
-				if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
-					if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
-						se401->frame[se401->curframe].grabstate=FRAME_DONE;
+			decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
+								packetlength);
+			se401->frame[se401->curframe].curpix += pix_exp * 3;
+			datapos += size-(se401->vlcdatapos-packetlength);
+			se401->vlcdatapos = 0;
+			if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) {
+				if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) {
+					if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) {
+						se401->frame[se401->curframe].grabstate = FRAME_DONE;
 						se401->framecount++;
 						se401->readcount++;
 					}
-					if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
-						se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
-					}
-				} else {
+					if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
+						se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
+				} else
 					se401->error++;
-				}
-				se401->frame[se401->curframe].curpix=0;
-				datapos=len;
+				se401->frame[se401->curframe].curpix = 0;
+				datapos = len;
 			}
-		} else {
-			datapos+=size;
-		}
+		} else
+			datapos += size;
 	}
 }
 
-static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
+static inline void decode_bayer(struct usb_se401 *se401,
+						struct se401_scratch *buffer)
 {
-	unsigned char *data=buffer->data;
-	int len=buffer->length;
-	int offset=buffer->offset;
-	int datasize=se401->cwidth*se401->cheight;
-	struct se401_frame *frame=&se401->frame[se401->curframe];
+	unsigned char *data = buffer->data;
+	int len = buffer->length;
+	int offset = buffer->offset;
+	int datasize = se401->cwidth * se401->cheight;
+	struct se401_frame *frame = &se401->frame[se401->curframe];
+	unsigned char *framedata = frame->data, *curline, *nextline;
+	int width = se401->cwidth;
+	int blineoffset = 0, bline;
+	int linelength = width * 3, i;
 
-	unsigned char *framedata=frame->data, *curline, *nextline;
-	int width=se401->cwidth;
-	int blineoffset=0, bline;
-	int linelength=width*3, i;
 
+	if (frame->curpix == 0) {
+		if (frame->grabstate == FRAME_READY)
+			frame->grabstate = FRAME_GRABBING;
 
-	if (frame->curpix==0) {
-		if (frame->grabstate==FRAME_READY) {
-			frame->grabstate=FRAME_GRABBING;
-		}
-		frame->curline=framedata+linelength;
-		frame->curlinepix=0;
+		frame->curline = framedata + linelength;
+		frame->curlinepix = 0;
 	}
 
-	if (offset!=frame->curpix) {
+	if (offset != frame->curpix) {
 		/* Regard frame as lost :( */
-		frame->curpix=0;
+		frame->curpix = 0;
 		se401->error++;
 		return;
 	}
 
 	/* Check if we have to much data */
-	if (frame->curpix+len > datasize) {
-		len=datasize-frame->curpix;
-	}
-	if (se401->cheight%4)
-		blineoffset=1;
-	bline=frame->curpix/se401->cwidth+blineoffset;
-
-	curline=frame->curline;
-	nextline=curline+linelength;
-	if (nextline >= framedata+datasize*3)
-		nextline=curline;
+	if (frame->curpix + len > datasize)
+		len = datasize-frame->curpix;
+
+	if (se401->cheight % 4)
+		blineoffset = 1;
+	bline = frame->curpix / se401->cwidth+blineoffset;
+
+	curline = frame->curline;
+	nextline = curline + linelength;
+	if (nextline >= framedata+datasize * 3)
+		nextline = curline;
 	while (len) {
-		if (frame->curlinepix>=width) {
-			frame->curlinepix-=width;
-			bline=frame->curpix/width+blineoffset;
-			curline+=linelength*2;
-			nextline+=linelength*2;
-			if (curline >= framedata+datasize*3) {
+		if (frame->curlinepix >= width) {
+			frame->curlinepix -= width;
+			bline = frame->curpix / width + blineoffset;
+			curline += linelength*2;
+			nextline += linelength*2;
+			if (curline >= framedata+datasize * 3) {
 				frame->curlinepix++;
-				curline-=3;
-				nextline-=3;
+				curline -= 3;
+				nextline -= 3;
 				len--;
 				data++;
 				frame->curpix++;
 			}
 			if (nextline >= framedata+datasize*3)
-				nextline=curline;
+				nextline = curline;
 		}
-		if ((bline&1)) {
-			if ((frame->curlinepix&1)) {
-				*(curline+2)=*data;
-				*(curline-1)=*data;
-				*(nextline+2)=*data;
-				*(nextline-1)=*data;
+		if (bline & 1) {
+			if (frame->curlinepix & 1) {
+				*(curline + 2) = *data;
+				*(curline - 1) = *data;
+				*(nextline + 2) = *data;
+				*(nextline - 1) = *data;
 			} else {
-				*(curline+1)=
-					(*(curline+1)+*data)/2;
-				*(curline-2)=
-					(*(curline-2)+*data)/2;
-				*(nextline+1)=*data;
-				*(nextline-2)=*data;
+				*(curline + 1) =
+					(*(curline + 1) + *data) / 2;
+				*(curline-2) =
+					(*(curline - 2) + *data) / 2;
+				*(nextline + 1) = *data;
+				*(nextline - 2) = *data;
 			}
 		} else {
-			if ((frame->curlinepix&1)) {
-				*(curline+1)=
-					(*(curline+1)+*data)/2;
-				*(curline-2)=
-					(*(curline-2)+*data)/2;
-				*(nextline+1)=*data;
-				*(nextline-2)=*data;
+			if (frame->curlinepix & 1) {
+				*(curline + 1) =
+					(*(curline + 1) + *data) / 2;
+				*(curline - 2) =
+					(*(curline - 2) + *data) / 2;
+				*(nextline + 1) = *data;
+				*(nextline - 2) = *data;
 			} else {
-				*curline=*data;
-				*(curline-3)=*data;
-				*nextline=*data;
-				*(nextline-3)=*data;
+				*curline = *data;
+				*(curline - 3) = *data;
+				*nextline = *data;
+				*(nextline - 3) = *data;
 			}
 		}
 		frame->curlinepix++;
-		curline-=3;
-		nextline-=3;
+		curline -= 3;
+		nextline -= 3;
 		len--;
 		data++;
 		frame->curpix++;
 	}
-	frame->curline=curline;
+	frame->curline = curline;
 
-	if (frame->curpix>=datasize) {
+	if (frame->curpix >= datasize) {
 		/* Fix the top line */
-		framedata+=linelength;
-		for (i=0; i<linelength; i++) {
+		framedata += linelength;
+		for (i = 0; i < linelength; i++) {
 			framedata--;
-			*framedata=*(framedata+linelength);
+			*framedata = *(framedata + linelength);
 		}
 		/* Fix the left side (green is already present) */
-		for (i=0; i<se401->cheight; i++) {
-			*framedata=*(framedata+3);
-			*(framedata+1)=*(framedata+4);
-			*(framedata+2)=*(framedata+5);
-			framedata+=linelength;
+		for (i = 0; i < se401->cheight; i++) {
+			*framedata = *(framedata + 3);
+			*(framedata + 1) = *(framedata + 4);
+			*(framedata + 2) = *(framedata + 5);
+			framedata += linelength;
 		}
-		frame->curpix=0;
-		frame->grabstate=FRAME_DONE;
+		frame->curpix = 0;
+		frame->grabstate = FRAME_DONE;
 		se401->framecount++;
 		se401->readcount++;
-		if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
-			se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
+		if (se401->frame[(se401->curframe + 1) &
+		    (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
+			se401->curframe = (se401->curframe+1) &
+							(SE401_NUMFRAMES-1);
 		}
 	}
 }
@@ -845,72 +853,76 @@ static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *
 static int se401_newframe(struct usb_se401 *se401, int framenr)
 {
 	DECLARE_WAITQUEUE(wait, current);
-	int errors=0;
+	int errors = 0;
 
 	while (se401->streaming &&
-	    (se401->frame[framenr].grabstate==FRAME_READY ||
-	     se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
-		if(!se401->frame[framenr].curpix) {
+	    (se401->frame[framenr].grabstate == FRAME_READY ||
+	     se401->frame[framenr].grabstate == FRAME_GRABBING)) {
+		if (!se401->frame[framenr].curpix)
 			errors++;
-		}
+
 		wait_interruptible(
-		    se401->scratch[se401->scratch_use].state!=BUFFER_READY,
-		    &se401->wq,
-		    &wait
-		);
+		    se401->scratch[se401->scratch_use].state != BUFFER_READY,
+						    &se401->wq, &wait);
 		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
-			se401->nullpackets=0;
+			se401->nullpackets = 0;
 			dev_info(&se401->dev->dev,
-				 "too many null length packets, restarting capture\n");
+			 "too many null length packets, restarting capture\n");
 			se401_stop_stream(se401);
 			se401_start_stream(se401);
 		} else {
-			if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
-				se401->frame[framenr].grabstate=FRAME_ERROR;
+			if (se401->scratch[se401->scratch_use].state !=
+								BUFFER_READY) {
+				se401->frame[framenr].grabstate = FRAME_ERROR;
 				return -EIO;
 			}
-			se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
-			if (se401->format==FMT_JANGGU) {
-				decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
-			} else {
-				decode_bayer(se401, &se401->scratch[se401->scratch_use]);
-			}
-			se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
+			se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
+			if (se401->format == FMT_JANGGU)
+				decode_JangGu(se401,
+					&se401->scratch[se401->scratch_use]);
+			else
+				decode_bayer(se401,
+					&se401->scratch[se401->scratch_use]);
+
+			se401->scratch[se401->scratch_use].state =
+							BUFFER_UNUSED;
 			se401->scratch_use++;
-			if (se401->scratch_use>=SE401_NUMSCRATCH)
-				se401->scratch_use=0;
+			if (se401->scratch_use >= SE401_NUMSCRATCH)
+				se401->scratch_use = 0;
 			if (errors > SE401_MAX_ERRORS) {
-				errors=0;
+				errors = 0;
 				dev_info(&se401->dev->dev,
-					 "too many errors, restarting capture\n");
+				      "too many errors, restarting capture\n");
 				se401_stop_stream(se401);
 				se401_start_stream(se401);
 			}
 		}
 	}
 
-	if (se401->frame[framenr].grabstate==FRAME_DONE)
+	if (se401->frame[framenr].grabstate == FRAME_DONE)
 		if (se401->enhance)
-			enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
+			enhance_picture(se401->frame[framenr].data,
+					se401->cheight * se401->cwidth * 3);
 	return 0;
 }
 
-static void usb_se401_remove_disconnected (struct usb_se401 *se401)
+static void usb_se401_remove_disconnected(struct usb_se401 *se401)
 {
 	int i;
 
 	se401->dev = NULL;
 
-	for (i=0; i<SE401_NUMSBUF; i++)
+	for (i = 0; i < SE401_NUMSBUF; i++)
 		if (se401->urb[i]) {
 			usb_kill_urb(se401->urb[i]);
 			usb_free_urb(se401->urb[i]);
 			se401->urb[i] = NULL;
 			kfree(se401->sbuf[i].data);
 		}
-	for (i=0; i<SE401_NUMSCRATCH; i++) {
+
+	for (i = 0; i < SE401_NUMSCRATCH; i++)
 		kfree(se401->scratch[i].data);
-	}
+
 	if (se401->inturb) {
 		usb_kill_urb(se401->inturb);
 		usb_free_urb(se401->inturb);
@@ -965,11 +977,11 @@ static int se401_close(struct file *file)
 		dev_info(&se401->dev->dev, "device unregistered\n");
 		usb_se401_remove_disconnected(se401);
 	} else {
-		for (i=0; i<SE401_NUMFRAMES; i++)
-			se401->frame[i].grabstate=FRAME_UNUSED;
+		for (i = 0; i < SE401_NUMFRAMES; i++)
+			se401->frame[i].grabstate = FRAME_UNUSED;
 		if (se401->streaming)
 			se401_stop_stream(se401);
-		se401->user=0;
+		se401->user = 0;
 	}
 	file->private_data = NULL;
 	return 0;
@@ -1065,7 +1077,7 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(vm, 0, sizeof(*vm));
 		vm->size = SE401_NUMFRAMES * se401->maxframesize;
 		vm->frames = SE401_NUMFRAMES;
-		for (i=0; i<SE401_NUMFRAMES; i++)
+		for (i = 0; i < SE401_NUMFRAMES; i++)
 			vm->offsets[i] = se401->maxframesize * i;
 		return 0;
 	}
@@ -1083,16 +1095,16 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		/* Is this according to the v4l spec??? */
 		if (se401_set_size(se401, vm->width, vm->height))
 			return -EINVAL;
-		se401->frame[vm->frame].grabstate=FRAME_READY;
+		se401->frame[vm->frame].grabstate = FRAME_READY;
 
 		if (!se401->streaming)
 			se401_start_stream(se401);
 
 		/* Set the picture properties */
-		if (se401->framecount==0)
+		if (se401->framecount == 0)
 			se401_send_pict(se401);
 		/* Calibrate the reset level after a few frames. */
-		if (se401->framecount%20==1)
+		if (se401->framecount % 20 == 1)
 			se401_auto_resetlevel(se401);
 
 		return 0;
@@ -1100,13 +1112,13 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	case VIDIOCSYNC:
 	{
 		int *frame = arg;
-		int ret=0;
+		int ret = 0;
 
-		if(*frame <0 || *frame >= SE401_NUMFRAMES)
+		if (*frame < 0 || *frame >= SE401_NUMFRAMES)
 			return -EINVAL;
 
-		ret=se401_newframe(se401, *frame);
-		se401->frame[*frame].grabstate=FRAME_UNUSED;
+		ret = se401_newframe(se401, *frame);
+		se401->frame[*frame].grabstate = FRAME_UNUSED;
 		return ret;
 	}
 	case VIDIOCGFBUF:
@@ -1147,36 +1159,36 @@ static long se401_ioctl(struct file *file,
 static ssize_t se401_read(struct file *file, char __user *buf,
 		     size_t count, loff_t *ppos)
 {
-	int realcount=count, ret=0;
+	int realcount = count, ret = 0;
 	struct video_device *dev = file->private_data;
 	struct usb_se401 *se401 = (struct usb_se401 *)dev;
 
 
-	if (se401->dev == NULL)
+	if (se401->dev ==  NULL)
 		return -EIO;
 	if (realcount > se401->cwidth*se401->cheight*3)
-		realcount=se401->cwidth*se401->cheight*3;
+		realcount = se401->cwidth*se401->cheight*3;
 
 	/* Shouldn't happen: */
-	if (se401->frame[0].grabstate==FRAME_GRABBING)
+	if (se401->frame[0].grabstate == FRAME_GRABBING)
 		return -EBUSY;
-	se401->frame[0].grabstate=FRAME_READY;
-	se401->frame[1].grabstate=FRAME_UNUSED;
-	se401->curframe=0;
+	se401->frame[0].grabstate = FRAME_READY;
+	se401->frame[1].grabstate = FRAME_UNUSED;
+	se401->curframe = 0;
 
 	if (!se401->streaming)
 		se401_start_stream(se401);
 
 	/* Set the picture properties */
-	if (se401->framecount==0)
+	if (se401->framecount == 0)
 		se401_send_pict(se401);
 	/* Calibrate the reset level after a few frames. */
-	if (se401->framecount%20==1)
+	if (se401->framecount%20 == 1)
 		se401_auto_resetlevel(se401);
 
-	ret=se401_newframe(se401, 0);
+	ret = se401_newframe(se401, 0);
 
-	se401->frame[0].grabstate=FRAME_UNUSED;
+	se401->frame[0].grabstate = FRAME_UNUSED;
 	if (ret)
 		return ret;
 	if (copy_to_user(buf, se401->frame[0].data, realcount))
@@ -1195,11 +1207,12 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
 
 	mutex_lock(&se401->lock);
 
-	if (se401->dev == NULL) {
+	if (se401->dev ==  NULL) {
 		mutex_unlock(&se401->lock);
 		return -EIO;
 	}
-	if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
+	if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
+							& ~(PAGE_SIZE - 1))) {
 		mutex_unlock(&se401->lock);
 		return -EINVAL;
 	}
@@ -1210,10 +1223,10 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
 			mutex_unlock(&se401->lock);
 			return -EAGAIN;
 		}
-		start += PAGE_SIZE;
-		pos += PAGE_SIZE;
+		start +=  PAGE_SIZE;
+		pos +=  PAGE_SIZE;
 		if (size > PAGE_SIZE)
-			size -= PAGE_SIZE;
+			size -=  PAGE_SIZE;
 		else
 			size = 0;
 	}
@@ -1223,7 +1236,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
 }
 
 static const struct v4l2_file_operations se401_fops = {
-	.owner =	THIS_MODULE,
+	.owner  = 	THIS_MODULE,
 	.open =         se401_open,
 	.release =      se401_close,
 	.read =         se401_read,
@@ -1241,7 +1254,7 @@ static struct video_device se401_template = {
 /***************************/
 static int se401_init(struct usb_se401 *se401, int button)
 {
-	int i=0, rc;
+	int i = 0, rc;
 	unsigned char cp[0x40];
 	char temp[200];
 	int slen;
@@ -1250,64 +1263,67 @@ static int se401_init(struct usb_se401 *se401, int button)
 	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
 
 	/* get camera descriptor */
-	rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
+	rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0,
+							cp, sizeof(cp));
 	if (cp[1] != 0x41) {
 		err("Wrong descriptor type");
 		return 1;
 	}
 	slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
 
-	se401->sizes=cp[4]+cp[5]*256;
-	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	se401->sizes = cp[4] + cp[5] * 256;
+	se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
 	if (!se401->width)
 		return 1;
-	se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
 	if (!se401->height) {
 		kfree(se401->width);
 		return 1;
 	}
-	for (i=0; i<se401->sizes; i++) {
-		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
-		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
+	for (i = 0; i < se401->sizes; i++) {
+		se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256;
+		se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256;
 	}
-	slen += snprintf (temp + slen, 200 - slen, " Sizes:");
-	for (i=0; i<se401->sizes; i++) {
-		slen += snprintf(temp + slen, 200 - slen,
+	slen += snprintf(temp + slen, 200 - slen, " Sizes:");
+	for (i = 0; i < se401->sizes; i++) {
+		slen +=  snprintf(temp + slen, 200 - slen,
 			" %dx%d", se401->width[i], se401->height[i]);
 	}
 	dev_info(&se401->dev->dev, "%s\n", temp);
-	se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
+	se401->maxframesize = se401->width[se401->sizes-1] *
+					se401->height[se401->sizes - 1] * 3;
 
-	rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
-	se401->cwidth=cp[0]+cp[1]*256;
-	rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
-	se401->cheight=cp[0]+cp[1]*256;
+	rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
+	se401->cwidth = cp[0]+cp[1]*256;
+	rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
+	se401->cheight = cp[0]+cp[1]*256;
 
 	if (!(cp[2] & SE401_FORMAT_BAYER)) {
 		err("Bayer format not supported!");
 		return 1;
 	}
 	/* set output mode (BAYER) */
-	se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
+	se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE,
+						SE401_FORMAT_BAYER, NULL, 0);
 
-	rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
-	se401->brightness=cp[0]+cp[1]*256;
+	rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
+	se401->brightness = cp[0]+cp[1]*256;
 	/* some default values */
-	se401->resetlevel=0x2d;
-	se401->rgain=0x20;
-	se401->ggain=0x20;
-	se401->bgain=0x20;
+	se401->resetlevel = 0x2d;
+	se401->rgain = 0x20;
+	se401->ggain = 0x20;
+	se401->bgain = 0x20;
 	se401_set_exposure(se401, 20000);
-	se401->palette=VIDEO_PALETTE_RGB24;
-	se401->enhance=1;
-	se401->dropped=0;
-	se401->error=0;
-	se401->framecount=0;
-	se401->readcount=0;
+	se401->palette = VIDEO_PALETTE_RGB24;
+	se401->enhance = 1;
+	se401->dropped = 0;
+	se401->error = 0;
+	se401->framecount = 0;
+	se401->readcount = 0;
 
 	/* Start interrupt transfers for snapshot button */
 	if (button) {
-		se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
+		se401->inturb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!se401->inturb) {
 			dev_info(&se401->dev->dev,
 				 "Allocation of inturb failed\n");
@@ -1325,7 +1341,7 @@ static int se401_init(struct usb_se401 *se401, int button)
 			return 1;
 		}
 	} else
-		se401->inturb=NULL;
+		se401->inturb = NULL;
 
 	/* Flash the led */
 	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
@@ -1342,8 +1358,8 @@ static int se401_probe(struct usb_interface *intf,
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_se401 *se401;
-	char *camera_name=NULL;
-	int button=1;
+	char *camera_name = NULL;
+	int button = 1;
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
@@ -1352,22 +1368,22 @@ static int se401_probe(struct usb_interface *intf,
 	interface = &intf->cur_altsetting->desc;
 
 	/* Is it an se401? */
-	if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
-		camera_name="Endpoints/Aox SE401";
-	} else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
-		camera_name="Philips PCVC665K";
-	} else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
-		camera_name="Kensington VideoCAM 67014";
-	} else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
-		camera_name="Kensington VideoCAM 6701(5/7)";
-	} else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
-		camera_name="Kensington VideoCAM 67016";
-		button=0;
+	if (le16_to_cpu(dev->descriptor.idVendor) ==  0x03e8 &&
+	    le16_to_cpu(dev->descriptor.idProduct) ==  0x0004) {
+		camera_name = "Endpoints/Aox SE401";
+	} else if (le16_to_cpu(dev->descriptor.idVendor) ==  0x0471 &&
+	    le16_to_cpu(dev->descriptor.idProduct) ==  0x030b) {
+		camera_name = "Philips PCVC665K";
+	} else if (le16_to_cpu(dev->descriptor.idVendor) ==  0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) ==  0x5001) {
+		camera_name = "Kensington VideoCAM 67014";
+	} else if (le16_to_cpu(dev->descriptor.idVendor) ==  0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) ==  0x5002) {
+		camera_name = "Kensington VideoCAM 6701(5/7)";
+	} else if (le16_to_cpu(dev->descriptor.idVendor) ==  0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) ==  0x5003) {
+		camera_name = "Kensington VideoCAM 67016";
+		button = 0;
 	} else
 		return -ENODEV;
 
@@ -1380,7 +1396,8 @@ static int se401_probe(struct usb_interface *intf,
 	/* We found one */
 	dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
 
-	if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
+	se401 = kzalloc(sizeof(*se401), GFP_KERNEL);
+	if (se401 ==  NULL) {
 		err("couldn't kmalloc se401 struct");
 		return -ENOMEM;
 	}
@@ -1398,12 +1415,14 @@ static int se401_probe(struct usb_interface *intf,
 	}
 
 	memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
-	memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
+	memcpy(se401->vdev.name, se401->camera_name,
+					strlen(se401->camera_name));
 	init_waitqueue_head(&se401->wq);
 	mutex_init(&se401->lock);
 	wmb();
 
-	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
+	if (video_register_device(&se401->vdev,
+					VFL_TYPE_GRABBER, video_nr) < 0) {
 		kfree(se401);
 		err("video_register_device failed");
 		return -EIO;
@@ -1411,20 +1430,20 @@ static int se401_probe(struct usb_interface *intf,
 	dev_info(&intf->dev, "registered new video device: video%d\n",
 		 se401->vdev.num);
 
-	usb_set_intfdata (intf, se401);
+	usb_set_intfdata(intf, se401);
 	return 0;
 }
 
 static void se401_disconnect(struct usb_interface *intf)
 {
-	struct usb_se401 *se401 = usb_get_intfdata (intf);
+	struct usb_se401 *se401 = usb_get_intfdata(intf);
 
-	usb_set_intfdata (intf, NULL);
+	usb_set_intfdata(intf, NULL);
 	if (se401) {
 		video_unregister_device(&se401->vdev);
-		if (!se401->user){
+		if (!se401->user)
 			usb_se401_remove_disconnected(se401);
-		} else {
+		else {
 			se401->frame[0].grabstate = FRAME_ERROR;
 			se401->frame[0].grabstate = FRAME_ERROR;
 
@@ -1437,10 +1456,10 @@ static void se401_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver se401_driver = {
-	.name		= "se401",
-	.id_table	= device_table,
-	.probe		= se401_probe,
-	.disconnect	= se401_disconnect,
+	.name		 =  "se401",
+	.id_table	 =  device_table,
+	.probe		 =  se401_probe,
+	.disconnect	 =  se401_disconnect,
 };
 
 
@@ -1453,9 +1472,10 @@ static struct usb_driver se401_driver = {
 
 static int __init usb_se401_init(void)
 {
-	printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version);
+	printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
+								version);
 	if (flickerless)
-		if (flickerless!=50 && flickerless!=60) {
+		if (flickerless != 50 && flickerless != 60) {
 			printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
 			return -1;
 	}
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index 2ce685db5d8..bf7d2e9765b 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -2,7 +2,7 @@
 #ifndef __LINUX_se401_H
 #define __LINUX_se401_H
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -12,9 +12,10 @@
 
 #ifdef se401_DEBUG
 #  define PDEBUG(level, fmt, args...) \
-if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
+if (debug >= level) \
+	info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
 #else
-#  define PDEBUG(level, fmt, args...) do {} while(0)
+#  define PDEBUG(level, fmt, args...) do {} while (0)
 #endif
 
 /* An almost drop-in replacement for sleep_on_interruptible */
-- 
cgit v1.2.3-70-g09d2


From 1fcbcc47d3ebd962f5486697cb85fd216e01cf89 Mon Sep 17 00:00:00 2001
From: Robert Krakora <rob.krakora@messagenetsystems.com>
Date: Fri, 12 Jun 2009 13:51:03 -0300
Subject: V4L/DVB (12002): uvc: Fix for no return value check of uvc_ctrl_set()
 which calls mutex_lock_interruptible()

Fix for no return value check of uvc_ctrl_set() which calls
mutex_lock_interruptible().

Signed-off-by: Robert Krakora <rob.krakora@messagenetsystems.com>
Acked-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/uvc/uvc_v4l2.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index f8b94d608a1..5e77cad2969 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -530,7 +530,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(&xctrl, 0, sizeof xctrl);
 		xctrl.id = ctrl->id;
 
-		uvc_ctrl_begin(video);
+	       ret = uvc_ctrl_begin(video);
+	       if (ret < 0)
+			return ret;
+
 		ret = uvc_ctrl_get(video, &xctrl);
 		uvc_ctrl_rollback(video);
 		if (ret >= 0)
@@ -547,7 +550,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		xctrl.id = ctrl->id;
 		xctrl.value = ctrl->value;
 
-		uvc_ctrl_begin(video);
+	       ret = uvc_ctrl_begin(video);
+	       if (ret < 0)
+			return ret;
+
 		ret = uvc_ctrl_set(video, &xctrl);
 		if (ret < 0) {
 			uvc_ctrl_rollback(video);
@@ -566,7 +572,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_ext_control *ctrl = ctrls->controls;
 		unsigned int i;
 
-		uvc_ctrl_begin(video);
+	       ret = uvc_ctrl_begin(video);
+	       if (ret < 0)
+			return ret;
+
 		for (i = 0; i < ctrls->count; ++ctrl, ++i) {
 			ret = uvc_ctrl_get(video, ctrl);
 			if (ret < 0) {
-- 
cgit v1.2.3-70-g09d2


From b02064caebd9b1d73dd29ebb6e75f487c5f0dbc5 Mon Sep 17 00:00:00 2001
From: Dean Anderson <dean@sensoray.com>
Date: Thu, 30 Apr 2009 12:29:38 -0300
Subject: V4L/DVB (11738): patch: s2255drv: urb completion routine fixes

Error count in read pipe completion corrected.
URB not resubmitted if shutting down.
URB not freed in completion routine if new urb_submit_fails.
(URB is freed on shutdown).

Signed-off-by: Dean Anderson <dean@sensoray.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/s2255drv.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index f08939c1f16..6be845ccc7d 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -2281,8 +2281,10 @@ static void read_pipe_completion(struct urb *purb)
 		return;
 	}
 	status = purb->status;
-	if (status != 0) {
-		dprintk(2, "read_pipe_completion: err\n");
+	/* if shutting down, do not resubmit, exit immediately */
+	if (status == -ESHUTDOWN) {
+		dprintk(2, "read_pipe_completion: err shutdown\n");
+		pipe_info->err_count++;
 		return;
 	}
 
@@ -2291,9 +2293,13 @@ static void read_pipe_completion(struct urb *purb)
 		return;
 	}
 
-	s2255_read_video_callback(dev, pipe_info);
+	if (status == 0)
+		s2255_read_video_callback(dev, pipe_info);
+	else {
+		pipe_info->err_count++;
+		dprintk(1, "s2255drv: failed URB %d\n", status);
+	}
 
-	pipe_info->err_count = 0;
 	pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
 	/* reuse urb */
 	usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
@@ -2305,7 +2311,6 @@ static void read_pipe_completion(struct urb *purb)
 	if (pipe_info->state != 0) {
 		if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
 			dev_err(&dev->udev->dev, "error submitting urb\n");
-			usb_free_urb(pipe_info->stream_urb);
 		}
 	} else {
 		dprintk(2, "read pipe complete state 0\n");
-- 
cgit v1.2.3-70-g09d2


From 06f837cadbcdedb45f0702cb57c99c404ae921e6 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Tue, 28 Apr 2009 14:35:27 -0300
Subject: V4L/DVB (11784): cx88: Fix race condition between cx8800 startup and
 hald

A power management fix to properly put the xc5000 into low power mode
revealed a race condition where hald could detect the creation of the device
file and connect to the device while the initial device configuration is
still in progress.

Lock the core structure so that video_release cannot be called and put the
tuner to sleep in the middle of the initial call to cx88_set_tvnorm() in
cx8800_initdev()

Thanks to Michael Krufky for discovering the issue and providing an
environment to test in.

Cc: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-video.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index b993d42fe73..d6d6d13a6a6 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -926,8 +926,10 @@ static int video_release(struct file *file)
 	file->private_data = NULL;
 	kfree(fh);
 
+	mutex_lock(&dev->core->lock);
 	if(atomic_dec_and_test(&dev->core->users))
 		call_all(dev->core, tuner, s_standby);
+	mutex_unlock(&dev->core->lock);
 
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2


From e878cf3a47a5d99635edc564423a9a4469c17810 Mon Sep 17 00:00:00 2001
From: Marton Balint <cus@fazekas.hu>
Date: Tue, 31 Mar 2009 19:01:51 -0300
Subject: V4L/DVB (11394): cx88: Add support for stereo and sap detection for
 A2

The patch implements reliable stereo and sap detection for the A2 sound
standard.  This is achieved by processing the samples of the audio RDS fifo of
the cx2388x chip. A2M, EIAJ and BTSC stereo/sap detection is also possible with
this new approach, but it's not implemented yet. Stereo detection when alsa
handles the sound also does not work yet.

Signed-off-by: Marton Balint <cus@fazekas.hu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/Makefile       |   2 +-
 drivers/media/video/cx88/cx88-core.c    |  26 ++-
 drivers/media/video/cx88/cx88-dsp.c     | 299 ++++++++++++++++++++++++++++++++
 drivers/media/video/cx88/cx88-tvaudio.c |  54 +++++-
 drivers/media/video/cx88/cx88.h         |  10 ++
 5 files changed, 381 insertions(+), 10 deletions(-)
 create mode 100644 drivers/media/video/cx88/cx88-dsp.c

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index b06b1275a9e..5b7e26761f0 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -1,5 +1,5 @@
 cx88xx-objs	:= cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
-		   cx88-input.o
+		   cx88-dsp.o cx88-input.o
 cx8800-objs	:= cx88-video.o cx88-vbi.o
 cx8802-objs	:= cx88-mpeg.o
 
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index b4049de071a..cf634606ba9 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -231,7 +231,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
  * can use the whole SDRAM for the DMA fifos.  To simplify things, we
  * use a static memory layout.  That surely will waste memory in case
  * we don't use all DMA channels at the same time (which will be the
- * case most of the time).  But that still gives us enougth FIFO space
+ * case most of the time).  But that still gives us enough FIFO space
  * to be able to deal with insane long pci latencies ...
  *
  * FIFO space allocations:
@@ -241,6 +241,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
  *    channel  24    (vbi)      -  4.0k
  *    channels 25+26 (audio)    -  4.0k
  *    channel  28    (mpeg)     -  4.0k
+ *    channel  27    (audio rds)-  3.0k
  *    TOTAL                     = 29.0k
  *
  * Every channel has 160 bytes control data (64 bytes instruction
@@ -337,6 +338,18 @@ struct sram_channel cx88_sram_channels[] = {
 		.cnt1_reg   = MO_DMA28_CNT1,
 		.cnt2_reg   = MO_DMA28_CNT2,
 	},
+	[SRAM_CH27] = {
+		.name       = "audio rds",
+		.cmds_start = 0x1801C0,
+		.ctrl_start = 0x180860,
+		.cdt        = 0x180860 + 64,
+		.fifo_start = 0x187400,
+		.fifo_size  = 0x000C00,
+		.ptr1_reg   = MO_DMA27_PTR1,
+		.ptr2_reg   = MO_DMA27_PTR2,
+		.cnt1_reg   = MO_DMA27_CNT1,
+		.cnt2_reg   = MO_DMA27_CNT2,
+	},
 };
 
 int cx88_sram_channel_setup(struct cx88_core *core,
@@ -598,6 +611,7 @@ int cx88_reset(struct cx88_core *core)
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
 
 	/* misc init ... */
 	cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
@@ -796,6 +810,8 @@ int cx88_start_audio_dma(struct cx88_core *core)
 	/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
 	int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
 
+	int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
+
 	/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
 	if (cx_read(MO_AUD_DMACNTRL) & 0x10)
 		return 0;
@@ -803,12 +819,14 @@ int cx88_start_audio_dma(struct cx88_core *core)
 	/* setup fifo + format */
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
+				rds_bpl, 0);
 
 	cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
-	cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
+	cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
 
-	/* start dma */
-	cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
+	/* enable Up, Down and Audio RDS fifo */
+	cx_write(MO_AUD_DMACNTRL, 0x0007);
 
 	return 0;
 }
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
new file mode 100644
index 00000000000..a78286e853c
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -0,0 +1,299 @@
+/*
+ *
+ *  Stereo and SAP detection for cx88
+ *
+ *  Copyright (c) 2009 Marton Balint <cus@fazekas.hu>
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+
+#include "cx88.h"
+#include "cx88-reg.h"
+
+#define INT_PI			((s32)(3.141592653589 * 32768.0))
+
+#define compat_remainder(a, b) \
+	 ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0)
+
+#define baseband_freq(carrier, srate, tone) ((s32)( \
+	 (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI))
+
+/* We calculate the baseband frequencies of the carrier and the pilot tones
+ * based on the the sampling rate of the audio rds fifo. */
+
+#define FREQ_A2_CARRIER         baseband_freq(54687.5, 2689.36, 0.0)
+#define FREQ_A2_DUAL            baseband_freq(54687.5, 2689.36, 274.1)
+#define FREQ_A2_STEREO          baseband_freq(54687.5, 2689.36, 117.5)
+
+/* The frequencies below are from the reference driver. They probably need
+ * further adjustments, because they are not tested at all. You may even need
+ * to play a bit with the registers of the chip to select the proper signal
+ * for the input of the audio rds fifo, and measure it's sampling rate to
+ * calculate the proper baseband frequencies... */
+
+#define FREQ_A2M_CARRIER	((s32)(2.114516 * 32768.0))
+#define FREQ_A2M_DUAL		((s32)(2.754916 * 32768.0))
+#define FREQ_A2M_STEREO		((s32)(2.462326 * 32768.0))
+
+#define FREQ_EIAJ_CARRIER	((s32)(1.963495 * 32768.0)) /* 5pi/8  */
+#define FREQ_EIAJ_DUAL		((s32)(2.562118 * 32768.0))
+#define FREQ_EIAJ_STEREO	((s32)(2.601053 * 32768.0))
+
+#define FREQ_BTSC_DUAL		((s32)(1.963495 * 32768.0)) /* 5pi/8  */
+#define FREQ_BTSC_DUAL_REF	((s32)(1.374446 * 32768.0)) /* 7pi/16 */
+
+#define FREQ_BTSC_SAP		((s32)(2.471532 * 32768.0))
+#define FREQ_BTSC_SAP_REF	((s32)(1.730072 * 32768.0))
+
+/* The spectrum of the signal should be empty between these frequencies. */
+#define FREQ_NOISE_START	((s32)(0.100000 * 32768.0))
+#define FREQ_NOISE_END		((s32)(1.200000 * 32768.0))
+
+static unsigned int dsp_debug;
+module_param(dsp_debug, int, 0644);
+MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages");
+
+#define dprintk(level, fmt, arg...)	if (dsp_debug >= level) \
+	printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
+
+static s32 int_cos(u32 x)
+{
+	u32 t2, t4, t6, t8;
+	s32 ret;
+	u16 period = x / INT_PI;
+	if (period % 2)
+		return -int_cos(x - INT_PI);
+	x = x % INT_PI;
+	if (x > INT_PI/2)
+		return -int_cos(INT_PI/2 - (x % (INT_PI/2)));
+	/* Now x is between 0 and INT_PI/2.
+	 * To calculate cos(x) we use it's Taylor polinom. */
+	t2 = x*x/32768/2;
+	t4 = t2*x/32768*x/32768/3/4;
+	t6 = t4*x/32768*x/32768/5/6;
+	t8 = t6*x/32768*x/32768/7/8;
+	ret = 32768-t2+t4-t6+t8;
+	return ret;
+}
+
+static u32 int_goertzel(s16 x[], u32 N, u32 freq)
+{
+	/* We use the Goertzel algorithm to determine the power of the
+	 * given frequency in the signal */
+	s32 s_prev = 0;
+	s32 s_prev2 = 0;
+	s32 coeff = 2*int_cos(freq);
+	u32 i;
+	for (i = 0; i < N; i++) {
+		s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2;
+		s_prev2 = s_prev;
+		s_prev = s;
+	}
+	return (u32)(((s64)s_prev2*s_prev2 + (s64)s_prev*s_prev -
+		      (s64)coeff*s_prev2*s_prev/32768)/N/N);
+}
+
+static u32 freq_magnitude(s16 x[], u32 N, u32 freq)
+{
+	u32 sum = int_goertzel(x, N, freq);
+	return (u32)int_sqrt(sum);
+}
+
+static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end)
+{
+	int i;
+	u32 sum = 0;
+	u32 freq_step;
+	int samples = 5;
+
+	if (N > 192) {
+		/* The last 192 samples are enough for noise detection */
+		x += (N-192);
+		N = 192;
+	}
+
+	freq_step = (freq_end - freq_start) / (samples - 1);
+
+	for (i = 0; i < samples; i++) {
+		sum += int_goertzel(x, N, freq_start);
+		freq_start += freq_step;
+	}
+
+	return (u32)int_sqrt(sum / samples);
+}
+
+static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N)
+{
+	s32 carrier, stereo, dual, noise;
+	s32 carrier_freq, stereo_freq, dual_freq;
+	s32 ret;
+
+	switch (core->tvaudio) {
+	case WW_BG:
+	case WW_DK:
+		carrier_freq = FREQ_A2_CARRIER;
+		stereo_freq = FREQ_A2_STEREO;
+		dual_freq = FREQ_A2_DUAL;
+		break;
+	case WW_M:
+		carrier_freq = FREQ_A2M_CARRIER;
+		stereo_freq = FREQ_A2M_STEREO;
+		dual_freq = FREQ_A2M_DUAL;
+		break;
+	case WW_EIAJ:
+		carrier_freq = FREQ_EIAJ_CARRIER;
+		stereo_freq = FREQ_EIAJ_STEREO;
+		dual_freq = FREQ_EIAJ_DUAL;
+		break;
+	default:
+		printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n",
+		       core->name, core->tvaudio, __func__);
+		return UNSET;
+	}
+
+	carrier = freq_magnitude(x, N, carrier_freq);
+	stereo  = freq_magnitude(x, N, stereo_freq);
+	dual    = freq_magnitude(x, N, dual_freq);
+	noise   = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END);
+
+	dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, "
+		   "noise=%d\n", carrier, stereo, dual, noise);
+
+	if (stereo > dual)
+		ret = V4L2_TUNER_SUB_STEREO;
+	else
+		ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+	if (core->tvaudio == WW_EIAJ) {
+		/* EIAJ checks may need adjustments */
+		if ((carrier > max(stereo, dual)*2) &&
+		    (carrier < max(stereo, dual)*6) &&
+		    (carrier > 20 && carrier < 200) &&
+		    (max(stereo, dual) > min(stereo, dual))) {
+			/* For EIAJ the carrier is always present,
+			   so we probably don't need noise detection */
+			return ret;
+		}
+	} else {
+		if ((carrier > max(stereo, dual)*2) &&
+		    (carrier < max(stereo, dual)*8) &&
+		    (carrier > 20 && carrier < 200) &&
+		    (noise < 10) &&
+		    (max(stereo, dual) > min(stereo, dual)*2)) {
+			return ret;
+		}
+	}
+	return V4L2_TUNER_SUB_MONO;
+}
+
+static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N)
+{
+	s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF);
+	s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP);
+	s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF);
+	s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL);
+	dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d"
+		   "\n", dual_ref, dual, sap_ref, sap);
+	/* FIXME: Currently not supported */
+	return UNSET;
+}
+
+static s16 *read_rds_samples(struct cx88_core *core, u32 *N)
+{
+	struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
+	s16 *samples;
+
+	unsigned int i;
+	unsigned int bpl = srch->fifo_size/AUD_RDS_LINES;
+	unsigned int spl = bpl/4;
+	unsigned int sample_count = spl*(AUD_RDS_LINES-1);
+
+	u32 current_address = cx_read(srch->ptr1_reg);
+	u32 offset = (current_address - srch->fifo_start + bpl);
+
+	dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), "
+		"sample_count=%d, aud_intstat=%08x\n", current_address,
+		current_address - srch->fifo_start, sample_count,
+		cx_read(MO_AUD_INTSTAT));
+
+	samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL);
+	if (!samples)
+		return NULL;
+
+	*N = sample_count;
+
+	for (i = 0; i < sample_count; i++)  {
+		offset = offset % (AUD_RDS_LINES*bpl);
+		samples[i] = cx_read(srch->fifo_start + offset);
+		offset += 4;
+	}
+
+	if (dsp_debug >= 2) {
+		dprintk(2, "RDS samples dump: ");
+		for (i = 0; i < sample_count; i++)
+			printk("%hd ", samples[i]);
+		printk(".\n");
+	}
+
+	return samples;
+}
+
+s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
+{
+	s16 *samples;
+	u32 N = 0;
+	s32 ret = UNSET;
+
+	/* If audio RDS fifo is disabled, we can't read the samples */
+	if (!(cx_read(MO_AUD_DMACNTRL) & 0x04))
+		return ret;
+	if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS))
+		return ret;
+
+	/* Wait at least 500 ms after an audio standard change */
+	if (time_before(jiffies, core->last_change + msecs_to_jiffies(500)))
+		return ret;
+
+	samples = read_rds_samples(core, &N);
+
+	if (!samples)
+		return ret;
+
+	switch (core->tvaudio) {
+	case WW_BG:
+	case WW_DK:
+		ret = detect_a2_a2m_eiaj(core, samples, N);
+		break;
+	case WW_BTSC:
+		ret = detect_btsc(core, samples, N);
+		break;
+	}
+
+	kfree(samples);
+
+	if (UNSET != ret)
+		dprintk(1, "stereo/sap detection result:%s%s%s\n",
+			   (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "",
+			   (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
+			   (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : "");
+
+	return ret;
+}
+EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap);
+
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 7dd506b987f..f9501eb8557 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
 	/* unmute */
 	volume = cx_sread(SHADOW_AUD_VOL_CTL);
 	cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
+
+	core->last_change = jiffies;
 }
 
 /* ----------------------------------------------------------- */
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
 		break;
 	case WW_BG:
 	case WW_DK:
+	case WW_M:
 	case WW_I:
 	case WW_L:
 		/* prepare all dsp registers */
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
 		if (0 == cx88_detect_nicam(core)) {
 			/* fall back to fm / am mono */
 			set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
+			core->audiomode_current = V4L2_TUNER_MODE_MONO;
 			core->use_nicam = 0;
 		} else {
 			core->use_nicam = 1;
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
 void cx88_newstation(struct cx88_core *core)
 {
 	core->audiomode_manual = UNSET;
+	core->last_change = jiffies;
 }
 
 void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
 			aud_ctl_names[cx_read(AUD_CTL) & 63]);
 	core->astat = reg;
 
-/* TODO
-	Reading from AUD_STATUS is not enough
-	for auto-detecting sap/dual-fm/nicam.
-	Add some code here later.
-*/
+	t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
+	    V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+	t->rxsubchans = UNSET;
+	t->audmode = V4L2_TUNER_MODE_MONO;
 
+	switch (mode) {
+	case 0:
+		t->audmode = V4L2_TUNER_MODE_STEREO;
+		break;
+	case 1:
+		t->audmode = V4L2_TUNER_MODE_LANG2;
+		break;
+	case 2:
+		t->audmode = V4L2_TUNER_MODE_MONO;
+		break;
+	case 3:
+		t->audmode = V4L2_TUNER_MODE_SAP;
+		break;
+	}
+
+	switch (core->tvaudio) {
+	case WW_BTSC:
+	case WW_BG:
+	case WW_DK:
+	case WW_M:
+	case WW_EIAJ:
+		if (!core->use_nicam) {
+			t->rxsubchans = cx88_dsp_detect_stereo_sap(core);
+			break;
+		}
+		break;
+	default:
+		/* nothing */
+		break;
+	}
+
+	/* If software stereo detection is not supported... */
+	if (UNSET == t->rxsubchans) {
+		t->rxsubchans = V4L2_TUNER_SUB_MONO;
+		/* If the hardware itself detected stereo, also return
+		   stereo as an available subchannel */
+		if (V4L2_TUNER_MODE_STEREO == t->audmode)
+			t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+	}
 	return;
 }
 
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
 		break;
 	case WW_BG:
 	case WW_DK:
+	case WW_M:
 	case WW_I:
 	case WW_L:
 		if (1 == core->use_nicam) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f55e4eeed78..9d83762163f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -65,6 +65,8 @@
 #define VBI_LINE_COUNT              17
 #define VBI_LINE_LENGTH           2048
 
+#define AUD_RDS_LINES		     4
+
 /* need "shadow" registers for some write-only ones ... */
 #define SHADOW_AUD_VOL_CTL           1
 #define SHADOW_AUD_BAL_CTL           2
@@ -132,6 +134,7 @@ struct cx88_ctrl {
 #define SRAM_CH25 4   /* audio */
 #define SRAM_CH26 5
 #define SRAM_CH28 6   /* mpeg */
+#define SRAM_CH27 7   /* audio rds */
 /* more */
 
 struct sram_channel {
@@ -352,6 +355,7 @@ struct cx88_core {
 	u32                        input;
 	u32                        astat;
 	u32			   use_nicam;
+	unsigned long		   last_change;
 
 	/* IR remote control state */
 	struct cx88_IR             *ir;
@@ -654,6 +658,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
 #define WW_I2SPT	 8
 #define WW_FM		 9
 #define WW_I2SADC	 10
+#define WW_M		 11
 
 void cx88_set_tvaudio(struct cx88_core *core);
 void cx88_newstation(struct cx88_core *core);
@@ -666,6 +671,11 @@ int cx8802_unregister_driver(struct cx8802_driver *drv);
 struct cx8802_dev *cx8802_get_device(int minor);
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
 
+/* ----------------------------------------------------------- */
+/* cx88-dsp.c                                                  */
+
+s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
+
 /* ----------------------------------------------------------- */
 /* cx88-input.c                                                */
 
-- 
cgit v1.2.3-70-g09d2


From 083d6f8c81e9a2bd5f71633fb38acda35fb8240c Mon Sep 17 00:00:00 2001
From: Marton Balint <cus@fazekas.hu>
Date: Tue, 31 Mar 2009 19:01:52 -0300
Subject: V4L/DVB (11395): cx88: audio thread: if stereo detection is hw
 supported don't do it manually

The sole purpose of the audio thread is to detect if stereo transmission is
available, and if it is, then switch to stereo mode (and switch back, if it's
no longer available). This manual autodetection is useful for some audio
standards (e.g. A2) where cx88_get_stereo CAN detect stereo sound, but the
cx2388x chip CANNOT auto-detect stereo sound.

However, for other audio standards, the cx2388x chip CAN auto-detect the stereo
sound, so the manual autodetection in the audio thread is not needed. In fact,
it can cause serious problems because for some of these audio standards,
cx88_get_stereo CANNOT detect the presence of stereo sound.  Besides that, if
the hardware automatically detects stereo/mono sound, you cannot set
core->audiomode_current to the real current audio mode on channel change.

With this patch, the manual autodetection is only used if audiomode_current is
known after a channel change (because of the initial mono mode), and
hardware-based stereo autodetecion is not applicable for the current audio
standard.

Signed-off-by: Marton Balint <cus@fazekas.hu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-tvaudio.c | 51 +++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 18 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index f9501eb8557..0a8699fa729 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -976,24 +976,39 @@ int cx88_audio_thread(void *data)
 			break;
 		try_to_freeze();
 
-		/* just monitor the audio status for now ... */
-		memset(&t, 0, sizeof(t));
-		cx88_get_stereo(core, &t);
-
-		if (UNSET != core->audiomode_manual)
-			/* manually set, don't do anything. */
-			continue;
-
-		/* monitor signal */
-		if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
-			mode = V4L2_TUNER_MODE_STEREO;
-		else
-			mode = V4L2_TUNER_MODE_MONO;
-		if (mode == core->audiomode_current)
-			continue;
-
-		/* automatically switch to best available mode */
-		cx88_set_stereo(core, mode, 0);
+		switch (core->tvaudio) {
+		case WW_BG:
+		case WW_DK:
+		case WW_M:
+		case WW_I:
+		case WW_L:
+			if (core->use_nicam)
+				goto hw_autodetect;
+
+			/* just monitor the audio status for now ... */
+			memset(&t, 0, sizeof(t));
+			cx88_get_stereo(core, &t);
+
+			if (UNSET != core->audiomode_manual)
+				/* manually set, don't do anything. */
+				continue;
+
+			/* monitor signal and set stereo if available */
+			if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
+				mode = V4L2_TUNER_MODE_STEREO;
+			else
+				mode = V4L2_TUNER_MODE_MONO;
+			if (mode == core->audiomode_current)
+				continue;
+			/* automatically switch to best available mode */
+			cx88_set_stereo(core, mode, 0);
+			break;
+		default:
+hw_autodetect:
+			/* stereo autodetection is supported by hardware so
+			   we don't need to do it manually. Do nothing. */
+			break;
+		}
 	}
 
 	dprintk("cx88: tvaudio thread exiting\n");
-- 
cgit v1.2.3-70-g09d2


From 2325a6b98609b6559ce5da7528fc0f5a6d0d8e9b Mon Sep 17 00:00:00 2001
From: Marton Balint <cus@fazekas.hu>
Date: Tue, 31 Mar 2009 19:01:53 -0300
Subject: V4L/DVB (11396): cx88: avoid reprogramming every audio register on A2
 stereo/mono change

This patch changes cx88_set_stereo to avoid resetting all of the audio
registers on stereo/mono change if the audio standard is A2, and set
only the AUD_CTL register. The benefit of this method is that it
eliminates the annoying clicking noise on setting the audio mode to
stereo or mono.

The driver had used the same method 1.5 years ago (and for FM radio it
still does), but a pretty big cleanup commit changed it to the
"complete audio reset" method, although the reason for this move was
not clear. (If somebody knows why it was necessary, please let me
know!)

The original commit: http://linuxtv.org/hg/v4l-dvb/rev/ffe313541d7d

Signed-off-by: Marton Balint <cus@fazekas.hu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-tvaudio.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 0a8699fa729..e8316cf7f32 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -916,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
 				set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
 			} else {
 				/* TODO: Add A2 autodection */
+				mask = 0x3f;
 				switch (mode) {
 				case V4L2_TUNER_MODE_MONO:
 				case V4L2_TUNER_MODE_LANG1:
-					set_audio_standard_A2(core,
-							      EN_A2_FORCE_MONO1);
+					ctl = EN_A2_FORCE_MONO1;
 					break;
 				case V4L2_TUNER_MODE_LANG2:
-					set_audio_standard_A2(core,
-							      EN_A2_FORCE_MONO2);
+					ctl = EN_A2_FORCE_MONO2;
 					break;
 				case V4L2_TUNER_MODE_STEREO:
 				case V4L2_TUNER_MODE_LANG1_LANG2:
-					set_audio_standard_A2(core,
-							      EN_A2_FORCE_STEREO);
+					ctl = EN_A2_FORCE_STEREO;
 					break;
 				}
 			}
-- 
cgit v1.2.3-70-g09d2


From 7561300a7cea56b61fa28b36d40cdfab22af38bd Mon Sep 17 00:00:00 2001
From: Miroslav Sustek <sustmidown@centrum.cz>
Date: Mon, 6 Apr 2009 20:07:04 -0300
Subject: V4L/DVB (11441): cx88-dsp: fixing 64bit math

cx88-dsp: fixing 64bit math on 32bit kernels

Some gcc versions report the missing of __divdi3

[mchehab.redhat.com: CodingStyle fixes]

Signed-off-by: Miroslav Sustek <sustmidown@centrum.cz>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-dsp.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
index a78286e853c..3e5eaf3fe2a 100644
--- a/drivers/media/video/cx88/cx88-dsp.c
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
+#include <asm/div64.h>
 
 #include "cx88.h"
 #include "cx88-reg.h"
@@ -100,13 +101,25 @@ static u32 int_goertzel(s16 x[], u32 N, u32 freq)
 	s32 s_prev2 = 0;
 	s32 coeff = 2*int_cos(freq);
 	u32 i;
+
+	u64 tmp;
+	u32 divisor;
+
 	for (i = 0; i < N; i++) {
 		s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2;
 		s_prev2 = s_prev;
 		s_prev = s;
 	}
-	return (u32)(((s64)s_prev2*s_prev2 + (s64)s_prev*s_prev -
-		      (s64)coeff*s_prev2*s_prev/32768)/N/N);
+
+	tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev -
+		      (s64)coeff * s_prev2 * s_prev / 32768;
+
+	/* XXX: N must be low enough so that N*N fits in s32.
+	 * Else we need two divisions. */
+	divisor = N * N;
+	do_div(tmp, divisor);
+
+	return (u32) tmp;
 }
 
 static u32 freq_magnitude(s16 x[], u32 N, u32 freq)
-- 
cgit v1.2.3-70-g09d2


From 9fd6418a6a7655b69cfa0ae27a3639a6d0b2924f Mon Sep 17 00:00:00 2001
From: "Figo.zhang" <figo1802@gmail.com>
Date: Tue, 16 Jun 2009 13:31:29 -0300
Subject: V4L/DVB (12004): poll method lose race condition

bttv-driver.c,cx23885-video.c,cx88-video.c: poll method lose race condition for capture video.

Signed-off-by: Figo.zhang <figo1802@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/bt8xx/bttv-driver.c     | 11 +++++++----
 drivers/media/video/cx23885/cx23885-video.c | 14 ++++++++++----
 drivers/media/video/cx88/cx88-video.c       | 14 ++++++++++----
 3 files changed, 27 insertions(+), 12 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 7c1f82661ee..5eb1464af67 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3152,6 +3152,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
 	struct bttv_fh *fh = file->private_data;
 	struct bttv_buffer *buf;
 	enum v4l2_field field;
+	unsigned int rc = POLLERR;
 
 	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
 		if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
@@ -3160,9 +3161,10 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
 	}
 
 	if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
+		mutex_lock(&fh->cap.vb_lock);
 		/* streaming capture */
 		if (list_empty(&fh->cap.stream))
-			return POLLERR;
+			goto err;
 		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
 	} else {
 		/* read() capture */
@@ -3191,11 +3193,12 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
 	poll_wait(file, &buf->vb.done, wait);
 	if (buf->vb.state == VIDEOBUF_DONE ||
 	    buf->vb.state == VIDEOBUF_ERROR)
-		return POLLIN|POLLRDNORM;
-	return 0;
+		rc =  POLLIN|POLLRDNORM;
+	else
+		rc = 0;
 err:
 	mutex_unlock(&fh->cap.vb_lock);
-	return POLLERR;
+	return rc;
 }
 
 static int bttv_open(struct file *file)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 68068c6d098..66bbd2e7110 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -796,6 +796,7 @@ static unsigned int video_poll(struct file *file,
 {
 	struct cx23885_fh *fh = file->private_data;
 	struct cx23885_buffer *buf;
+	unsigned int rc = POLLERR;
 
 	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
 		if (!res_get(fh->dev, fh, RESOURCE_VBI))
@@ -803,23 +804,28 @@ static unsigned int video_poll(struct file *file,
 		return videobuf_poll_stream(file, &fh->vbiq, wait);
 	}
 
+	mutex_lock(&fh->vidq.vb_lock);
 	if (res_check(fh, RESOURCE_VIDEO)) {
 		/* streaming capture */
 		if (list_empty(&fh->vidq.stream))
-			return POLLERR;
+			goto done;
 		buf = list_entry(fh->vidq.stream.next,
 			struct cx23885_buffer, vb.stream);
 	} else {
 		/* read() capture */
 		buf = (struct cx23885_buffer *)fh->vidq.read_buf;
 		if (NULL == buf)
-			return POLLERR;
+			goto done;
 	}
 	poll_wait(file, &buf->vb.done, wait);
 	if (buf->vb.state == VIDEOBUF_DONE ||
 	    buf->vb.state == VIDEOBUF_ERROR)
-		return POLLIN|POLLRDNORM;
-	return 0;
+		rc =  POLLIN|POLLRDNORM;
+	else
+		rc = 0;
+done:
+	mutex_unlock(&fh->vidq.vb_lock);
+	return rc;
 }
 
 static int video_release(struct file *file)
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index d6d6d13a6a6..0ccac702bea 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -869,6 +869,7 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct cx8800_fh *fh = file->private_data;
 	struct cx88_buffer *buf;
+	unsigned int rc = POLLERR;
 
 	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
 		if (!res_get(fh->dev,fh,RESOURCE_VBI))
@@ -876,22 +877,27 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 		return videobuf_poll_stream(file, &fh->vbiq, wait);
 	}
 
+	mutex_lock(&fh->vidq.vb_lock);
 	if (res_check(fh,RESOURCE_VIDEO)) {
 		/* streaming capture */
 		if (list_empty(&fh->vidq.stream))
-			return POLLERR;
+			goto done;
 		buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
 	} else {
 		/* read() capture */
 		buf = (struct cx88_buffer*)fh->vidq.read_buf;
 		if (NULL == buf)
-			return POLLERR;
+			goto done;
 	}
 	poll_wait(file, &buf->vb.done, wait);
 	if (buf->vb.state == VIDEOBUF_DONE ||
 	    buf->vb.state == VIDEOBUF_ERROR)
-		return POLLIN|POLLRDNORM;
-	return 0;
+		rc = POLLIN|POLLRDNORM;
+	else
+		rc = 0;
+done:
+	mutex_unlock(&fh->vidq.vb_lock);
+	return rc;
 }
 
 static int video_release(struct file *file)
-- 
cgit v1.2.3-70-g09d2


From 11c635a25b9f3a5d87409ce46cf2e05c500251ec Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 25 May 2009 15:04:22 -0300
Subject: V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f1108f1be83..f7e0355ad64 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -863,6 +863,32 @@ out:
 	return ret;
 }
 
+static int vidioc_enum_framesizes(struct file *file, void *priv,
+				  struct v4l2_frmsizeenum *fsize)
+{
+	struct gspca_dev *gspca_dev = priv;
+	int i;
+	__u32 index = 0;
+
+	for (i = 0; i < gspca_dev->cam.nmodes; i++) {
+		if (fsize->pixel_format !=
+				gspca_dev->cam.cam_mode[i].pixelformat)
+			continue;
+
+		if (fsize->index == index) {
+			fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+			fsize->discrete.width =
+				gspca_dev->cam.cam_mode[i].width;
+			fsize->discrete.height =
+				gspca_dev->cam.cam_mode[i].height;
+			return 0;
+		}
+		index++;
+	}
+
+	return -EINVAL;
+}
+
 static void gspca_release(struct video_device *vfd)
 {
 	struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
@@ -1858,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
 	.vidioc_g_parm		= vidioc_g_parm,
 	.vidioc_s_parm		= vidioc_s_parm,
 	.vidioc_s_std		= vidioc_s_std,
+	.vidioc_enum_framesizes = vidioc_enum_framesizes,
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	.vidiocgmbuf          = vidiocgmbuf,
 #endif
-- 
cgit v1.2.3-70-g09d2


From 720b17e759a50635c429ccaa2ec3d01edb4f92d6 Mon Sep 17 00:00:00 2001
From: Magnus Damm <damm@igel.co.jp>
Date: Tue, 16 Jun 2009 15:32:36 -0700
Subject: videobuf-dma-contig: zero copy USERPTR support

Since videobuf-dma-contig is designed to handle physically contiguous
memory, this patch modifies the videobuf-dma-contig code to only accept a
user space pointer to physically contiguous memory.  For now only
VM_PFNMAP vmas are supported, so forget hotplug.

On SuperH Mobile we use this with our sh_mobile_ceu_camera driver together
with various multimedia accelerator blocks that are exported to user space
using UIO.  The UIO kernel code exports physically contiguous memory to
user space and lets the user space application mmap() this memory and pass
a pointer using the USERPTR interface for V4L2 zero copy operation.

With this approach we support zero copy capture, hardware scaling and
various forms of hardware encoding and decoding.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 drivers/media/video/videobuf-dma-contig.c | 94 +++++++++++++++++++++++++++++--
 1 file changed, 89 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 6109fb5f34e..0c29a019bc8 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/pagemap.h>
 #include <linux/dma-mapping.h>
 #include <media/videobuf-dma-contig.h>
 
@@ -25,6 +26,7 @@ struct videobuf_dma_contig_memory {
 	void *vaddr;
 	dma_addr_t dma_handle;
 	unsigned long size;
+	int is_userptr;
 };
 
 #define MAGIC_DC_MEM 0x0733ac61
@@ -108,6 +110,82 @@ static struct vm_operations_struct videobuf_vm_ops = {
 	.close    = videobuf_vm_close,
 };
 
+/**
+ * videobuf_dma_contig_user_put() - reset pointer to user space buffer
+ * @mem: per-buffer private videobuf-dma-contig data
+ *
+ * This function resets the user space pointer
+ */
+static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
+{
+	mem->is_userptr = 0;
+	mem->dma_handle = 0;
+	mem->size = 0;
+}
+
+/**
+ * videobuf_dma_contig_user_get() - setup user space memory pointer
+ * @mem: per-buffer private videobuf-dma-contig data
+ * @vb: video buffer to map
+ *
+ * This function validates and sets up a pointer to user space memory.
+ * Only physically contiguous pfn-mapped memory is accepted.
+ *
+ * Returns 0 if successful.
+ */
+static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
+					struct videobuf_buffer *vb)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long prev_pfn, this_pfn;
+	unsigned long pages_done, user_address;
+	int ret;
+
+	mem->size = PAGE_ALIGN(vb->size);
+	mem->is_userptr = 0;
+	ret = -EINVAL;
+
+	down_read(&mm->mmap_sem);
+
+	vma = find_vma(mm, vb->baddr);
+	if (!vma)
+		goto out_up;
+
+	if ((vb->baddr + mem->size) > vma->vm_end)
+		goto out_up;
+
+	pages_done = 0;
+	prev_pfn = 0; /* kill warning */
+	user_address = vb->baddr;
+
+	while (pages_done < (mem->size >> PAGE_SHIFT)) {
+		ret = follow_pfn(vma, user_address, &this_pfn);
+		if (ret)
+			break;
+
+		if (pages_done == 0)
+			mem->dma_handle = this_pfn << PAGE_SHIFT;
+		else if (this_pfn != (prev_pfn + 1))
+			ret = -EFAULT;
+
+		if (ret)
+			break;
+
+		prev_pfn = this_pfn;
+		user_address += PAGE_SIZE;
+		pages_done++;
+	}
+
+	if (!ret)
+		mem->is_userptr = 1;
+
+ out_up:
+	up_read(&current->mm->mmap_sem);
+
+	return ret;
+}
+
 static void *__videobuf_alloc(size_t size)
 {
 	struct videobuf_dma_contig_memory *mem;
@@ -154,12 +232,11 @@ static int __videobuf_iolock(struct videobuf_queue *q,
 	case V4L2_MEMORY_USERPTR:
 		dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
 
-		/* The only USERPTR currently supported is the one needed for
-		   read() method.
-		 */
+		/* handle pointer from user space */
 		if (vb->baddr)
-			return -EINVAL;
+			return videobuf_dma_contig_user_get(mem, vb);
 
+		/* allocate memory for the read() method */
 		mem->size = PAGE_ALIGN(vb->size);
 		mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
 						&mem->dma_handle, GFP_KERNEL);
@@ -400,7 +477,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
 	   So, it should free memory only if the memory were allocated for
 	   read() operation.
 	 */
-	if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
+	if (buf->memory != V4L2_MEMORY_USERPTR)
 		return;
 
 	if (!mem)
@@ -408,6 +485,13 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
 
 	MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
 
+	/* handle user space pointer case */
+	if (buf->baddr) {
+		videobuf_dma_contig_user_put(mem);
+		return;
+	}
+
+	/* read() method */
 	dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
 	mem->vaddr = NULL;
 }
-- 
cgit v1.2.3-70-g09d2


From 0a861e9eb76c68b23be1aa4758269c5b412089a9 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Date: Tue, 12 May 2009 15:13:32 +0000
Subject: soc-camera: unify i2c camera device platform data

Unify i2c camera device platform data to point to struct soc_camera_link
for a smooth transition to soc-camera as a platform driver.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
---
 arch/sh/boards/board-ap325rxa.c   | 2 +-
 arch/sh/boards/mach-migor/setup.c | 4 ++--
 drivers/media/video/ov772x.c      | 6 ++++--
 drivers/media/video/tw9910.c      | 6 ++++--
 4 files changed, 11 insertions(+), 7 deletions(-)

(limited to 'drivers/media/video')

diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 1c4d83ef2a4..8cc46874ade 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -417,7 +417,7 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
 	},
 	{
 		I2C_BOARD_INFO("ov772x", 0x21),
-		.platform_data = &ov7725_info,
+		.platform_data = &ov7725_info.link,
 	},
 };
 
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 6ed401cd315..95d90213be0 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -430,11 +430,11 @@ static struct i2c_board_info migor_i2c_devices[] = {
 	},
 	{
 		I2C_BOARD_INFO("ov772x", 0x21),
-		.platform_data = &ov7725_info,
+		.platform_data = &ov7725_info.link,
 	},
 	{
 		I2C_BOARD_INFO("tw9910", 0x45),
-		.platform_data = &tw9910_info,
+		.platform_data = &tw9910_info.link,
 	},
 };
 
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index c0d91125286..0bce255168b 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -1067,10 +1067,12 @@ static int ov772x_probe(struct i2c_client *client,
 	struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
 	int                        ret;
 
-	info = client->dev.platform_data;
-	if (!info)
+	if (!client->dev.platform_data)
 		return -EINVAL;
 
+	info = container_of(client->dev.platform_data,
+			    struct ov772x_camera_info, link);
+
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&adapter->dev,
 			"I2C-Adapter doesn't support "
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index a3994764399..aa5065ea09e 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -875,10 +875,12 @@ static int tw9910_probe(struct i2c_client *client,
 	const struct tw9910_scale_ctrl *scale;
 	int                             i, ret;
 
-	info = client->dev.platform_data;
-	if (!info)
+	if (!client->dev.platform_data)
 		return -EINVAL;
 
+	info = container_of(client->dev.platform_data,
+			    struct tw9910_video_info, link);
+
 	if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent),
 				     I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&client->dev,
-- 
cgit v1.2.3-70-g09d2


From 14422f9dd8515bfbe6fdbde37eadf59e2980f104 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Tue, 16 Jun 2009 23:55:44 -0300
Subject: V4L/DVB (12010): cx88: Properly support Leadtek TV2000 XP Global

Fix Leadtek TV2000 XP Global entries and add missing PCI ID's.

Thanks to Terry Wu <terrywu2009@gmail.com> for pointing us for the proper settings.

Cc: Terry Wu <terrywu2009@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.cx88 |  6 +--
 drivers/media/video/cx88/cx88-cards.c   | 94 ++++++++++++++++++++++++++-------
 2 files changed, 78 insertions(+), 22 deletions(-)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 89093f53172..0736518b2f8 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -6,8 +6,8 @@
   5 -> Leadtek Winfast 2000XP Expert                       [107d:6611,107d:6613]
   6 -> AverTV Studio 303 (M126)                            [1461:000b]
   7 -> MSI TV-@nywhere Master                              [1462:8606]
-  8 -> Leadtek Winfast DV2000                              [107d:6620]
-  9 -> Leadtek PVR 2000                                    [107d:663b,107d:663c,107d:6632]
+  8 -> Leadtek Winfast DV2000                              [107d:6620,107d:6621]
+  9 -> Leadtek PVR 2000                                    [107d:663b,107d:663c,107d:6632,107d:6630,107d:6638,107d:6631,107d:6637,107d:663d]
  10 -> IODATA GV-VCP3/PCI                                  [10fc:d003]
  11 -> Prolink PlayTV PVR
  12 -> ASUS PVR-416                                        [1043:4823,1461:c111]
@@ -59,7 +59,7 @@
  58 -> Pinnacle PCTV HD 800i                               [11bd:0051]
  59 -> DViCO FusionHDTV 5 PCI nano                         [18ac:d530]
  60 -> Pinnacle Hybrid PCTV                                [12ab:1788]
- 61 -> Winfast TV2000 XP Global                            [107d:6f18]
+ 61 -> Leadtek TV2000 XP Global                            [107d:6f18,107d:6618]
  62 -> PowerColor RA330                                    [14f1:ea3d]
  63 -> Geniatech X8000-MT DVBT                             [14f1:8852]
  64 -> DViCO FusionHDTV DVB-T PRO                          [18ac:db30]
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 94b7a52629d..a5cc1c1fc2d 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1524,33 +1524,45 @@ static const struct cx88_board cx88_boards[] = {
 		},
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	/* Terry Wu <terrywu2009@gmail.com> */
+	/* TV Audio :      set GPIO 2, 18, 19 value to 0, 1, 0 */
+	/* FM Audio :      set GPIO 2, 18, 19 value to 0, 0, 0 */
+	/* Line-in Audio : set GPIO 2, 18, 19 value to 0, 1, 1 */
+	/* Mute Audio :    set GPIO 2 value to 1               */
 	[CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
-		.name           = "Winfast TV2000 XP Global",
+		.name           = "Leadtek TV2000 XP Global",
 		.tuner_type     = TUNER_XC2028,
 		.tuner_addr     = 0x61,
+		.radio_type     = TUNER_XC2028,
+		.radio_addr     = 0x61,
 		.input          = { {
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
-			.gpio0  = 0x0400, /* pin 2:mute = 0 (off?) */
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
 			.gpio1  = 0x0000,
-			.gpio2  = 0x0800, /* pin 19:audio = 0 (tv) */
-
+			.gpio2  = 0x0C04,       /* pin 18 = 1, pin 19 = 0 */
+			.gpio3  = 0x0000,
 		}, {
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
-			.gpio0  = 0x0400, /* probably?  or 0x0404 to turn mute on */
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
 			.gpio1  = 0x0000,
-			.gpio2  = 0x0808, /* pin 19:audio = 1 (line) */
-
+			.gpio2  = 0x0C0C,       /* pin 18 = 1, pin 19 = 1 */
+			.gpio3  = 0x0000,
 		}, {
 			.type   = CX88_VMUX_SVIDEO,
 			.vmux   = 2,
+			.gpio0  = 0x0400,       /* pin 2 = 0 */
+			.gpio1  = 0x0000,
+			.gpio2  = 0x0C0C,       /* pin 18 = 1, pin 19 = 1 */
+			.gpio3  = 0x0000,
 		} },
 		.radio = {
 			.type   = CX88_RADIO,
-			.gpio0  = 0x004ff,
-			.gpio1  = 0x010ff,
-			.gpio2  = 0x0ff,
+			.gpio0  = 0x0400,        /* pin 2 = 0 */
+			.gpio1  = 0x0000,
+			.gpio2  = 0x0C00,       /* pin 18 = 0, pin 19 = 0 */
+			.gpio3  = 0x0000,
 		},
 	},
 	[CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
@@ -2438,6 +2450,41 @@ static const struct cx88_subid cx88_subids[] = {
 		.subvendor = 0x107d,
 		.subdevice = 0x6654,
 		.card      = CX88_BOARD_WINFAST_DTV1800H,
+	}, {
+		/* PVR2000 PAL Model [107d:6630] */
+		.subvendor = 0x107d,
+		.subdevice = 0x6630,
+		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	}, {
+		/* PVR2000 PAL Model [107d:6638] */
+		.subvendor = 0x107d,
+		.subdevice = 0x6638,
+		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	}, {
+		/* PVR2000 NTSC Model [107d:6631] */
+		.subvendor = 0x107d,
+		.subdevice = 0x6631,
+		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	}, {
+		/* PVR2000 NTSC Model [107d:6637] */
+		.subvendor = 0x107d,
+		.subdevice = 0x6637,
+		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	}, {
+		/* PVR2000 NTSC Model [107d:663d] */
+		.subvendor = 0x107d,
+		.subdevice = 0x663d,
+		.card      = CX88_BOARD_LEADTEK_PVR2000,
+	}, {
+		/* DV2000 NTSC Model [107d:6621] */
+		.subvendor = 0x107d,
+		.subdevice = 0x6621,
+		.card      = CX88_BOARD_WINFAST_DV2000,
+	}, {
+		/* TV2000 XP Global [107d:6618]  */
+		.subvendor = 0x107d,
+		.subdevice = 0x6618,
+		.card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
 	},
 };
 
@@ -2446,12 +2493,6 @@ static const struct cx88_subid cx88_subids[] = {
 
 static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
 {
-	/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
-	 * any others.
-	 *
-	 * Byte 0 is 1 on the NTSC board.
-	 */
-
 	if (eeprom_data[4] != 0x7d ||
 	    eeprom_data[5] != 0x10 ||
 	    eeprom_data[7] != 0x66) {
@@ -2459,8 +2500,19 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
 		return;
 	}
 
-	core->board.tuner_type = (eeprom_data[6] == 0x13) ?
-		TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
+	/* Terry Wu <terrywu2009@gmail.com> */
+	switch (eeprom_data[6]) {
+	case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */
+	case 0x21: /* SSID 6621 for DV2000 NTSC Model */
+	case 0x31: /* SSID 6631 for PVR2000 NTSC Model */
+	case 0x37: /* SSID 6637 for PVR2000 NTSC Model */
+	case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */
+		core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3;
+		break;
+	default:
+		core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+		break;
+	}
 
 	info_printk(core, "Leadtek Winfast 2000XP Expert config: "
 		    "tuner=%d, eeprom[0]=0x%02x\n",
@@ -2713,7 +2765,6 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
 {
 	/* Board-specific callbacks */
 	switch (core->boardnr) {
-	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 	case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
 	case CX88_BOARD_GENIATECH_X8000_MT:
 	case CX88_BOARD_KWORLD_ATSC_120:
@@ -2725,6 +2776,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		return cx88_dvico_xc2028_callback(core, command, arg);
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 	case CX88_BOARD_WINFAST_DTV1800H:
 		return cx88_xc3028_winfast1800h_callback(core, command, arg);
 	}
@@ -2914,6 +2966,7 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
 		udelay(1000);
 		break;
 
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 	case CX88_BOARD_WINFAST_DTV1800H:
 		/* GPIO 12 (xc3028 tuner reset) */
 		cx_set(MO_GP1_IO, 0x1010);
@@ -2950,6 +3003,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		ctl->demod = XC3028_FE_OREN538;
 		break;
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
 	case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
 	case CX88_BOARD_PROLINK_PV_8000GT:
 		/*
@@ -2993,6 +3047,8 @@ static void cx88_card_setup(struct cx88_core *core)
 		if (0 == core->i2c_rc)
 			gdi_eeprom(core, eeprom);
 		break;
+	case CX88_BOARD_LEADTEK_PVR2000:
+	case CX88_BOARD_WINFAST_DV2000:
 	case CX88_BOARD_WINFAST2000XP_EXPERT:
 		if (0 == core->i2c_rc)
 			leadtek_eeprom(core, eeprom);
-- 
cgit v1.2.3-70-g09d2


From b8bfb5fb348d939a96fc8f71996a2e5e48b4544b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sat, 13 Jun 2009 18:56:22 -0300
Subject: V4L/DVB (12071): gspca: fix NULL pointer deref in query_ctrl

gspca: fix NULL pointer deref in query_ctrl

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/gspca.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f7e0355ad64..1e89600986c 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1042,13 +1042,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 		for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
 			if (gspca_dev->ctrl_dis & (1 << i))
 				continue;
-			if (ctrls->qctrl.id < id)
+			if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
 				continue;
-			if (ctrls != NULL) {
-				if (gspca_dev->sd_desc->ctrls[i].qctrl.id
+			if (ctrls && gspca_dev->sd_desc->ctrls[i].qctrl.id
 					    > ctrls->qctrl.id)
-					continue;
-			}
+				continue;
 			ctrls = &gspca_dev->sd_desc->ctrls[i];
 		}
 	} else {
-- 
cgit v1.2.3-70-g09d2


From 02ab18b0f497bed623814677577b76cc97234085 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 04:32:04 -0300
Subject: V4L/DVB (12072): gspca-ov519: add extra controls

This patch adds autobrightness (so that it can
be turned off to make the already present brightness
control work) and light frequency filtering controls.

The lightfreq control needed 2 different entries
in the ctrls array, as the number of options differs
depending on the sensor. Always one of the 2 entires is
disabled ofcourse.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 214 ++++++++++++++++++++++++++++++++++++--
 include/linux/videodev2.h         |   3 +-
 2 files changed, 207 insertions(+), 10 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 188866ac6ce..baa488dd33d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -65,6 +65,8 @@ struct sd {
 	__u8 colors;
 	__u8 hflip;
 	__u8 vflip;
+	__u8 autobrightness;
+	__u8 freq;
 
 	__u8 stopped;		/* Streaming is temporarily paused */
 
@@ -94,11 +96,17 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautobrightness(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 void setbrightness(struct gspca_dev *gspca_dev);
 static void setcontrast(struct gspca_dev *gspca_dev);
 static void setcolors(struct gspca_dev *gspca_dev);
+static void setautobrightness(struct sd *sd);
+static void setfreq(struct sd *sd);
 
-static struct ctrl sd_ctrls[] = {
+static const struct ctrl sd_ctrls[] = {
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -141,7 +149,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setcolors,
 	    .get = sd_getcolors,
 	},
-/* next controls work with ov7670 only */
+/* The flip controls work with ov7670 only */
 #define HFLIP_IDX 3
 	{
 	    {
@@ -172,6 +180,51 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setvflip,
 	    .get = sd_getvflip,
 	},
+#define AUTOBRIGHT_IDX 5
+	{
+	    {
+		.id      = V4L2_CID_AUTOBRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Auto Brightness",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AUTOBRIGHT_DEF 1
+		.default_value = AUTOBRIGHT_DEF,
+	    },
+	    .set = sd_setautobrightness,
+	    .get = sd_getautobrightness,
+	},
+#define FREQ_IDX 6
+	{
+	    {
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+		.step    = 1,
+#define FREQ_DEF 0
+		.default_value = FREQ_DEF,
+	    },
+	    .set = sd_setfreq,
+	    .get = sd_getfreq,
+	},
+#define OV7670_FREQ_IDX 7
+	{
+	    {
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 3,	/* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */
+		.step    = 1,
+#define OV7670_FREQ_DEF 3
+		.default_value = OV7670_FREQ_DEF,
+	    },
+	    .set = sd_setfreq,
+	    .get = sd_getfreq,
+	},
 };
 
 static const struct v4l2_pix_format ov519_vga_mode[] = {
@@ -416,7 +469,7 @@ static const struct ov_i2c_regvals norm_6x30[] = {
 	{ 0x07, 0x2d }, /* Sharpness */
 	{ 0x0c, 0x20 },
 	{ 0x0d, 0x20 },
-	{ 0x0e, 0x20 },
+	{ 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
 	{ 0x0f, 0x05 },
 	{ 0x10, 0x9a },
 	{ 0x11, 0x00 }, /* Pixel clock = fastest */
@@ -1659,9 +1712,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->colors = COLOR_DEF;
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
-	if (sd->sensor != SEN_OV7670)
-		gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
-					| (1 << VFLIP_IDX);
+	sd->autobrightness = AUTOBRIGHT_DEF;
+	if (sd->sensor == SEN_OV7670) {
+		sd->freq = OV7670_FREQ_DEF;
+		gspca_dev->ctrl_dis = 1 << FREQ_IDX;
+	} else {
+		sd->freq = FREQ_DEF;
+		gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
+				      (1 << OV7670_FREQ_IDX);
+	}
+	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
+		gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
+	/* OV8610 Frequency filter control should work but needs testing */
+	if (sd->sensor == SEN_OV8610)
+		gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
+
 	return 0;
 error:
 	PDEBUG(D_ERR, "OV519 Config failed");
@@ -2233,7 +2298,6 @@ static int set_ov_sensor_window(struct sd *sd)
 		msleep(10);	/* need to sleep between read and write to
 				 * same reg! */
 		i2c_w(sd, OV7670_REG_VREF, v);
-		sethvflip(sd);
 	} else {
 		i2c_w(sd, 0x17, hwsbase);
 		i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
@@ -2268,6 +2332,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	setcontrast(gspca_dev);
 	setbrightness(gspca_dev);
 	setcolors(gspca_dev);
+	sethvflip(sd);
+	setautobrightness(sd);
+	setfreq(sd);
 
 	ret = ov51x_restart(sd);
 	if (ret < 0)
@@ -2394,8 +2461,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 		break;
 	case SEN_OV7620:
 		/* 7620 doesn't like manual changes when in auto mode */
-/*fixme
- *		if (!sd->auto_brt) */
+		if (!sd->autobrightness)
 			i2c_w(sd, OV7610_REG_BRT, val);
 		break;
 	case SEN_OV7670:
@@ -2482,6 +2548,70 @@ static void setcolors(struct gspca_dev *gspca_dev)
 	}
 }
 
+static void setautobrightness(struct sd *sd)
+{
+	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
+		return;
+
+	i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
+}
+
+static void setfreq(struct sd *sd)
+{
+	if (sd->sensor == SEN_OV7670) {
+		switch (sd->freq) {
+		case 0: /* Banding filter disabled */
+			i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
+			break;
+		case 1: /* 50 hz */
+			i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+				   OV7670_COM8_BFILT);
+			i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
+			break;
+		case 2: /* 60 hz */
+			i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+				   OV7670_COM8_BFILT);
+			i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
+			break;
+		case 3: /* Auto hz */
+			i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+				   OV7670_COM8_BFILT);
+			i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
+				   0x18);
+			break;
+		}
+	} else {
+		switch (sd->freq) {
+		case 0: /* Banding filter disabled */
+			i2c_w_mask(sd, 0x2d, 0x00, 0x04);
+			i2c_w_mask(sd, 0x2a, 0x00, 0x80);
+			break;
+		case 1: /* 50 hz (filter on and framerate adj) */
+			i2c_w_mask(sd, 0x2d, 0x04, 0x04);
+			i2c_w_mask(sd, 0x2a, 0x80, 0x80);
+			/* 20 fps -> 16.667 fps */
+			if (sd->sensor == SEN_OV6620 ||
+			    sd->sensor == SEN_OV6630)
+				i2c_w(sd, 0x2b, 0x5e);
+			else
+				i2c_w(sd, 0x2b, 0xac);
+			break;
+		case 2: /* 60 hz (filter on, ...) */
+			i2c_w_mask(sd, 0x2d, 0x04, 0x04);
+			if (sd->sensor == SEN_OV6620 ||
+			    sd->sensor == SEN_OV6630) {
+				/* 20 fps -> 15 fps */
+				i2c_w_mask(sd, 0x2a, 0x80, 0x80);
+				i2c_w(sd, 0x2b, 0xa8);
+			} else {
+				/* no framerate adj. */
+				i2c_w_mask(sd, 0x2a, 0x00, 0x80);
+			}
+			break;
+		}
+	}
+}
+
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2572,6 +2702,71 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
+static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autobrightness = val;
+	if (gspca_dev->streaming)
+		setautobrightness(sd);
+	return 0;
+}
+
+static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autobrightness;
+	return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->freq = val;
+	if (gspca_dev->streaming)
+		setfreq(sd);
+	return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->freq;
+	return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		case 3:
+			if (sd->sensor != SEN_OV7670)
+				return -EINVAL;
+
+			strcpy((char *) menu->name, "Automatic");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -2582,6 +2777,7 @@ static const struct sd_desc sd_desc = {
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.pkt_scan = sd_pkt_scan,
+	.querymenu = sd_querymenu,
 };
 
 /* -- module initialisation -- */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index f24eceecc5a..772d226cb5c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -894,9 +894,10 @@ enum v4l2_colorfx {
 	V4L2_COLORFX_BW		= 1,
 	V4L2_COLORFX_SEPIA	= 2,
 };
+#define V4L2_CID_AUTOBRIGHTNESS			(V4L2_CID_BASE+32)
 
 /* last CID + 1 */
-#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+32)
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+33)
 
 /*  MPEG-class control IDs defined by V4L2 */
 #define V4L2_CID_MPEG_BASE 			(V4L2_CTRL_CLASS_MPEG | 0x900)
-- 
cgit v1.2.3-70-g09d2


From 7d9713735d7537baf2b00be806a8de08a5c9f11b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 05:28:17 -0300
Subject: V4L/DVB (12073): gspca_ov519: limit ov6630 qvif uv swap fix to
 ov66308AF

The fix for the UV swapping in qcif mode with the ov6630, which I did
to fix this issue on a ov518 cam with an ov66308AF, causes UV swapping in
qcif with another cam of mine with the ov518 and an ov66308AE, so this
patch changes the code to differentiate between the ov66308AF and other
ov6630 versions, and restricts the UV swap fix to the ov66308AF.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index baa488dd33d..2d5d95f0277 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -77,12 +77,13 @@ struct sd {
 #define SEN_UNKNOWN 0
 #define SEN_OV6620 1
 #define SEN_OV6630 2
-#define SEN_OV7610 3
-#define SEN_OV7620 4
-#define SEN_OV7640 5
-#define SEN_OV7670 6
-#define SEN_OV76BE 7
-#define SEN_OV8610 8
+#define SEN_OV66308AF 3
+#define SEN_OV7610 4
+#define SEN_OV7620 5
+#define SEN_OV7640 6
+#define SEN_OV7670 7
+#define SEN_OV76BE 8
+#define SEN_OV8610 9
 };
 
 /* V4L2 controls supported by the driver */
@@ -1415,13 +1416,14 @@ static int ov6xx0_configure(struct sd *sd)
 		break;
 	case 0x01:
 		sd->sensor = SEN_OV6620;
+		PDEBUG(D_PROBE, "Sensor is an OV6620");
 		break;
 	case 0x02:
 		sd->sensor = SEN_OV6630;
 		PDEBUG(D_PROBE, "Sensor is an OV66308AE");
 		break;
 	case 0x03:
-		sd->sensor = SEN_OV6630;
+		sd->sensor = SEN_OV66308AF;
 		PDEBUG(D_PROBE, "Sensor is an OV66308AF");
 		break;
 	case 0x90:
@@ -1745,6 +1747,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			return -EIO;
 		break;
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
 			return -EIO;
 		break;
@@ -2081,6 +2084,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 		break;
 	case SEN_OV6620:
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		break;
 	default:
@@ -2101,7 +2105,8 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 
 	/* OV7640 is 8-bit only */
 
-	if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
+	if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
+					sd->sensor != SEN_OV7640)
 		i2c_w_mask(sd, 0x13, 0x00, 0x20);
 
 	/******** Clock programming ********/
@@ -2188,15 +2193,14 @@ static int set_ov_sensor_window(struct sd *sd)
 		break;
 	case SEN_OV6620:
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		hwsbase = 0x38;
 		hwebase = 0x3a;
 		vwsbase = 0x05;
 		vwebase = 0x06;
-		if (qvga) {
+		if (sd->sensor == SEN_OV66308AF && qvga)
 			/* HDG: this fixes U and V getting swapped */
-			hwsbase--;
-			vwsbase--;
-		}
+			hwsbase++;
 		break;
 	case SEN_OV7620:
 		hwsbase = 0x2f;		/* From 7620.SET (spec is wrong) */
@@ -2220,6 +2224,7 @@ static int set_ov_sensor_window(struct sd *sd)
 	switch (sd->sensor) {
 	case SEN_OV6620:
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		if (qvga) {		/* QCIF */
 			hwscale = 0;
 			vwscale = 0;
@@ -2456,6 +2461,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 	case SEN_OV76BE:
 	case SEN_OV6620:
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 	case SEN_OV7640:
 		i2c_w(sd, OV7610_REG_BRT, val);
 		break;
@@ -2484,6 +2490,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 		i2c_w(sd, OV7610_REG_CNT, val);
 		break;
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
 		break;
 	case SEN_OV8610: {
@@ -2528,6 +2535,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
 	case SEN_OV76BE:
 	case SEN_OV6620:
 	case SEN_OV6630:
+	case SEN_OV66308AF:
 		i2c_w(sd, OV7610_REG_SAT, val);
 		break;
 	case SEN_OV7620:
@@ -2591,7 +2599,8 @@ static void setfreq(struct sd *sd)
 			i2c_w_mask(sd, 0x2a, 0x80, 0x80);
 			/* 20 fps -> 16.667 fps */
 			if (sd->sensor == SEN_OV6620 ||
-			    sd->sensor == SEN_OV6630)
+			    sd->sensor == SEN_OV6630 ||
+			    sd->sensor == SEN_OV66308AF)
 				i2c_w(sd, 0x2b, 0x5e);
 			else
 				i2c_w(sd, 0x2b, 0xac);
@@ -2599,7 +2608,8 @@ static void setfreq(struct sd *sd)
 		case 2: /* 60 hz (filter on, ...) */
 			i2c_w_mask(sd, 0x2d, 0x04, 0x04);
 			if (sd->sensor == SEN_OV6620 ||
-			    sd->sensor == SEN_OV6630) {
+			    sd->sensor == SEN_OV6630 ||
+			    sd->sensor == SEN_OV66308AF) {
 				/* 20 fps -> 15 fps */
 				i2c_w_mask(sd, 0x2a, 0x80, 0x80);
 				i2c_w(sd, 0x2b, 0xa8);
-- 
cgit v1.2.3-70-g09d2


From 124cc9c0c8acc77ac2f1114ee7eea961334020ba Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 05:48:00 -0300
Subject: V4L/DVB (12074): gspca_ov519: Add 320x240 and 160x120 support for cif
 sensor cams

gspca_ov519: Add 320x240 and 160x120 support for cif sensor cams

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 2d5d95f0277..55db32c95be 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -241,11 +241,21 @@ static const struct v4l2_pix_format ov519_vga_mode[] = {
 		.priv = 0},
 };
 static const struct v4l2_pix_format ov519_sif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 3},
 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 176,
 		.sizeimage = 176 * 144 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 2},
 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 352,
 		.sizeimage = 352 * 288 * 3 / 8 + 590,
@@ -266,11 +276,21 @@ static const struct v4l2_pix_format ov518_vga_mode[] = {
 		.priv = 0},
 };
 static const struct v4l2_pix_format ov518_sif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 40000,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 3},
 	{176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 176,
 		.sizeimage = 40000,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 2},
 	{352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 352,
 		.sizeimage = 352 * 288 * 3 / 8 + 590,
@@ -2039,7 +2059,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 	int qvga;
 
 	gspca_dev = &sd->gspca_dev;
-	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
 
 	/******** Mode (VGA/QVGA) and sensor specific regs ********/
 	switch (sd->sensor) {
@@ -2168,13 +2188,14 @@ static void sethvflip(struct sd *sd)
 static int set_ov_sensor_window(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev;
-	int qvga;
+	int qvga, crop;
 	int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
 	int ret, hstart, hstop, vstop, vstart;
 	__u8 v;
 
 	gspca_dev = &sd->gspca_dev;
-	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
+	crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
 
 	/* The different sensor ICs handle setting up of window differently.
 	 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
@@ -2201,6 +2222,12 @@ static int set_ov_sensor_window(struct sd *sd)
 		if (sd->sensor == SEN_OV66308AF && qvga)
 			/* HDG: this fixes U and V getting swapped */
 			hwsbase++;
+		if (crop) {
+			hwsbase += 8;
+			hwebase += 8;
+			vwsbase += 11;
+			vwebase += 11;
+		}
 		break;
 	case SEN_OV7620:
 		hwsbase = 0x2f;		/* From 7620.SET (spec is wrong) */
-- 
cgit v1.2.3-70-g09d2


From 92918a53ee74bb326430aaa958caa0cf111b54b1 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 06:21:35 -0300
Subject: V4L/DVB (12075): gspca_ov519: check ov518 packet numbers

Check ov518 packet numbers to detect dropped packets.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 55db32c95be..c2982137dc2 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -50,6 +50,8 @@ static int i2c_detect_tries = 10;
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
+	__u8 packet_nr;
+
 	char bridge;
 #define BRIDGE_OV511		0
 #define BRIDGE_OV511PLUS	1
@@ -2391,18 +2393,33 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
-	PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len);
-
-	if (len & 7) {
-		len--;
-		PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]);
-	}
+	struct sd *sd = (struct sd *) gspca_dev;
 
 	/* A false positive here is likely, until OVT gives me
 	 * the definitive SOF/EOF format */
 	if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
 		gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
 		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		sd->packet_nr = 0;
+	}
+
+	if (gspca_dev->last_packet_type == DISCARD_PACKET)
+		return;
+
+	/* Does this device use packet numbers ? */
+	if (len & 7) {
+		len--;
+		if (sd->packet_nr == data[len])
+			sd->packet_nr++;
+		/* The last few packets of the frame (which are all 0's
+		   except that they may contain part of the footer), are
+		   numbered 0 */
+		else if (sd->packet_nr == 0 || data[len]) {
+			PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
+				(int)data[len], (int)sd->packet_nr);
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
 	}
 
 	/* intermediate packet */
-- 
cgit v1.2.3-70-g09d2


From 9e4d82588174e68abe8e3568202f0b530415661f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 06:25:06 -0300
Subject: V4L/DVB (12076): gspca_ov519: Fix led inversion with some cams

My ov519 cam has it led inverted, the same has been
reported on the ov51x-jpeg list for another
creative cam. This patch fixes this without changing
the behaviour for other cams.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index c2982137dc2..c2c087222f1 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -58,6 +58,10 @@ struct sd {
 #define BRIDGE_OV518		2
 #define BRIDGE_OV518PLUS	3
 #define BRIDGE_OV519		4
+#define BRIDGE_MASK		7
+
+	char invert_led;
+#define BRIDGE_INVERT_LED	8
 
 	/* Determined by sensor type */
 	__u8 sif;
@@ -1468,6 +1472,9 @@ static int ov6xx0_configure(struct sd *sd)
 /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
 static void ov51x_led_control(struct sd *sd, int on)
 {
+	if (sd->invert_led)
+		on = !on;
+
 	switch (sd->bridge) {
 	/* OV511 has no LED control */
 	case BRIDGE_OV511PLUS:
@@ -1650,7 +1657,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct cam *cam;
 	int ret = 0;
 
-	sd->bridge = id->driver_info;
+	sd->bridge = id->driver_info & BRIDGE_MASK;
+	sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
 
 	switch (sd->bridge) {
 	case BRIDGE_OV518:
@@ -2840,8 +2848,10 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
-	{USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
-	{USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x041e, 0x4064),
+	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+	{USB_DEVICE(0x041e, 0x4068),
+	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
 	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
-- 
cgit v1.2.3-70-g09d2


From 80142efa715581c06d01b37f299a240309699ff4 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 06:26:49 -0300
Subject: V4L/DVB (12077): gspca_ov519: Fix 320x240 with ov7660 sensor

As reported on the ov51x-jpeg list, and as I can confirm with my own cam
the ov7670 in 320x240 has a number of broken columns of pixels
at the left of the picture. This was not present in the old
driver as it always used 640x480 and did software
downscaling (took me a while to figure that one out).
The fix adds a sensor specific if in so far sensor
neutral code :( But this is the only way to fix this,
this cannot be fixed by only changing sensor registers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index c2c087222f1..c7e88cb0095 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1977,7 +1977,11 @@ static int ov519_mode_init_regs(struct sd *sd)
 
 	reg_w(sd, OV519_R10_H_SIZE,	sd->gspca_dev.width >> 4);
 	reg_w(sd, OV519_R11_V_SIZE,	sd->gspca_dev.height >> 3);
-	reg_w(sd, OV519_R12_X_OFFSETL,	0x00);
+	if (sd->sensor == SEN_OV7670 &&
+	    sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
+		reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
+	else
+		reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
 	reg_w(sd, OV519_R13_X_OFFSETH,	0x00);
 	reg_w(sd, OV519_R14_Y_OFFSETL,	0x00);
 	reg_w(sd, OV519_R15_Y_OFFSETH,	0x00);
@@ -2314,7 +2318,7 @@ static int set_ov_sensor_window(struct sd *sd)
 		if (qvga) {		/* QVGA from ov7670.c by
 					 * Jonathan Corbet */
 			hstart = 164;
-			hstop = 20;
+			hstop = 28;
 			vstart = 14;
 			vstop = 494;
 		} else {		/* VGA */
-- 
cgit v1.2.3-70-g09d2


From f5cee95c2e4c56b50cdb8edd33cf04902946cd25 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 06:32:52 -0300
Subject: V4L/DVB (12078): gspca_ov519: Better default contrast for ov6630

Hmm, another one with an extra if (life sucks) the
default contrast really is no good for the ov6630, it
isn't even high enough in full daylight, this gives
the ov6630 a different initial value for a better out
of the box experience.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index c7e88cb0095..9d4b69dbf96 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1740,7 +1740,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		break;
 	}
 	sd->brightness = BRIGHTNESS_DEF;
-	sd->contrast = CONTRAST_DEF;
+	if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
+		sd->contrast = 200; /* The default is too low for the ov6630 */
+	else
+		sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
-- 
cgit v1.2.3-70-g09d2


From 1876bb923c98c605eca69f0bfe295f7b5f5eba28 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 06:45:50 -0300
Subject: V4L/DVB (12079): gspca_ov519: add support for the ov511 bridge

gspca_ov519: add support for the ov511 bridge

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 533 +++++++++++++++++++++++++++++++++++++-
 include/linux/videodev2.h         |   1 +
 2 files changed, 521 insertions(+), 13 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 9d4b69dbf96..1f8e2613ecc 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -76,8 +76,8 @@ struct sd {
 
 	__u8 stopped;		/* Streaming is temporarily paused */
 
-	__u8 frame_rate;	/* current Framerate (OV519 only) */
-	__u8 clockdiv;		/* clockdiv override for OV519 only */
+	__u8 frame_rate;	/* current Framerate */
+	__u8 clockdiv;		/* clockdiv override */
 
 	char sensor;		/* Type of image sensor chip (SEN_*) */
 #define SEN_UNKNOWN 0
@@ -304,17 +304,77 @@ static const struct v4l2_pix_format ov518_sif_mode[] = {
 		.priv = 0},
 };
 
+static const struct v4l2_pix_format ov511_vga_mode[] = {
+	{320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 1},
+	{640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ov511_sif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 40000,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 3},
+	{176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 40000,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 3,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 2},
+	{352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288 * 3,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
 
 /* Registers common to OV511 / OV518 */
+#define R51x_FIFO_PSIZE			0x30	/* 2 bytes wide w/ OV518(+) */
 #define R51x_SYS_RESET          	0x50
+	/* Reset type flags */
+	#define	OV511_RESET_OMNICE	0x08
 #define R51x_SYS_INIT         		0x53
 #define R51x_SYS_SNAP			0x52
 #define R51x_SYS_CUST_ID		0x5F
 #define R51x_COMP_LUT_BEGIN		0x80
 
 /* OV511 Camera interface register numbers */
+#define R511_CAM_DELAY			0x10
+#define R511_CAM_EDGE			0x11
+#define R511_CAM_PXCNT			0x12
+#define R511_CAM_LNCNT			0x13
+#define R511_CAM_PXDIV			0x14
+#define R511_CAM_LNDIV			0x15
+#define R511_CAM_UV_EN			0x16
+#define R511_CAM_LINE_MODE		0x17
+#define R511_CAM_OPTS			0x18
+
+#define R511_SNAP_FRAME			0x19
+#define R511_SNAP_PXCNT			0x1A
+#define R511_SNAP_LNCNT			0x1B
+#define R511_SNAP_PXDIV			0x1C
+#define R511_SNAP_LNDIV			0x1D
+#define R511_SNAP_UV_EN			0x1E
+#define R511_SNAP_UV_EN			0x1E
+#define R511_SNAP_OPTS			0x1F
+
+#define R511_DRAM_FLOW_CTL		0x20
+#define R511_FIFO_OPTS			0x31
+#define R511_I2C_CTL			0x40
 #define R511_SYS_LED_CTL		0x55	/* OV511+ only */
-#define	OV511_RESET_NOREGS		0x3F	/* All but OV511 & regs */
+#define R511_COMP_EN			0x78
+#define R511_COMP_LUT_EN		0x79
 
 /* OV518 Camera interface register numbers */
 #define R518_GPIO_OUT			0x56	/* OV518(+) only */
@@ -1079,13 +1139,128 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
 	return ret;
 }
 
+static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+{
+	int rc, retries;
+
+	PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+
+	/* Three byte write cycle */
+	for (retries = 6; ; ) {
+		/* Select camera register */
+		rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
+		if (rc < 0)
+			return rc;
+
+		/* Write "value" to I2C data port of OV511 */
+		rc = reg_w(sd, R51x_I2C_DATA, value);
+		if (rc < 0)
+			return rc;
+
+		/* Initiate 3-byte write cycle */
+		rc = reg_w(sd, R511_I2C_CTL, 0x01);
+		if (rc < 0)
+			return rc;
+
+		do
+			rc = reg_r(sd, R511_I2C_CTL);
+		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+
+		if (rc < 0)
+			return rc;
+
+		if ((rc & 2) == 0) /* Ack? */
+			break;
+		if (--retries < 0) {
+			PDEBUG(D_USBO, "i2c write retries exhausted");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int ov511_i2c_r(struct sd *sd, __u8 reg)
+{
+	int rc, value, retries;
+
+	/* Two byte write cycle */
+	for (retries = 6; ; ) {
+		/* Select camera register */
+		rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
+		if (rc < 0)
+			return rc;
+
+		/* Initiate 2-byte write cycle */
+		rc = reg_w(sd, R511_I2C_CTL, 0x03);
+		if (rc < 0)
+			return rc;
+
+		do
+			rc = reg_r(sd, R511_I2C_CTL);
+		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+
+		if (rc < 0)
+			return rc;
+
+		if ((rc & 2) == 0) /* Ack? */
+			break;
+
+		/* I2C abort */
+		reg_w(sd, R511_I2C_CTL, 0x10);
+
+		if (--retries < 0) {
+			PDEBUG(D_USBI, "i2c write retries exhausted");
+			return -1;
+		}
+	}
+
+	/* Two byte read cycle */
+	for (retries = 6; ; ) {
+		/* Initiate 2-byte read cycle */
+		rc = reg_w(sd, R511_I2C_CTL, 0x05);
+		if (rc < 0)
+			return rc;
+
+		do
+			rc = reg_r(sd, R511_I2C_CTL);
+		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+
+		if (rc < 0)
+			return rc;
+
+		if ((rc & 2) == 0) /* Ack? */
+			break;
+
+		/* I2C abort */
+		rc = reg_w(sd, R511_I2C_CTL, 0x10);
+		if (rc < 0)
+			return rc;
+
+		if (--retries < 0) {
+			PDEBUG(D_USBI, "i2c read retries exhausted");
+			return -1;
+		}
+	}
+
+	value = reg_r(sd, R51x_I2C_DATA);
+
+	PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+
+	/* This is needed to make i2c_w() work */
+	rc = reg_w(sd, R511_I2C_CTL, 0x05);
+	if (rc < 0)
+		return rc;
+
+	return value;
+}
 
 /*
  * The OV518 I2C I/O procedure is different, hence, this function.
  * This is normally only called from i2c_w(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
-static int i2c_w(struct sd *sd,
+static int ov518_i2c_w(struct sd *sd,
 		__u8 reg,
 		__u8 value)
 {
@@ -1120,7 +1295,7 @@ static int i2c_w(struct sd *sd,
  * This is normally only called from i2c_r(). Note that this function
  * always succeeds regardless of whether the sensor is present and working.
  */
-static int i2c_r(struct sd *sd, __u8 reg)
+static int ov518_i2c_r(struct sd *sd, __u8 reg)
 {
 	int rc, value;
 
@@ -1143,6 +1318,34 @@ static int i2c_r(struct sd *sd, __u8 reg)
 	return value;
 }
 
+static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
+{
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		return ov511_i2c_w(sd, reg, value);
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+	case BRIDGE_OV519:
+		return ov518_i2c_w(sd, reg, value);
+	}
+	return -1; /* Should never happen */
+}
+
+static int i2c_r(struct sd *sd, __u8 reg)
+{
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		return ov511_i2c_r(sd, reg);
+	case BRIDGE_OV518:
+	case BRIDGE_OV518PLUS:
+	case BRIDGE_OV519:
+		return ov518_i2c_r(sd, reg);
+	}
+	return -1; /* Should never happen */
+}
+
 /* Writes bits at positions specified by mask to an I2C reg. Bits that are in
  * the same position as 1's in "mask" are cleared and set to "value". Bits
  * that are in the same position as 0's in "mask" are preserved, regardless
@@ -1490,9 +1693,31 @@ static void ov51x_led_control(struct sd *sd, int on)
 	}
 }
 
-/* OV518 quantization tables are 8x4 (instead of 8x8) */
-static int ov518_upload_quan_tables(struct sd *sd)
+static int ov51x_upload_quan_tables(struct sd *sd)
 {
+	const unsigned char yQuanTable511[] = {
+		0, 1, 1, 2, 2, 3, 3, 4,
+		1, 1, 1, 2, 2, 3, 4, 4,
+		1, 1, 2, 2, 3, 4, 4, 4,
+		2, 2, 2, 3, 4, 4, 4, 4,
+		2, 2, 3, 4, 4, 5, 5, 5,
+		3, 3, 4, 4, 5, 5, 5, 5,
+		3, 4, 4, 4, 5, 5, 5, 5,
+		4, 4, 4, 4, 5, 5, 5, 5
+	};
+
+	const unsigned char uvQuanTable511[] = {
+		0, 2, 2, 3, 4, 4, 4, 4,
+		2, 2, 2, 4, 4, 4, 4, 4,
+		2, 2, 3, 4, 4, 4, 4, 4,
+		3, 4, 4, 4, 4, 4, 4, 4,
+		4, 4, 4, 4, 4, 4, 4, 4,
+		4, 4, 4, 4, 4, 4, 4, 4,
+		4, 4, 4, 4, 4, 4, 4, 4,
+		4, 4, 4, 4, 4, 4, 4, 4
+	};
+
+	/* OV518 quantization tables are 8x4 (instead of 8x8) */
 	const unsigned char yQuanTable518[] = {
 		5, 4, 5, 6, 6, 7, 7, 7,
 		5, 5, 5, 5, 6, 7, 7, 7,
@@ -1507,14 +1732,23 @@ static int ov518_upload_quan_tables(struct sd *sd)
 		7, 7, 7, 7, 7, 7, 8, 8
 	};
 
-	const unsigned char *pYTable = yQuanTable518;
-	const unsigned char *pUVTable = uvQuanTable518;
+	const unsigned char *pYTable, *pUVTable;
 	unsigned char val0, val1;
-	int i, rc, reg = R51x_COMP_LUT_BEGIN;
+	int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
 
 	PDEBUG(D_PROBE, "Uploading quantization tables");
 
-	for (i = 0; i < 16; i++) {
+	if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
+		pYTable = yQuanTable511;
+		pUVTable = uvQuanTable511;
+		size  = 32;
+	} else {
+		pYTable = yQuanTable518;
+		pUVTable = uvQuanTable518;
+		size  = 16;
+	}
+
+	for (i = 0; i < size; i++) {
 		val0 = *pYTable++;
 		val1 = *pYTable++;
 		val0 &= 0x0f;
@@ -1529,7 +1763,7 @@ static int ov518_upload_quan_tables(struct sd *sd)
 		val0 &= 0x0f;
 		val1 &= 0x0f;
 		val0 |= val1 << 4;
-		rc = reg_w(sd, reg + 16, val0);
+		rc = reg_w(sd, reg + size, val0);
 		if (rc < 0)
 			return rc;
 
@@ -1539,6 +1773,87 @@ static int ov518_upload_quan_tables(struct sd *sd)
 	return 0;
 }
 
+/* This initializes the OV511/OV511+ and the sensor */
+static int ov511_configure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int rc;
+
+	/* For 511 and 511+ */
+	const struct ov_regvals init_511[] = {
+		{ R51x_SYS_RESET,	0x7f },
+		{ R51x_SYS_INIT,	0x01 },
+		{ R51x_SYS_RESET,	0x7f },
+		{ R51x_SYS_INIT,	0x01 },
+		{ R51x_SYS_RESET,	0x3f },
+		{ R51x_SYS_INIT,	0x01 },
+		{ R51x_SYS_RESET,	0x3d },
+	};
+
+	const struct ov_regvals norm_511[] = {
+		{ R511_DRAM_FLOW_CTL, 	0x01 },
+		{ R51x_SYS_SNAP,	0x00 },
+		{ R51x_SYS_SNAP,	0x02 },
+		{ R51x_SYS_SNAP,	0x00 },
+		{ R511_FIFO_OPTS,	0x1f },
+		{ R511_COMP_EN,		0x00 },
+		{ R511_COMP_LUT_EN,	0x03 },
+	};
+
+	const struct ov_regvals norm_511_p[] = {
+		{ R511_DRAM_FLOW_CTL,	0xff },
+		{ R51x_SYS_SNAP,	0x00 },
+		{ R51x_SYS_SNAP,	0x02 },
+		{ R51x_SYS_SNAP,	0x00 },
+		{ R511_FIFO_OPTS,	0xff },
+		{ R511_COMP_EN,		0x00 },
+		{ R511_COMP_LUT_EN,	0x03 },
+	};
+
+	const struct ov_regvals compress_511[] = {
+		{ 0x70, 0x1f },
+		{ 0x71, 0x05 },
+		{ 0x72, 0x06 },
+		{ 0x73, 0x06 },
+		{ 0x74, 0x14 },
+		{ 0x75, 0x03 },
+		{ 0x76, 0x04 },
+		{ 0x77, 0x04 },
+	};
+
+	PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
+
+	rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
+	if (rc < 0)
+		return rc;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+		rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
+		if (rc < 0)
+			return rc;
+		break;
+	case BRIDGE_OV511PLUS:
+		rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
+		if (rc < 0)
+			return rc;
+		break;
+	}
+
+	/* Init compression */
+	rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
+	if (rc < 0)
+		return rc;
+
+	rc = ov51x_upload_quan_tables(sd);
+	if (rc < 0) {
+		PDEBUG(D_ERR, "Error uploading quantization tables");
+		return rc;
+	}
+
+	return 0;
+}
+
 /* This initializes the OV518/OV518+ and the sensor */
 static int ov518_configure(struct gspca_dev *gspca_dev)
 {
@@ -1615,7 +1930,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
 		break;
 	}
 
-	rc = ov518_upload_quan_tables(sd);
+	rc = ov51x_upload_quan_tables(sd);
 	if (rc < 0) {
 		PDEBUG(D_ERR, "Error uploading quantization tables");
 		return rc;
@@ -1661,6 +1976,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
 
 	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		ret = ov511_configure(gspca_dev);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 		ret = ov518_configure(gspca_dev);
@@ -1719,6 +2038,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		if (!sd->sif) {
+			cam->cam_mode = ov511_vga_mode;
+			cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
+		} else {
+			cam->cam_mode = ov511_sif_mode;
+			cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
+		}
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 		if (!sd->sif) {
@@ -1810,6 +2139,126 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	return 0;
 }
 
+/* Set up the OV511/OV511+ with the given image parameters.
+ *
+ * Do not put any sensor-specific code in here (including I2C I/O functions)
+ */
+static int ov511_mode_init_regs(struct sd *sd)
+{
+	int hsegs, vsegs, packet_size, fps, needed;
+	int interlaced = 0;
+	struct usb_host_interface *alt;
+	struct usb_interface *intf;
+
+	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+	if (!alt) {
+		PDEBUG(D_ERR, "Couldn't get altsetting");
+		return -EIO;
+	}
+
+	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+	reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
+
+	reg_w(sd, R511_CAM_UV_EN, 0x01);
+	reg_w(sd, R511_SNAP_UV_EN, 0x01);
+	reg_w(sd, R511_SNAP_OPTS, 0x03);
+
+	/* Here I'm assuming that snapshot size == image size.
+	 * I hope that's always true. --claudio
+	 */
+	hsegs = (sd->gspca_dev.width >> 3) - 1;
+	vsegs = (sd->gspca_dev.height >> 3) - 1;
+
+	reg_w(sd, R511_CAM_PXCNT, hsegs);
+	reg_w(sd, R511_CAM_LNCNT, vsegs);
+	reg_w(sd, R511_CAM_PXDIV, 0x00);
+	reg_w(sd, R511_CAM_LNDIV, 0x00);
+
+	/* YUV420, low pass filter on */
+	reg_w(sd, R511_CAM_OPTS, 0x03);
+
+	/* Snapshot additions */
+	reg_w(sd, R511_SNAP_PXCNT, hsegs);
+	reg_w(sd, R511_SNAP_LNCNT, vsegs);
+	reg_w(sd, R511_SNAP_PXDIV, 0x00);
+	reg_w(sd, R511_SNAP_LNDIV, 0x00);
+
+	/******** Set the framerate ********/
+	if (frame_rate > 0)
+		sd->frame_rate = frame_rate;
+
+	switch (sd->sensor) {
+	case SEN_OV6620:
+		/* No framerate control, doesn't like higher rates yet */
+		sd->clockdiv = 3;
+		break;
+
+	/* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
+	   for more sensors we need to do this for them too */
+	case SEN_OV7620:
+	case SEN_OV7640:
+		if (sd->gspca_dev.width == 320)
+			interlaced = 1;
+		/* Fall through */
+	case SEN_OV6630:
+	case SEN_OV76BE:
+	case SEN_OV7610:
+	case SEN_OV7670:
+		switch (sd->frame_rate) {
+		case 30:
+		case 25:
+			/* Not enough bandwidth to do 640x480 @ 30 fps */
+			if (sd->gspca_dev.width != 640) {
+				sd->clockdiv = 0;
+				break;
+			}
+			/* Fall through for 640x480 case */
+		default:
+/*		case 20: */
+/*		case 15: */
+			sd->clockdiv = 1;
+			break;
+		case 10:
+			sd->clockdiv = 2;
+			break;
+		case 5:
+			sd->clockdiv = 5;
+			break;
+		}
+		if (interlaced) {
+			sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
+			/* Higher then 10 does not work */
+			if (sd->clockdiv > 10)
+				sd->clockdiv = 10;
+		}
+		break;
+
+	case SEN_OV8610:
+		/* No framerate control ?? */
+		sd->clockdiv = 0;
+		break;
+	}
+
+	/* Check if we have enough bandwidth to disable compression */
+	fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
+	needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
+	/* 1400 is a conservative estimate of the max nr of isoc packets/sec */
+	if (needed > 1400 * packet_size) {
+		/* Enable Y and UV quantization and compression */
+		reg_w(sd, R511_COMP_EN, 0x07);
+		reg_w(sd, R511_COMP_LUT_EN, 0x03);
+	} else {
+		reg_w(sd, R511_COMP_EN, 0x06);
+		reg_w(sd, R511_COMP_LUT_EN, 0x00);
+	}
+
+	reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
+	reg_w(sd, R51x_SYS_RESET, 0);
+
+	return 0;
+}
+
 /* Sets up the OV518/OV518+ with the given image parameters
  *
  * OV518 needs a completely different approach, until we can figure out what
@@ -2363,6 +2812,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	int ret = 0;
 
 	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		ret = ov511_mode_init_regs(sd);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 		ret = ov518_mode_init_regs(sd);
@@ -2403,6 +2856,56 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 	ov51x_led_control(sd, 0);
 }
 
+static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
+			struct gspca_frame *frame,	/* target */
+			__u8 *in,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
+	 * byte non-zero. The EOF packet has image width/height in the
+	 * 10th and 11th bytes. The 9th byte is given as follows:
+	 *
+	 * bit 7: EOF
+	 *     6: compression enabled
+	 *     5: 422/420/400 modes
+	 *     4: 422/420/400 modes
+	 *     3: 1
+	 *     2: snapshot button on
+	 *     1: snapshot frame
+	 *     0: even/odd field
+	 */
+	if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
+	    (in[8] & 0x08)) {
+		if (in[8] & 0x80) {
+			/* Frame end */
+			if ((in[9] + 1) * 8 != gspca_dev->width ||
+			    (in[10] + 1) * 8 != gspca_dev->height) {
+				PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
+					" requested: %dx%d\n",
+					(in[9] + 1) * 8, (in[10] + 1) * 8,
+					gspca_dev->width, gspca_dev->height);
+				gspca_dev->last_packet_type = DISCARD_PACKET;
+				return;
+			}
+			/* Add 11 byte footer to frame, might be usefull */
+			gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11);
+			return;
+		} else {
+			/* Frame start */
+			gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0);
+			sd->packet_nr = 0;
+		}
+	}
+
+	/* Ignore the packet number */
+	len--;
+
+	/* intermediate packet */
+	gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len);
+}
+
 static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -2495,6 +2998,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
+		ov511_pkt_scan(gspca_dev, frame, data, len);
 		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
@@ -2862,12 +3366,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
 	{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
 	{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
 	{USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
+	{USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
 	{}
 };
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 772d226cb5c..8a025d51090 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -348,6 +348,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_SQ905C   v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
 #define V4L2_PIX_FMT_PJPG     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
 #define V4L2_PIX_FMT_YVYU     v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
+#define V4L2_PIX_FMT_OV511    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
 #define V4L2_PIX_FMT_OV518    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
 
 /*
-- 
cgit v1.2.3-70-g09d2


From b282d87332f5b3c2ac2e289f772b33067e4be77b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 19:10:40 -0300
Subject: V4L/DVB (12080): gspca_ov519: Fix ov518+ with OV7620AE (Trust
 spacecam 320)

gspca_ov519: Fix ov518+ with OV7620AE (Trust spacecam 320)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 91 +++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 36 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1f8e2613ecc..3aebc744368 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -269,37 +269,43 @@ static const struct v4l2_pix_format ov519_sif_mode[] = {
 		.priv = 0},
 };
 
+/* Note some of the sizeimage values for the ov511 / ov518 may seem
+   larger then necessary, however they need to be this big as the ov511 /
+   ov518 always fills the entire isoc frame, using 0 padding bytes when
+   it doesn't have any data. So with low framerates the amount of data
+   transfered can become quite large (libv4l will remove all the 0 padding
+   in userspace). */
 static const struct v4l2_pix_format ov518_vga_mode[] = {
 	{320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 320,
-		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.sizeimage = 320 * 240 * 3,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
 	{640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 640,
-		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		.sizeimage = 640 * 480 * 2,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
 };
 static const struct v4l2_pix_format ov518_sif_mode[] = {
 	{160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 160,
-		.sizeimage = 40000,
+		.sizeimage = 70000,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 3},
 	{176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 176,
-		.sizeimage = 40000,
+		.sizeimage = 70000,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
 	{320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 320,
-		.sizeimage = 320 * 240 * 3 / 8 + 590,
+		.sizeimage = 320 * 240 * 3,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 2},
 	{352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
 		.bytesperline = 352,
-		.sizeimage = 352 * 288 * 3 / 8 + 590,
+		.sizeimage = 352 * 288 * 3,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
 };
@@ -319,12 +325,12 @@ static const struct v4l2_pix_format ov511_vga_mode[] = {
 static const struct v4l2_pix_format ov511_sif_mode[] = {
 	{160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
 		.bytesperline = 160,
-		.sizeimage = 40000,
+		.sizeimage = 70000,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 3},
 	{176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
 		.bytesperline = 176,
-		.sizeimage = 40000,
+		.sizeimage = 70000,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
 	{320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
@@ -698,7 +704,7 @@ static const struct ov_i2c_regvals norm_7620[] = {
 	{ 0x23, 0x00 },
 	{ 0x26, 0xa2 },
 	{ 0x27, 0xea },
-	{ 0x28, 0x20 },
+	{ 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
 	{ 0x29, 0x00 },
 	{ 0x2a, 0x10 },
 	{ 0x2b, 0x00 },
@@ -1525,7 +1531,6 @@ static int ov8xx0_configure(struct sd *sd)
 	}
 
 	/* Set sensor-specific vars */
-/*	sd->sif = 0;		already done */
 	return 0;
 }
 
@@ -1562,15 +1567,13 @@ static int ov7xx0_configure(struct sd *sd)
 		}
 	} else if ((rc & 3) == 1) {
 		/* I don't know what's different about the 76BE yet. */
-		if (i2c_r(sd, 0x15) & 1)
+		if (i2c_r(sd, 0x15) & 1) {
 			PDEBUG(D_PROBE, "Sensor is an OV7620AE");
-		else
+			sd->sensor = SEN_OV7620;
+		} else {
 			PDEBUG(D_PROBE, "Sensor is an OV76BE");
-
-		/* OV511+ will return all zero isoc data unless we
-		 * configure the sensor as a 7620. Someone needs to
-		 * find the exact reg. setting that causes this. */
-		sd->sensor = SEN_OV76BE;
+			sd->sensor = SEN_OV76BE;
+		}
 	} else if ((rc & 3) == 0) {
 		/* try to read product id registers */
 		high = i2c_r(sd, 0x0a);
@@ -1616,7 +1619,6 @@ static int ov7xx0_configure(struct sd *sd)
 	}
 
 	/* Set sensor-specific vars */
-/*	sd->sif = 0;		already done */
 	return 0;
 }
 
@@ -2198,11 +2200,11 @@ static int ov511_mode_init_regs(struct sd *sd)
 	   for more sensors we need to do this for them too */
 	case SEN_OV7620:
 	case SEN_OV7640:
+	case SEN_OV76BE:
 		if (sd->gspca_dev.width == 320)
 			interlaced = 1;
 		/* Fall through */
 	case SEN_OV6630:
-	case SEN_OV76BE:
 	case SEN_OV7610:
 	case SEN_OV7670:
 		switch (sd->frame_rate) {
@@ -2268,7 +2270,19 @@ static int ov511_mode_init_regs(struct sd *sd)
  */
 static int ov518_mode_init_regs(struct sd *sd)
 {
-	int hsegs, vsegs;
+	int hsegs, vsegs, packet_size;
+	struct usb_host_interface *alt;
+	struct usb_interface *intf;
+
+	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+	if (!alt) {
+		PDEBUG(D_ERR, "Couldn't get altsetting");
+		return -EIO;
+	}
+
+	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+	ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
 
 	/******** Set the mode ********/
 
@@ -2305,20 +2319,30 @@ static int ov518_mode_init_regs(struct sd *sd)
 	/* Windows driver does this here; who knows why */
 	reg_w(sd, 0x2f, 0x80);
 
-	/******** Set the framerate (to 30 FPS) ********/
-	if (sd->bridge == BRIDGE_OV518PLUS)
-		sd->clockdiv = 1;
-	else
-		sd->clockdiv = 0;
+	/******** Set the framerate  ********/
+	sd->clockdiv = 1;
 
 	/* Mode independent, but framerate dependent, regs */
-	reg_w(sd, 0x51, 0x04);	/* Clock divider; lower==faster */
+	/* 0x51: Clock divider; Only works on some cams which use 2 crystals */
+	reg_w(sd, 0x51, 0x04);
 	reg_w(sd, 0x22, 0x18);
 	reg_w(sd, 0x23, 0xff);
 
-	if (sd->bridge == BRIDGE_OV518PLUS)
-		reg_w(sd, 0x21, 0x19);
-	else
+	if (sd->bridge == BRIDGE_OV518PLUS) {
+		switch (sd->sensor) {
+		case SEN_OV7620:
+			if (sd->gspca_dev.width == 320) {
+				reg_w(sd, 0x20, 0x00);
+				reg_w(sd, 0x21, 0x19);
+			} else {
+				reg_w(sd, 0x20, 0x60);
+				reg_w(sd, 0x21, 0x1f);
+			}
+			break;
+		default:
+			reg_w(sd, 0x21, 0x19);
+		}
+	} else
 		reg_w(sd, 0x71, 0x17);	/* Compression-related? */
 
 	/* FIXME: Sensor-specific */
@@ -2537,21 +2561,16 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		break;
 	case SEN_OV7620:
-/*		i2c_w(sd, 0x2b, 0x00); */
+	case SEN_OV76BE:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
 		i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
 		i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
 		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
-		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
+		i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
 		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
 		break;
-	case SEN_OV76BE:
-/*		i2c_w(sd, 0x2b, 0x00); */
-		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
-		break;
 	case SEN_OV7640:
-/*		i2c_w(sd, 0x2b, 0x00); */
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
 		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
 /*		i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */
-- 
cgit v1.2.3-70-g09d2


From ae49c40461d8981b232e3fec28234d492067f0e1 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 14 Jun 2009 19:15:07 -0300
Subject: V4L/DVB (12081): gspca_ov519: Cleanup some sensor special cases

gspca_ov519: Cleanup some sensor special cases

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 24 ++++--------------------
 1 file changed, 4 insertions(+), 20 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 3aebc744368..cb5f3c786db 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -529,7 +529,7 @@ static const struct ov_i2c_regvals norm_6x20[] = {
 	{ 0x28, 0x05 },
 	{ 0x2a, 0x04 }, /* Disable framerate adjust */
 /*	{ 0x2b, 0xac },  * Framerate; Set 2a[7] first */
-	{ 0x2d, 0x99 },
+	{ 0x2d, 0x85 },
 	{ 0x33, 0xa0 }, /* Color Processing Parameter */
 	{ 0x34, 0xd2 }, /* Max A/D range */
 	{ 0x38, 0x8b },
@@ -2120,6 +2120,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 /*	case SEN_OV76BE: */
 		if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
 			return -EIO;
+		if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
+			return -EIO;
 		break;
 	case SEN_OV7620:
 		if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
@@ -2597,10 +2599,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 	}
 
 	/******** Palette-specific regs ********/
-	if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
-		/* not valid on the OV6620/OV7620/6630? */
-		i2c_w_mask(sd, 0x0e, 0x00, 0x40);
-	}
 
 	/* The OV518 needs special treatment. Although both the OV518
 	 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
@@ -2615,21 +2613,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 		i2c_w_mask(sd, 0x13, 0x00, 0x20);
 
 	/******** Clock programming ********/
-	/* The OV6620 needs special handling. This prevents the
-	 * severe banding that normally occurs */
-	if (sd->sensor == SEN_OV6620) {
-
-		/* Clock down */
-		i2c_w(sd, 0x2a, 0x04);
-		i2c_w(sd, 0x11, sd->clockdiv);
-		i2c_w(sd, 0x2a, 0x84);
-		/* This next setting is critical. It seems to improve
-		 * the gain or the contrast. The "reserved" bits seem
-		 * to have some effect in this case. */
-		i2c_w(sd, 0x2d, 0x85);
-	} else {
-		i2c_w(sd, 0x11, sd->clockdiv);
-	}
+	i2c_w(sd, 0x11, sd->clockdiv);
 
 	/******** Special Features ********/
 /* no evidence this is possible with OV7670, either */
-- 
cgit v1.2.3-70-g09d2


From 8668d504d72c384fbfb6ab6f5d02a9fe4d813554 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 17 Jun 2009 18:37:57 -0300
Subject: V4L/DVB (12082): gspca_stv06xx: Add support for st6422 bridge and
 sensor

Add support for st6422 bridge and sensor to the stv06xx gspca sub driver,
tested with:
Logitech QuickCam Messenger     046d:08f0       ST6422  integrated
Logitech QuickCam Mess. Plus    046d:08f6       ST6422  integrated

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/stv06xx/Makefile         |   3 +-
 drivers/media/video/gspca/stv06xx/stv06xx.c        |  53 ++-
 drivers/media/video/gspca/stv06xx/stv06xx.h        |  11 +
 drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c   |  10 +-
 drivers/media/video/gspca/stv06xx/stv06xx_sensor.h |   3 +-
 drivers/media/video/gspca/stv06xx/stv06xx_st6422.c | 453 +++++++++++++++++++++
 drivers/media/video/gspca/stv06xx/stv06xx_st6422.h |  59 +++
 7 files changed, 577 insertions(+), 15 deletions(-)
 create mode 100644 drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
 create mode 100644 drivers/media/video/gspca/stv06xx/stv06xx_st6422.h

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile
index feeaa94ab58..2f3c3a606ce 100644
--- a/drivers/media/video/gspca/stv06xx/Makefile
+++ b/drivers/media/video/gspca/stv06xx/Makefile
@@ -3,7 +3,8 @@ obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
 gspca_stv06xx-objs := stv06xx.o \
 		      stv06xx_vv6410.o \
 		      stv06xx_hdcs.o \
-		      stv06xx_pb0100.o
+		      stv06xx_pb0100.o \
+		      stv06xx_st6422.o
 
 EXTRA_CFLAGS += -Idrivers/media/video/gspca
 
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index e573c340632..0da8e0de045 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -92,11 +92,10 @@ static int stv06xx_write_sensor_finish(struct sd *sd)
 {
 	int err = 0;
 
-	if (IS_850(sd)) {
+	if (sd->bridge == BRIDGE_STV610) {
 		struct usb_device *udev = sd->gspca_dev.dev;
 		__u8 *buf = sd->gspca_dev.usb_buf;
 
-		/* Quickam Web needs an extra packet */
 		buf[0] = 0;
 		err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				      0x04, 0x40, 0x1704, 0, buf, 1,
@@ -253,7 +252,7 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
 
 	err = sd->sensor->init(sd);
 
-	if (dump_sensor)
+	if (dump_sensor && sd->sensor->dump)
 		sd->sensor->dump(sd);
 
 	return (err < 0) ? err : 0;
@@ -318,6 +317,8 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
 	PDEBUG(D_PACK, "Packet of length %d arrived", len);
 
 	/* A packet may contain several frames
@@ -343,14 +344,29 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 		if (len < chunk_len) {
 			PDEBUG(D_ERR, "URB packet length is smaller"
 				" than the specified chunk length");
+			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
 
+		/* First byte seem to be 02=data 2nd byte is unknown??? */
+		if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200)
+			goto frame_data;
+
 		switch (id) {
 		case 0x0200:
 		case 0x4200:
+frame_data:
 			PDEBUG(D_PACK, "Frame data packet detected");
 
+			if (sd->to_skip) {
+				int skip = (sd->to_skip < chunk_len) ?
+					    sd->to_skip : chunk_len;
+				data += skip;
+				len -= skip;
+				chunk_len -= skip;
+				sd->to_skip -= skip;
+			}
+
 			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
 					data, chunk_len);
 			break;
@@ -365,6 +381,9 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
 					frame, data, 0);
 
+			if (sd->bridge == BRIDGE_ST6422)
+				sd->to_skip = gspca_dev->width * 4;
+
 			if (chunk_len)
 				PDEBUG(D_ERR, "Chunk length is "
 					      "non-zero on a SOF");
@@ -395,8 +414,12 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 			/* Unknown chunk with 2 bytes of data,
 			   occurs 2-3 times per USB interrupt */
 			break;
+		case 0x42ff:
+			PDEBUG(D_PACK, "Chunk 0x42ff detected");
+			/* Special chunk seen sometimes on the ST6422 */
+			break;
 		default:
-			PDEBUG(D_PACK, "Unknown chunk %d detected", id);
+			PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
 			/* Unknown chunk */
 		}
 		data    += chunk_len;
@@ -428,11 +451,16 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 	sd->desc = sd_desc;
+	sd->bridge = id->driver_info;
 	gspca_dev->sd_desc = &sd->desc;
 
 	if (dump_bridge)
 		stv06xx_dump_bridge(sd);
 
+	sd->sensor = &stv06xx_sensor_st6422;
+	if (!sd->sensor->probe(sd))
+		return 0;
+
 	sd->sensor = &stv06xx_sensor_vv6410;
 	if (!sd->sensor->probe(sd))
 		return 0;
@@ -457,9 +485,20 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x046d, 0x0840)}, /* QuickCam Express */
-	{USB_DEVICE(0x046d, 0x0850)}, /* LEGO cam / QuickCam Web */
-	{USB_DEVICE(0x046d, 0x0870)}, /* Dexxa WebCam USB */
+	/* QuickCam Express */
+	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
+	/* LEGO cam / QuickCam Web */
+	{USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 },
+	/* Dexxa WebCam USB */
+	{USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 },
+	/* QuickCam Messenger */
+	{USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 },
+	/* QuickCam Communicate */
+	{USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
+	/* QuickCam Messenger (new) */
+	{USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
+	/* QuickCam Messenger (new) */
+	{USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 },
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
index 1207e7d17f1..9df7137fe67 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -93,6 +93,17 @@ struct sd {
 
 	/* Sensor private data */
 	void *sensor_priv;
+
+	/* The first 4 lines produced by the stv6422 are no good, this keeps
+	   track of how many bytes we still need to skip during a frame */
+	int to_skip;
+
+	/* Bridge / Camera type */
+	u8 bridge;
+	#define BRIDGE_STV600 0
+	#define BRIDGE_STV602 1
+	#define BRIDGE_STV610 2
+	#define BRIDGE_ST6422 3 /* With integrated sensor */
 };
 
 int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index b1690381420..3039ec208f3 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -434,7 +434,7 @@ static int hdcs_probe_1x00(struct sd *sd)
 	hdcs->exp.er = 100;
 
 	/*
-	 * Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP:
+	 * Frame rate on HDCS-1000 with STV600 depends on PSMP:
 	 *  4 = doesn't work at all
 	 *  5 = 7.8 fps,
 	 *  6 = 6.9 fps,
@@ -443,7 +443,7 @@ static int hdcs_probe_1x00(struct sd *sd)
 	 * 15 = 4.4 fps,
 	 * 31 = 2.8 fps
 	 *
-	 * Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP:
+	 * Frame rate on HDCS-1000 with STV602 depends on PSMP:
 	 * 15 = doesn't work at all
 	 * 18 = doesn't work at all
 	 * 19 = 7.3 fps
@@ -453,7 +453,7 @@ static int hdcs_probe_1x00(struct sd *sd)
 	 * 24 = 6.3 fps
 	 * 30 = 5.4 fps
 	 */
-	hdcs->psmp = IS_870(sd) ? 20 : 5;
+	hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5;
 
 	sd->sensor_priv = hdcs;
 
@@ -530,7 +530,7 @@ static int hdcs_init(struct sd *sd)
 	int i, err = 0;
 
 	/* Set the STV0602AA in STV0600 emulation mode */
-	if (IS_870(sd))
+	if (sd->bridge == BRIDGE_STV602)
 		stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1);
 
 	/* Execute the bridge init */
@@ -558,7 +558,7 @@ static int hdcs_init(struct sd *sd)
 		return err;
 
 	/* Set PGA sample duration
-	(was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */
+	(was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */
 	if (IS_1020(sd))
 		err = stv06xx_write_sensor(sd, HDCS_TCTRL,
 				(HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index e88c42f7d2f..934b9cebc1a 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -32,14 +32,13 @@
 
 #include "stv06xx.h"
 
-#define IS_850(sd)	((sd)->gspca_dev.dev->descriptor.idProduct == 0x850)
-#define IS_870(sd)	((sd)->gspca_dev.dev->descriptor.idProduct == 0x870)
 #define IS_1020(sd)	((sd)->sensor == &stv06xx_sensor_hdcs1020)
 
 extern const struct stv06xx_sensor stv06xx_sensor_vv6410;
 extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
 extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
 extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
+extern const struct stv06xx_sensor stv06xx_sensor_st6422;
 
 struct stv06xx_sensor {
 	/* Defines the name of a sensor */
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
new file mode 100644
index 00000000000..87cb5b9ddfa
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -0,0 +1,453 @@
+/*
+ * Support for the sensor part which is integrated (I think) into the
+ * st6422 stv06xx alike bridge, as its integrated there are no i2c writes
+ * but instead direct bridge writes.
+ *
+ * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Strongly based on qc-usb-messenger, which is:
+ * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
+ *		      Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
+ * Copyright (c) 2002, 2003 Tuukka Toivonen
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "stv06xx_st6422.h"
+
+static struct v4l2_pix_format st6422_mode[] = {
+	/* Note we actually get 124 lines of data, of which we skip the 4st
+	   4 as they are garbage */
+	{
+		162,
+		120,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 162 * 120,
+		.bytesperline = 162,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	},
+	/* Note we actually get 248 lines of data, of which we skip the 4st
+	   4 as they are garbage, and we tell the app it only gets the
+	   first 240 of the 244 lines it actually gets, so that it ignores
+	   the last 4. */
+	{
+		324,
+		240,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 324 * 244,
+		.bytesperline = 324,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
+};
+
+static const struct ctrl st6422_ctrl[] = {
+#define BRIGHTNESS_IDX 0
+	{
+		{
+			.id		= V4L2_CID_BRIGHTNESS,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Brightness",
+			.minimum	= 0,
+			.maximum	= 31,
+			.step		= 1,
+			.default_value  = 3
+		},
+		.set = st6422_set_brightness,
+		.get = st6422_get_brightness
+	},
+#define CONTRAST_IDX 1
+	{
+		{
+			.id		= V4L2_CID_CONTRAST,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Contrast",
+			.minimum	= 0,
+			.maximum	= 15,
+			.step		= 1,
+			.default_value  = 11
+		},
+		.set = st6422_set_contrast,
+		.get = st6422_get_contrast
+	},
+#define GAIN_IDX 2
+	{
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Gain",
+			.minimum	= 0,
+			.maximum	= 255,
+			.step		= 1,
+			.default_value  = 64
+		},
+		.set = st6422_set_gain,
+		.get = st6422_get_gain
+	},
+#define EXPOSURE_IDX 3
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Exposure",
+			.minimum	= 0,
+			.maximum	= 1023,
+			.step		= 1,
+			.default_value  = 256
+		},
+		.set = st6422_set_exposure,
+		.get = st6422_get_exposure
+	},
+};
+
+static int st6422_probe(struct sd *sd)
+{
+	int i;
+	s32 *sensor_settings;
+
+	if (sd->bridge != BRIDGE_ST6422)
+		return -ENODEV;
+
+	info("st6422 sensor detected");
+
+	sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32),
+				  GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
+	sd->gspca_dev.cam.cam_mode = st6422_mode;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
+	sd->desc.ctrls = st6422_ctrl;
+	sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
+	sd->sensor_priv = sensor_settings;
+
+	for (i = 0; i < sd->desc.nctrls; i++)
+		sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
+
+	return 0;
+}
+
+static int st6422_init(struct sd *sd)
+{
+	int err = 0, i;
+
+	const u16 st6422_bridge_init[][2] = {
+		{ STV_ISO_ENABLE, 0x00 }, /* disable capture */
+		{ 0x1436, 0x00 },
+		{ 0x1432, 0x03 },	/* 0x00-0x1F brightness */
+		{ 0x143a, 0xF9 },	/* 0x00-0x0F contrast */
+		{ 0x0509, 0x38 },	/* R */
+		{ 0x050a, 0x38 },	/* G */
+		{ 0x050b, 0x38 },	/* B */
+		{ 0x050c, 0x2A },
+		{ 0x050d, 0x01 },
+
+
+		{ 0x1431, 0x00 },	/* 0x00-0x07 ??? */
+		{ 0x1433, 0x34 },	/* 160x120, 0x00-0x01 night filter */
+		{ 0x1438, 0x18 },	/* 640x480 */
+/* 18 bayes */
+/* 10 compressed? */
+
+		{ 0x1439, 0x00 },
+/* antiflimmer??  0xa2 ger perfekt bild mot monitor */
+
+		{ 0x143b, 0x05 },
+		{ 0x143c, 0x00 },	/* 0x00-0x01 - ??? */
+
+
+/* shutter time 0x0000-0x03FF */
+/* low value  give good picures on moving objects (but requires much light) */
+/* high value gives good picures in darkness (but tends to be overexposed) */
+		{ 0x143e, 0x01 },
+		{ 0x143d, 0x00 },
+
+		{ 0x1442, 0xe2 },
+/* write: 1x1x xxxx */
+/* read:  1x1x xxxx */
+/*        bit 5 == button pressed and hold if 0 */
+/* write 0xe2,0xea */
+
+/* 0x144a */
+/* 0x00 init */
+/* bit 7 == button has been pressed, but not handled */
+
+/* interrupt */
+/* if(urb->iso_frame_desc[i].status == 0x80) { */
+/* if(urb->iso_frame_desc[i].status == 0x88) { */
+
+		{ 0x1500, 0xd0 },
+		{ 0x1500, 0xd0 },
+		{ 0x1500, 0x50 },	/* 0x00 - 0xFF  0x80 == compr ? */
+
+		{ 0x1501, 0xaf },
+/* high val-> ljus area blir morkare. */
+/* low val -> ljus area blir ljusare. */
+		{ 0x1502, 0xc2 },
+/* high val-> ljus area blir morkare. */
+/* low val -> ljus area blir ljusare. */
+		{ 0x1503, 0x45 },
+/* high val-> ljus area blir morkare. */
+/* low val -> ljus area blir ljusare. */
+
+		{ 0x1505, 0x02 },
+/* 2  : 324x248  80352 bytes */
+/* 7  : 248x162  40176 bytes */
+/* c+f: 162*124  20088 bytes */
+
+		{ 0x150e, 0x8e },
+		{ 0x150f, 0x37 },
+		{ 0x15c0, 0x00 },
+		{ 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */
+		{ 0x15c3, 0x08 },	/* 0x04/0x14 ... test pictures ??? */
+
+
+		{ 0x143f, 0x01 },	/* commit settings */
+
+	};
+
+	for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) {
+		err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0],
+					       st6422_bridge_init[i][1]);
+	}
+
+	return err;
+}
+
+static void st6422_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
+static int st6422_start(struct sd *sd)
+{
+	int err, packet_size;
+	struct cam *cam = &sd->gspca_dev.cam;
+	s32 *sensor_settings = sd->sensor_priv;
+	struct usb_host_interface *alt;
+	struct usb_interface *intf;
+
+	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+	if (!alt) {
+		PDEBUG(D_ERR, "Couldn't get altsetting");
+		return -EIO;
+	}
+
+	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+	err = stv06xx_write_bridge(sd, 0x15c1, packet_size);
+	if (err < 0)
+		return err;
+
+	if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
+		err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
+	else
+		err = stv06xx_write_bridge(sd, 0x1505, 0x02);
+	if (err < 0)
+		return err;
+
+	err = st6422_set_brightness(&sd->gspca_dev,
+				    sensor_settings[BRIGHTNESS_IDX]);
+	if (err < 0)
+		return err;
+
+	err = st6422_set_contrast(&sd->gspca_dev,
+				  sensor_settings[CONTRAST_IDX]);
+	if (err < 0)
+		return err;
+
+	err = st6422_set_exposure(&sd->gspca_dev,
+				  sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = st6422_set_gain(&sd->gspca_dev,
+			      sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
+	PDEBUG(D_STREAM, "Starting stream");
+
+	return 0;
+}
+
+static int st6422_stop(struct sd *sd)
+{
+	PDEBUG(D_STREAM, "Halting stream");
+
+	return 0;
+}
+
+static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[BRIGHTNESS_IDX];
+
+	PDEBUG(D_V4L2, "Read brightness %d", *val);
+
+	return 0;
+}
+
+static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[BRIGHTNESS_IDX] = val;
+
+	if (!gspca_dev->streaming)
+		return 0;
+
+	/* val goes from 0 -> 31 */
+	PDEBUG(D_V4L2, "Set brightness to %d", val);
+	err = stv06xx_write_bridge(sd, 0x1432, val);
+	if (err < 0)
+		return err;
+
+	/* commit settings */
+	err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+	return (err < 0) ? err : 0;
+}
+
+static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[CONTRAST_IDX];
+
+	PDEBUG(D_V4L2, "Read contrast %d", *val);
+
+	return 0;
+}
+
+static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[CONTRAST_IDX] = val;
+
+	if (!gspca_dev->streaming)
+		return 0;
+
+	/* Val goes from 0 -> 15 */
+	PDEBUG(D_V4L2, "Set contrast to %d\n", val);
+	err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
+	if (err < 0)
+		return err;
+
+	/* commit settings */
+	err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+	return (err < 0) ? err : 0;
+}
+
+static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[GAIN_IDX];
+
+	PDEBUG(D_V4L2, "Read gain %d", *val);
+
+	return 0;
+}
+
+static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[GAIN_IDX] = val;
+
+	if (!gspca_dev->streaming)
+		return 0;
+
+	PDEBUG(D_V4L2, "Set gain to %d", val);
+
+	/* Set red, green, blue, gain */
+	err = stv06xx_write_bridge(sd, 0x0509, val);
+	if (err < 0)
+		return err;
+
+	err = stv06xx_write_bridge(sd, 0x050a, val);
+	if (err < 0)
+		return err;
+
+	err = stv06xx_write_bridge(sd, 0x050b, val);
+	if (err < 0)
+		return err;
+
+	/* 2 mystery writes */
+	err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
+	if (err < 0)
+		return err;
+
+	err = stv06xx_write_bridge(sd, 0x050d, 0x01);
+	if (err < 0)
+		return err;
+
+	/* commit settings */
+	err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+	return (err < 0) ? err : 0;
+}
+
+static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[EXPOSURE_IDX];
+
+	PDEBUG(D_V4L2, "Read exposure %d", *val);
+
+	return 0;
+}
+
+static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[EXPOSURE_IDX] = val;
+
+	if (!gspca_dev->streaming)
+		return 0;
+
+	PDEBUG(D_V4L2, "Set exposure to %d\n", val);
+	err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
+	if (err < 0)
+		return err;
+
+	err = stv06xx_write_bridge(sd, 0x143e, val >> 8);
+	if (err < 0)
+		return err;
+
+	/* commit settings */
+	err = stv06xx_write_bridge(sd, 0x143f, 0x01);
+	return (err < 0) ? err : 0;
+}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
new file mode 100644
index 00000000000..b2d45fe5052
--- /dev/null
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
@@ -0,0 +1,59 @@
+/*
+ * Support for the sensor part which is integrated (I think) into the
+ * st6422 stv06xx alike bridge, as its integrated there are no i2c writes
+ * but instead direct bridge writes.
+ *
+ * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Strongly based on qc-usb-messenger, which is:
+ * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
+ *		      Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
+ * Copyright (c) 2002, 2003 Tuukka Toivonen
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef STV06XX_ST6422_H_
+#define STV06XX_ST6422_H_
+
+#include "stv06xx_sensor.h"
+
+static int st6422_probe(struct sd *sd);
+static int st6422_start(struct sd *sd);
+static int st6422_init(struct sd *sd);
+static int st6422_stop(struct sd *sd);
+static void st6422_disconnect(struct sd *sd);
+
+/* V4L2 controls supported by the driver */
+static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
+static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
+static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
+
+const struct stv06xx_sensor stv06xx_sensor_st6422 = {
+	.name = "ST6422",
+	.init = st6422_init,
+	.probe = st6422_probe,
+	.start = st6422_start,
+	.stop = st6422_stop,
+	.disconnect = st6422_disconnect,
+};
+
+#endif
-- 
cgit v1.2.3-70-g09d2


From 98b1e9be882eff0f00bb5770ced9d9b24eb0238c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 17 Jun 2009 18:41:01 -0300
Subject: V4L/DVB (12083): ov511: remove ov518 usb id's from the driver

ov511: remove ov518 usb id's from the driver, as they have not been working
ever since the decompression code got removed from the kernel, and they
are no supported by the gspca_ov519 module.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/ov511.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 08cfd3e4ae8..0bc2cf573c7 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -211,8 +211,6 @@ static const int i2c_detect_tries = 5;
 static struct usb_device_id device_table [] = {
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
-	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
-	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) },
 	{ USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
 	{ }  /* Terminating entry */
 };
-- 
cgit v1.2.3-70-g09d2


From 0220f8870e66628f19c36bad813e881ebfaae7a6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 17 Jun 2009 18:50:10 -0300
Subject: V4L/DVB (12084): ov511: mark as deprecated

Mark the v4l1 ov511 as deprecated as we now have ov511 support in
the gspca ov519 driver. Note we should really also keep track of this
in Documentation/feature-removal-schedule.txt, but that is not
part of the v4l-dvb tree.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/Kconfig | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 94f440535c6..061e147f6f2 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -866,9 +866,13 @@ config USB_W9968CF
 	  module will be called w9968cf.
 
 config USB_OV511
-	tristate "USB OV511 Camera support"
+	tristate "USB OV511 Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1
 	---help---
+	  This driver is DEPRECATED please use the gspca ov519 module
+	  instead. Note that for the ov511 / ov518 support of the gspca module
+	  you need atleast version 0.6.0 of libv4l.
+
 	  Say Y here if you want to connect this type of camera to your
 	  computer's USB port. See <file:Documentation/video4linux/ov511.txt>
 	  for more information and for a list of supported cameras.
-- 
cgit v1.2.3-70-g09d2


From e080fcd9298d544f3233d8c45304990be1920b3d Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 05:03:16 -0300
Subject: V4L/DVB (12085): gspca_ov519: constify ov518 inititial register value
 tables

gspca_ov519: constify ov518 inititial register value tables

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/ov519.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index cb5f3c786db..2f6e135d94b 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1863,7 +1863,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
 	int rc;
 
 	/* For 518 and 518+ */
-	static struct ov_regvals init_518[] = {
+	const struct ov_regvals init_518[] = {
 		{ R51x_SYS_RESET,	0x40 },
 		{ R51x_SYS_INIT,	0xe1 },
 		{ R51x_SYS_RESET,	0x3e },
@@ -1874,7 +1874,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
 		{ 0x5d,			0x03 },
 	};
 
-	static struct ov_regvals norm_518[] = {
+	const struct ov_regvals norm_518[] = {
 		{ R51x_SYS_SNAP,	0x02 }, /* Reset */
 		{ R51x_SYS_SNAP,	0x01 }, /* Enable */
 		{ 0x31, 		0x0f },
@@ -1887,7 +1887,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
 		{ 0x2f,			0x80 },
 	};
 
-	static struct ov_regvals norm_518_p[] = {
+	const struct ov_regvals norm_518_p[] = {
 		{ R51x_SYS_SNAP,	0x02 }, /* Reset */
 		{ R51x_SYS_SNAP,	0x01 }, /* Enable */
 		{ 0x31, 		0x0f },
-- 
cgit v1.2.3-70-g09d2


From 9764398bdeef49414b37ef8bd35abfec1f44bd3e Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 05:08:11 -0300
Subject: V4L/DVB (12086): gspca_sonixj: Fix control index numbering

The control index defines for the gspca_sonixj driver were numbered
wrong, causing us to disable the wrong controls on various sensors

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index dc6a6f11354..9e31d1bbc67 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -98,6 +98,7 @@ static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
+#define BRIGHTNESS_IDX 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -113,6 +114,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
+#define CONTRAST_IDX 1
 	{
 	    {
 		.id      = V4L2_CID_CONTRAST,
@@ -128,6 +130,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
+#define COLOR_IDX 2
 	{
 	    {
 		.id      = V4L2_CID_SATURATION,
@@ -142,6 +145,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setcolors,
 	    .get = sd_getcolors,
 	},
+#define BLUE_BALANCE_IDX 3
 	{
 	    {
 		.id      = V4L2_CID_BLUE_BALANCE,
@@ -156,6 +160,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setblue_balance,
 	    .get = sd_getblue_balance,
 	},
+#define RED_BALANCE_IDX 4
 	{
 	    {
 		.id      = V4L2_CID_RED_BALANCE,
@@ -170,6 +175,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setred_balance,
 	    .get = sd_getred_balance,
 	},
+#define GAMMA_IDX 5
 	{
 	    {
 		.id      = V4L2_CID_GAMMA,
@@ -184,7 +190,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setgamma,
 	    .get = sd_getgamma,
 	},
-#define AUTOGAIN_IDX 5
+#define AUTOGAIN_IDX 6
 	{
 	    {
 		.id      = V4L2_CID_AUTOGAIN,
@@ -200,7 +206,7 @@ static struct ctrl sd_ctrls[] = {
 	    .get = sd_getautogain,
 	},
 /* ov7630/ov7648 only */
-#define VFLIP_IDX 6
+#define VFLIP_IDX 7
 	{
 	    {
 		.id      = V4L2_CID_VFLIP,
@@ -216,7 +222,7 @@ static struct ctrl sd_ctrls[] = {
 	    .get = sd_getvflip,
 	},
 /* mt9v111 only */
-#define INFRARED_IDX 7
+#define INFRARED_IDX 8
 	{
 	    {
 		.id      = V4L2_CID_INFRARED,
-- 
cgit v1.2.3-70-g09d2


From cc7b5b573feb5edfe68c028bc1ea383dab37dde2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 05:14:42 -0300
Subject: V4L/DVB (12087): gspca_sonixj: enable support for 0c45:613e camera

gspca_sonixj: enable support for 0c45:613e camera, and slightly tweak
the ov7630 register init values for a much better picture.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 9e31d1bbc67..184bb924f45 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -610,7 +610,9 @@ static const u8 ov7630_sensor_init[][8] = {
 /* win: i2c_r from 00 to 80 */
 	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
 	{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
-	{0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
+/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
+	0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
+	{0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
 	{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
 	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
 	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
@@ -644,7 +646,6 @@ static const u8 ov7630_sensor_init[][8] = {
 	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
 /* */
-	{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
 /* */
@@ -2239,7 +2240,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
 #endif
 	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
-/*	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
 	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
 	{}
 };
-- 
cgit v1.2.3-70-g09d2


From 119893b2dfb18515bfdcc5edb83422e6aa126a86 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 05:20:51 -0300
Subject: V4L/DVB (12088): Mark the v4l1 uvcvideo quickcam messenger driver as
 deprecated

Mark the v4l1 uvcvideo quickcam messenger driver as deprecated, the one
cam it supports, is now also supported by the v4l2 gspca stv06xx driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/usbvideo/Kconfig | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
index e4cb99c1f94..adb1c044ad7 100644
--- a/drivers/media/video/usbvideo/Kconfig
+++ b/drivers/media/video/usbvideo/Kconfig
@@ -38,10 +38,13 @@ config USB_KONICAWC
 	  module will be called konicawc.
 
 config USB_QUICKCAM_MESSENGER
-	tristate "USB Logitech Quickcam Messenger"
+	tristate "USB Logitech Quickcam Messenger (DEPRECATED)"
 	depends on VIDEO_V4L1
 	select VIDEO_USBVIDEO
 	---help---
+	  This driver is DEPRECATED please use the gspca stv06xx module
+	  instead.
+
 	  Say Y or M here to enable support for the USB Logitech Quickcam
 	  Messenger webcam.
 
-- 
cgit v1.2.3-70-g09d2


From a5d1cc39fee739cf4fc2a1f43da812c50de9d3d6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 06:03:20 -0300
Subject: V4L/DVB (12089): gspca_sonixj: increase 640x480 frame-buffersize

gspca_sonixj: increase 640x480 frame-buffersize, as I was getting buffer
overflows during my testing of a "Premier" 0c45:613e cam

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 184bb924f45..46988120ec6 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -274,7 +274,8 @@ static const struct v4l2_pix_format vga_mode[] = {
 		.priv = 1},
 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 640,
-		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
+		.sizeimage = 640 * 480 * 3 / 4 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
 };
-- 
cgit v1.2.3-70-g09d2


From 1fec747cd389b4812a9932a1416d76e8a53596b2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 06:05:07 -0300
Subject: V4L/DVB (12090): gspca_sonixj: enable autogain control for the ov7620

gspca_sonixj: enable autogain control for the ov7620, and not only
make it enable autogain but also auto exposure (and do the
same for the ov7648).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 46988120ec6..6f475b471fb 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -251,7 +251,7 @@ static __u32 ctrl_dis[] = {
 						/* SENSOR_MT9V111 3 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_OM6802 4 */
-	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
+	(1 << INFRARED_IDX),
 						/* SENSOR_OV7630 5 */
 	(1 << INFRARED_IDX),
 						/* SENSOR_OV7648 6 */
@@ -1577,7 +1577,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
 		else
 			comb = 0xa0;
 		if (sd->autogain)
-			comb |= 0x02;
+			comb |= 0x03;
 		i2c_w1(&sd->gspca_dev, 0x13, comb);
 		return;
 	    }
-- 
cgit v1.2.3-70-g09d2


From 37c6dbe290c05023b47f52528e30ce51336b93eb Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 07:35:36 -0300
Subject: V4L/DVB (12091): gspca_sonixj: Add light frequency control

gspca_sonixj: Add light frequency control

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 133 ++++++++++++++++++++++++++++++++++---
 1 file changed, 123 insertions(+), 10 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 6f475b471fb..7daa60299c0 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -46,6 +46,7 @@ struct sd {
 	u8 gamma;
 	u8 vflip;			/* ov7630/ov7648 only */
 	u8 infrared;			/* mt9v111 only */
+	u8 freq;			/* ov76xx only */
 	u8 quality;			/* image quality */
 #define QUALITY_MIN 60
 #define QUALITY_MAX 95
@@ -96,6 +97,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getinfrared(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 struct ctrl sd_ctrls[] = {
 #define BRIGHTNESS_IDX 0
@@ -237,19 +240,35 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setinfrared,
 	    .get = sd_getinfrared,
 	},
+/* ov7630/ov7648/ov7660 only */
+#define FREQ_IDX 9
+	{
+	    {
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+		.step    = 1,
+#define FREQ_DEF 2
+		.default_value = FREQ_DEF,
+	    },
+	    .set = sd_setfreq,
+	    .get = sd_getfreq,
+	},
 };
 
 /* table of the disabled controls */
 static __u32 ctrl_dis[] = {
-	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 						/* SENSOR_HV7131R 0 */
-	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 						/* SENSOR_MI0360 1 */
-	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 						/* SENSOR_MO4000 2 */
-	(1 << VFLIP_IDX),
+	(1 << VFLIP_IDX) | (1 << FREQ_IDX),
 						/* SENSOR_MT9V111 3 */
-	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 						/* SENSOR_OM6802 4 */
 	(1 << INFRARED_IDX),
 						/* SENSOR_OV7630 5 */
@@ -257,8 +276,8 @@ static __u32 ctrl_dis[] = {
 						/* SENSOR_OV7648 6 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_OV7660 7 */
-	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
-						/* SENSOR_SP80708 8 */
+	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
+			      (1 << FREQ_IDX),	/* SENSOR_SP80708 8 */
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -647,8 +666,8 @@ static const u8 ov7630_sensor_init[][8] = {
 	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
 /* */
-	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
-	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
+/*	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
+/*	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
 /* */
 	{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
 /*	{0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
@@ -681,7 +700,7 @@ static const u8 ov7648_sensor_init[][8] = {
 	{0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
 /*	{0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
 /*	{0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
-	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
+/*	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
 /*...*/
 /*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
 /*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
@@ -1307,6 +1326,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	else
 		sd->vflip = 1;
 	sd->infrared = INFRARED_DEF;
+	sd->freq = FREQ_DEF;
 	sd->quality = QUALITY_DEF;
 	sd->jpegqual = 80;
 
@@ -1610,6 +1630,58 @@ static void setinfrared(struct sd *sd)
 		sd->infrared ? 0x66 : 0x64);
 }
 
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor == SENSOR_OV7660) {
+		switch (sd->freq) {
+		case 0: /* Banding filter disabled */
+			i2c_w1(gspca_dev, 0x13, 0xdf);
+			break;
+		case 1: /* 50 hz */
+			i2c_w1(gspca_dev, 0x13, 0xff);
+			i2c_w1(gspca_dev, 0x3b, 0x0a);
+			break;
+		case 2: /* 60 hz */
+			i2c_w1(gspca_dev, 0x13, 0xff);
+			i2c_w1(gspca_dev, 0x3b, 0x02);
+			break;
+		}
+	} else {
+		u8 reg2a = 0, reg2b = 0, reg2d = 0;
+
+		/* Get reg2a / reg2d base values */
+		switch (sd->sensor) {
+		case SENSOR_OV7630:
+			reg2a = 0x08;
+			reg2d = 0x01;
+			break;
+		case SENSOR_OV7648:
+			reg2a = 0x11;
+			reg2d = 0x81;
+			break;
+		}
+
+		switch (sd->freq) {
+		case 0: /* Banding filter disabled */
+			break;
+		case 1: /* 50 hz (filter on and framerate adj) */
+			reg2a |= 0x80;
+			reg2b = 0xac;
+			reg2d |= 0x04;
+			break;
+		case 2: /* 60 hz (filter on, no framerate adj) */
+			reg2a |= 0x80;
+			reg2d |= 0x04;
+			break;
+		}
+		i2c_w1(gspca_dev, 0x2a, reg2a);
+		i2c_w1(gspca_dev, 0x2b, reg2b);
+		i2c_w1(gspca_dev, 0x2d, reg2d);
+	}
+}
+
 static void setjpegqual(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1836,6 +1908,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	setbrightness(gspca_dev);
 	setcontrast(gspca_dev);
 	setautogain(gspca_dev);
+	setfreq(gspca_dev);
 	return 0;
 }
 
@@ -2139,6 +2212,24 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
 	return 0;
 }
 
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->freq = val;
+	if (gspca_dev->streaming)
+		setfreq(gspca_dev);
+	return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->freq;
+	return 0;
+}
+
 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
 			struct v4l2_jpegcompression *jcomp)
 {
@@ -2167,6 +2258,27 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 	return 0;
 }
 
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -2181,6 +2293,7 @@ static const struct sd_desc sd_desc = {
 	.dq_callback = do_autogain,
 	.get_jcomp = sd_get_jcomp,
 	.set_jcomp = sd_set_jcomp,
+	.querymenu = sd_querymenu,
 };
 
 /* -- module initialisation -- */
-- 
cgit v1.2.3-70-g09d2


From f800952c21157f11a5510d9cf700c9a7ba30800d Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 14:29:20 -0300
Subject: V4L/DVB (12092): gspca_sonixj + ov7630: invert vflip control instead
 of changing default

gspca_sonixj + ov7630 had the default value for flip enabled, as otherwise
the picture is upside down. It is better to instead invert the meaning
of the control in the set function, and have the default be no vflip,
as one would expect vflip enabled to be upside down.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 7daa60299c0..46ec24e4045 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -218,7 +218,7 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 1,
 		.step    = 1,
-#define VFLIP_DEF 0			/* vflip def = 1 for ov7630 */
+#define VFLIP_DEF 0
 		.default_value = VFLIP_DEF,
 	    },
 	    .set = sd_setvflip,
@@ -1321,10 +1321,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->gamma = GAMMA_DEF;
 	sd->autogain = AUTOGAIN_DEF;
 	sd->ag_cnt = -1;
-	if (sd->sensor != SENSOR_OV7630)
-		sd->vflip = 0;
-	else
-		sd->vflip = 1;
+	sd->vflip = VFLIP_DEF;
 	sd->infrared = INFRARED_DEF;
 	sd->freq = FREQ_DEF;
 	sd->quality = QUALITY_DEF;
@@ -1613,12 +1610,15 @@ static void setvflip(struct sd *sd)
 {
 	u8 comn;
 
-	if (sd->sensor == SENSOR_OV7630)
+	if (sd->sensor == SENSOR_OV7630) {
 		comn = 0x02;
-	else
+		if (!sd->vflip)
+			comn |= 0x80;
+	} else {
 		comn = 0x06;
-	if (sd->vflip)
-		comn |= 0x80;
+		if (sd->vflip)
+			comn |= 0x80;
+	}
 	i2c_w1(&sd->gspca_dev, 0x75, comn);
 }
 
-- 
cgit v1.2.3-70-g09d2


From 3fb4a57b494e05dba4d1305e2347c6633b76c20e Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 18 Jun 2009 14:31:36 -0300
Subject: V4L/DVB (12093): gspca_sonixj: Name saturation control saturation,
 not color

Name saturation control saturation, not color and make the default
less saturated (the old default was overdoing it).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/gspca/sonixj.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 46ec24e4045..0d02f41fa7d 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -138,11 +138,11 @@ static struct ctrl sd_ctrls[] = {
 	    {
 		.id      = V4L2_CID_SATURATION,
 		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Color",
+		.name    = "Saturation",
 		.minimum = 0,
 		.maximum = 40,
 		.step    = 1,
-#define COLOR_DEF 32
+#define COLOR_DEF 25
 		.default_value = COLOR_DEF,
 	    },
 	    .set = sd_setcolors,
-- 
cgit v1.2.3-70-g09d2


From 0cde9b2533d6fe79307173f24209228aaf34bc98 Mon Sep 17 00:00:00 2001
From: "Igor M. Liplianin" <liplianin@netup.ru>
Date: Sun, 14 Jun 2009 13:17:15 -0300
Subject: V4L/DVB (12095): Change lnbh24 configure bits for NetUP card.

Signed-off-by: Igor M. Liplianin <liplianin@netup.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index e236df23370..236eea0c41e 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -736,7 +736,8 @@ static int dvb_register(struct cx23885_tsport *port)
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL, 0, 0x09))
+							LNBH24_PCL,
+							LNBH24_TTX, 0x09))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
@@ -756,7 +757,8 @@ static int dvb_register(struct cx23885_tsport *port)
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL, 0, 0x0a))
+							LNBH24_PCL,
+							LNBH24_TTX, 0x0a))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
-- 
cgit v1.2.3-70-g09d2


From f867c3f4eab1d5006df4f3734fab1134feffbeba Mon Sep 17 00:00:00 2001
From: "Igor M. Liplianin" <liplianin@netup.ru>
Date: Fri, 19 Jun 2009 05:45:23 -0300
Subject: V4L/DVB (12098): Create table for customize stv0900 ts registers.

Signed-off-by: Igor M. Liplianin <liplianin@netup.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/dvb/frontends/stv0900.h      |  7 ++++++-
 drivers/media/dvb/frontends/stv0900_core.c | 21 +++++++++++++++++++--
 drivers/media/dvb/frontends/stv0900_priv.h |  2 ++
 drivers/media/video/cx23885/cx23885-dvb.c  | 17 +++++++++++++++--
 4 files changed, 42 insertions(+), 5 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index 8a1332c2031..bf4e9b63304 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -29,6 +29,11 @@
 #include <linux/dvb/frontend.h>
 #include "dvb_frontend.h"
 
+struct stv0900_reg {
+	u16 addr;
+	u8  val;
+};
+
 struct stv0900_config {
 	u8 demod_address;
 	u32 xtal;
@@ -38,7 +43,7 @@ struct stv0900_config {
 
 	u8 path1_mode;
 	u8 path2_mode;
-
+	struct stv0900_reg *ts_config_regs;
 	u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
 	u8 tun2_maddress;
 	u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 9ab4f301467..1da045fbb4e 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -1393,7 +1393,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
 	struct stv0900_state *state = fe->demodulator_priv;
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	enum fe_stv0900_error demodError = STV0900_NO_ERROR;
-	int selosci;
+	int selosci, i;
 
 	struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
 						state->config->demod_address);
@@ -1440,7 +1440,23 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
 				stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
 				stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
 
-				stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
+				state->internal->ts_config = p_init->ts_config;
+				if (state->internal->ts_config == NULL)
+					stv0900_set_ts_parallel_serial(state->internal,
+							p_init->path1_ts_clock,
+							p_init->path2_ts_clock);
+				else {
+					for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++)
+						stv0900_write_reg(state->internal,
+								state->internal->ts_config[i].addr,
+								state->internal->ts_config[i].val);
+
+					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1);
+					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0);
+					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1);
+					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0);
+				}
+
 				stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
 				switch (p_init->tuner1_adc) {
 				case 1:
@@ -1954,6 +1970,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
 		init_params.tun1_iq_inversion	= STV0900_IQ_NORMAL;
 		init_params.tuner1_adc		= config->tun1_adc;
 		init_params.path2_ts_clock	= config->path2_mode;
+		init_params.ts_config		= config->ts_config_regs;
 		init_params.tun2_maddress	= config->tun2_maddress;
 		init_params.tuner2_adc		= config->tun2_adc;
 		init_params.tun2_iq_inversion	= STV0900_IQ_SWAPPED;
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index 67dc8ec634e..5ed7a145c7d 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -271,6 +271,7 @@ struct stv0900_init_params{
 
 	/* IQ from the tuner2 to the demod */
 	enum stv0900_iq_inversion	tun2_iq_inversion;
+	struct stv0900_reg		*ts_config;
 };
 
 struct stv0900_search_params {
@@ -363,6 +364,7 @@ struct stv0900_internal{
 	u8			i2c_addr;
 	u8			clkmode;/* 0 for CLKI, 2 for XTALI */
 	u8			chip_id;
+	struct stv0900_reg	*ts_config;
 	enum fe_stv0900_error	errs;
 	int dmds_used;
 };
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 236eea0c41e..48de57b61f6 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -45,6 +45,7 @@
 #include "dibx000_common.h"
 #include "zl10353.h"
 #include "stv0900.h"
+#include "stv0900_reg.h"
 #include "stv6110.h"
 #include "lnbh24.h"
 #include "cx24116.h"
@@ -370,13 +371,25 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
 	.disable_i2c_gate_ctrl = 1,
 };
 
+static struct stv0900_reg stv0900_ts_regs[] = {
+	{ R0900_TSGENERAL, 0x00 },
+	{ R0900_P1_TSSPEED, 0x40 },
+	{ R0900_P2_TSSPEED, 0x40 },
+	{ R0900_P1_TSCFGM, 0xc0 },
+	{ R0900_P2_TSCFGM, 0xc0 },
+	{ R0900_P1_TSCFGH, 0xe0 },
+	{ R0900_P2_TSCFGH, 0xe0 },
+	{ R0900_P1_TSCFGL, 0x20 },
+	{ R0900_P2_TSCFGL, 0x20 },
+	{ 0xffff, 0xff }, /* terminate */
+};
+
 static struct stv0900_config netup_stv0900_config = {
 	.demod_address = 0x68,
 	.xtal = 27000000,
 	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
 	.diseqc_mode = 2,/* 2/3 PWM */
-	.path1_mode = 2,/*Serial continues clock */
-	.path2_mode = 2,/*Serial continues clock */
+	.ts_config_regs = stv0900_ts_regs,
 	.tun1_maddress = 0,/* 0x60 */
 	.tun2_maddress = 3,/* 0x63 */
 	.tun1_adc = 1,/* 1 Vpp */
-- 
cgit v1.2.3-70-g09d2


From cdf7bfa8926fb26d5900103ae09eb5f3eddb95cc Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Fri, 19 Jun 2009 00:20:28 -0300
Subject: V4L/DVB (12100): em28xx: make sure the analog GPIOs are set if we
 used a card hint

In cases where the board had a default USB ID, we would not indentify the
board until after the call to em28xx_set_mode().  As a result, for those
boards the analog GPIOs were not being set before probing the i2c bus for
devices (the probe would occur with the GPIOs being all high).

Make a call to em28xx_set_mode() so that the GPIOs are set properly before
probing the i2c bus for devices.

This problem was detected with the EVGA inDtube, where the tvp5150 is not
powered on unless GPIO1 is pulled low.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-cards.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 00cc791a9e4..0b6e5c7c346 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2101,6 +2101,12 @@ void em28xx_card_setup(struct em28xx *dev)
 	case EM2880_BOARD_MSI_DIGIVOX_AD:
 		if (!em28xx_hint_board(dev))
 			em28xx_set_model(dev);
+
+		/* In cases where we had to use a board hint, the call to
+		   em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
+		   so make the call now so the analog GPIOs are set properly
+		   before probing the i2c bus. */
+		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
 		break;
 	}
 
-- 
cgit v1.2.3-70-g09d2


From 19859229d7d98bc2d582ff45045dd7f73d649383 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Fri, 19 Jun 2009 00:33:54 -0300
Subject: V4L/DVB (12101): em28xx: add support for EVGA inDtube

Add support for the EVGA inDtube.  Both ATSC and analog side validated as
fully functional.

Thanks to Jake Crimmins from EVGA for providing the correct GPIO info.
Thanks to Alan Hagge for doing all the device testing.
Thanks to Greg Williamson for providing hardware for testing.

Cc: Jake Crimmins <jcrimmins@evga.com>
Cc: Alan Hagge <ahagge@gmail.com>
Cc: Greg Williamson <cheeseboy16@gmail.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 Documentation/video4linux/CARDLIST.em28xx |  1 +
 drivers/media/video/em28xx/em28xx-cards.c | 48 +++++++++++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx-dvb.c   |  1 +
 drivers/media/video/em28xx/em28xx.h       |  1 +
 4 files changed, 51 insertions(+)

(limited to 'drivers/media/video')

diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index a98a688c11b..873630e7e53 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -65,3 +65,4 @@
  67 -> Terratec Grabby                          (em2860)        [0ccd:0096]
  68 -> Terratec AV350                           (em2860)        [0ccd:0084]
  69 -> KWorld ATSC 315U HDTV TV Box             (em2882)        [eb1a:a313]
+ 70 -> Evga inDtube                             (em2882)
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 0b6e5c7c346..972c4addc40 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -139,6 +139,24 @@ static struct em28xx_reg_seq kworld_330u_digital[] = {
 	{ -1,			-1,	-1,		-1},
 };
 
+/* Evga inDtube
+   GPIO0 - Enable digital power (s5h1409) - low to enable
+   GPIO1 - Enable analog power (tvp5150/emp202) - low to enable
+   GPIO4 - xc3028 reset
+   GOP3  - s5h1409 reset
+ */
+static struct em28xx_reg_seq evga_indtube_analog[] = {
+	{EM28XX_R08_GPIO,	0x79,   0xff,		60},
+	{	-1,		-1,	-1,		-1},
+};
+
+static struct em28xx_reg_seq evga_indtube_digital[] = {
+	{EM28XX_R08_GPIO,	0x7a,	0xff,		 1},
+	{EM2880_R04_GPO,	0x04,	0xff,		10},
+	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
+	{ -1,			-1,	-1,		-1},
+};
+
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
 	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
@@ -1449,6 +1467,31 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = terratec_av350_unmute_gpio,
 		} },
 	},
+	[EM2882_BOARD_EVGA_INDTUBE] = {
+		.name         = "Evga inDtube",
+		.tuner_type   = TUNER_XC2028,
+		.tuner_gpio   = default_tuner_gpio,
+		.decoder      = EM28XX_TVP5150,
+		.mts_firmware = 1,
+		.has_dvb      = 1,
+		.dvb_gpio     = evga_indtube_digital,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO,
+			.gpio     = evga_indtube_analog,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = evga_indtube_analog,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = evga_indtube_analog,
+		} },
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1571,6 +1614,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
 	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
 	{0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
+	{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
 };
 
 /* I2C devicelist hash table for devices with generic USB IDs */
@@ -1834,6 +1878,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
 		ctl->demod = XC3028_FE_CHINA;
 		ctl->fname = XC2028_DEFAULT_FIRMWARE;
 		break;
+	case EM2882_BOARD_EVGA_INDTUBE:
+		ctl->demod = XC3028_FE_CHINA;
+		ctl->fname = XC3028L_DEFAULT_FIRMWARE;
+		break;
 	default:
 		ctl->demod = XC3028_FE_OREN538;
 	}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 563dd2b1c8e..e7b47c8da8f 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -445,6 +445,7 @@ static int dvb_init(struct em28xx *dev)
 		}
 		break;
 	case EM2883_BOARD_KWORLD_HYBRID_330U:
+	case EM2882_BOARD_EVGA_INDTUBE:
 		dvb->frontend = dvb_attach(s5h1409_attach,
 					   &em28xx_s5h1409_with_xc3028,
 					   &dev->i2c_adap);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 8bf81be1da6..813ce45c2f9 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -106,6 +106,7 @@
 #define EM2860_BOARD_TERRATEC_GRABBY		  67
 #define EM2860_BOARD_TERRATEC_AV350		  68
 #define EM2882_BOARD_KWORLD_ATSC_315U		  69
+#define EM2882_BOARD_EVGA_INDTUBE		  70
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
-- 
cgit v1.2.3-70-g09d2


From a4c473033b6a100773a4fd8b7ba1e45baeb1e692 Mon Sep 17 00:00:00 2001
From: Devin Heitmueller <dheitmueller@kernellabs.com>
Date: Sat, 20 Jun 2009 21:34:42 -0300
Subject: V4L/DVB (12102): em28xx: add Remote control support for EVGA inDtube

Add an IR profile for the EVGA inDtube remote control (which is an NEC type
remote)

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/common/ir-keymaps.c         | 23 +++++++++++++++++++++++
 drivers/media/video/em28xx/em28xx-cards.c |  2 ++
 include/media/ir-common.h                 |  2 ++
 3 files changed, 27 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 3fe158ac7bb..4216328552f 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -2750,3 +2750,26 @@ IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
 	[0x1b] = KEY_B,		/*recall*/
 };
 EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
+
+/* EVGA inDtube
+   Devin Heitmueller <devin.heitmueller@gmail.com>
+ */
+IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = {
+	[0x12] = KEY_POWER,
+	[0x02] = KEY_MODE,	/* TV */
+	[0x14] = KEY_MUTE,
+	[0x1a] = KEY_CHANNELUP,
+	[0x16] = KEY_TV2,	/* PIP */
+	[0x1d] = KEY_VOLUMEUP,
+	[0x05] = KEY_CHANNELDOWN,
+	[0x0f] = KEY_PLAYPAUSE,
+	[0x19] = KEY_VOLUMEDOWN,
+	[0x1c] = KEY_REWIND,
+	[0x0d] = KEY_RECORD,
+	[0x18] = KEY_FORWARD,
+	[0x1e] = KEY_PREVIOUS,
+	[0x1b] = KEY_STOP,
+	[0x1f] = KEY_NEXT,
+	[0x13] = KEY_CAMERA,
+};
+EXPORT_SYMBOL_GPL(ir_codes_evga_indtube);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 972c4addc40..c43fdb9bc88 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1472,9 +1472,11 @@ struct em28xx_board em28xx_boards[] = {
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.decoder      = EM28XX_TVP5150,
+		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
 		.mts_firmware = 1,
 		.has_dvb      = 1,
 		.dvb_gpio     = evga_indtube_digital,
+		.ir_codes     = ir_codes_evga_indtube,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 7b5b91f6042..9dcb632f608 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -162,6 +162,8 @@ extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE];
+
 #endif
 
 /*
-- 
cgit v1.2.3-70-g09d2


From c6711c3e6d4976716633047c0f6bbd953d6831fb Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sun, 14 Jun 2009 05:20:21 -0300
Subject: V4L/DVB (12104): ivtv/cx18: fix regression: class controls are no
 longer seen

A previous change (v4l2-common: remove v4l2_ctrl_query_fill_std) broke
the handling of class controls in VIDIOC_QUERYCTRL. The MPEG class control
was broken for all drivers that use the cx2341x module and the USER class
control was broken for ivtv and cx18.

This change adds back proper class control support.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx18/cx18-controls.c | 2 ++
 drivers/media/video/cx2341x.c            | 2 ++
 drivers/media/video/ivtv/ivtv-controls.c | 2 ++
 3 files changed, 6 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 8e35c3aed54..5136df19833 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -61,6 +61,8 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
 
 	switch (qctrl->id) {
 	/* Standard V4L2 controls */
+	case V4L2_CID_USER_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_BRIGHTNESS:
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 8ded5294633..4c8e95853fa 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -500,6 +500,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
 	int err;
 
 	switch (qctrl->id) {
+	case V4L2_CID_MPEG_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_MPEG_STREAM_TYPE:
 		return v4l2_ctrl_query_fill(qctrl,
 				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 84995bcf4a7..a3b77ed3f08 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -60,6 +60,8 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
 
 	switch (qctrl->id) {
 	/* Standard V4L2 controls */
+	case V4L2_CID_USER_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_BRIGHTNESS:
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
-- 
cgit v1.2.3-70-g09d2


From 54bb501c069bbe34cf8becf0a9985fc6873d6b21 Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 20 Jun 2009 09:18:34 -0300
Subject: V4L/DVB (12111): tcm825x: remove incorrect __exit_p wrapper

tcm825x_remove is not necessarily called on module exit, it can also be
called when the i2c_adapter is removed. While the i2c adapter might never
be removed on an embedded system, in practice this sensor driver can also
be used in e.g. a USB webcam where this is a perfectly acceptable thing
to do.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/tcm825x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index b30c4924821..b90e9da3167 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -878,7 +878,7 @@ static int tcm825x_probe(struct i2c_client *client,
 	return rval;
 }
 
-static int __exit tcm825x_remove(struct i2c_client *client)
+static int tcm825x_remove(struct i2c_client *client)
 {
 	struct tcm825x_sensor *sensor = i2c_get_clientdata(client);
 
@@ -902,7 +902,7 @@ static struct i2c_driver tcm825x_i2c_driver = {
 		.name = TCM825X_NAME,
 	},
 	.probe	= tcm825x_probe,
-	.remove	= __exit_p(tcm825x_remove),
+	.remove	= tcm825x_remove,
 	.id_table = tcm825x_id,
 };
 
-- 
cgit v1.2.3-70-g09d2


From aad40d3d0cd9b679e83f6a902ad1e2b8f7b4c9bb Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Sat, 20 Jun 2009 09:21:37 -0300
Subject: V4L/DVB (12112): cx231xx: fix uninitialized variable.

The variable 'rc' could be used uninitialized in the cx231xx_capture_start
function. Sri informed me that it should be initialized to -1.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-avcore.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 6a9464079b4..96f07d1473f 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -2055,7 +2055,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
 
 int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
 {
-	int rc;
+	int rc = -1;
 	u32 ep_mask = -1;
 	struct pcb_config *pcb_config;
 
-- 
cgit v1.2.3-70-g09d2


From b34cdc36c4aad10cf4eaadacf067835d6a622f1b Mon Sep 17 00:00:00 2001
From: Michael Krufky <mkrufky@kernellabs.com>
Date: Thu, 21 May 2009 12:49:28 -0300
Subject: V4L/DVB (12116): cx23885: ensure correct IF freq is used on HVR1200 &
 HVR1700

Ensure that we're programming the tda18271 tuner with the correct
IF frequencies to match the programming of the TDA10048 DVB-T demod
for the HVR1200 and HVR1700 products.

Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-dvb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 48de57b61f6..48a975134ac 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -243,12 +243,22 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
 		      .if_lvl = 6, .rfagc_top = 0x37 },
 };
 
+static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
+	.dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+};
+
 static struct tda18271_config hauppauge_tda18271_config = {
 	.std_map = &hauppauge_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
 static struct tda18271_config hauppauge_hvr1200_tuner_config = {
+	.std_map = &hauppauge_hvr1200_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
-- 
cgit v1.2.3-70-g09d2


From e17d787c513f41f59969247062561fff6340f211 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 20 Jun 2009 14:45:52 -0300
Subject: V4L/DVB (12118): pvrusb2: Fix hardware scaling when used with cx25840

The cx25840 module requires that its VBI initialization entry point be
called in order for hardware-scaled video capture to work properly -
even if we don't care about VBI.  Making this behavior even more
subtle is that if the capture resolution is set to 720x480 - which is
the default that the pvrusb2 driver sets up - then the cx25840
bypasses the hardware scaler.  Therefore this problem does not
manifest itself until some other resolution, e.g. 640x480, is tried.
MythTV typically defaults to 640x480 or 480x480, which means that
things break whenever the driver is used with MythTV.

This all has been known for a while (since at least Nov 2006), but
recent changes in the pvrusb2 driver (specifically in regards to
sub-device support) caused this to break again.  VBI initialization
must happen *after* the chip's firmware is loaded, not before.  With
this fix, 24xxx devices work correctly again.

A related fix that is part of this changeset is that now we
re-initialize VBI any time after we issue a reset to the cx25840
driver.  Issuing a chip reset erases the state that the VBI setup
previously did.  Until the HVR-1950 came along this subtlety went
unnoticed, because the pvrusb2 driver previously never issued such a
reset.  But with the HVR-1950 we have to do that reset in order to
correctly transition from digital back to analog mode - and since the
HVR-1950 always starts in digital mode (required for the DVB side to
initialize correctly) then this device has never had a chance to work
correctly in analog mode!  Analog capture on the HVR-1950 has been
broken this *ENTIRE* time.  I had missed it until now because I've
usually been testing at the default 720x480 resolution which does not
require scaling...  What fun.  By re-initializing VBI after a cx25840
chip reset, correct behavior is restored.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-hdw.c | 55 +++++++++++++++++--------------
 1 file changed, 31 insertions(+), 24 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 0c745b142fb..e97f8e0e466 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1987,6 +1987,34 @@ static unsigned int pvr2_copy_i2c_addr_list(
 }
 
 
+static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
+{
+	/*
+	  Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness
+	  for cx25840 causes that module to correctly set up its video
+	  scaling.  This is really a problem in the cx25840 module itself,
+	  but we work around it here.  The problem has not been seen in
+	  ivtv because there VBI is supported and set up.  We don't do VBI
+	  here (at least not yet) and thus we never attempted to even set
+	  it up.
+	*/
+	struct v4l2_format fmt;
+	if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) {
+		/* We're not using a cx25840 so don't enable the hack */
+		return;
+	}
+
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Module ID %u:"
+		   " Executing cx25840 VBI hack",
+		   hdw->decoder_client_id);
+	memset(&fmt, 0, sizeof(fmt));
+	fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+	v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+			     video, s_fmt, &fmt);
+}
+
+
 static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
 				const struct pvr2_device_client_desc *cd)
 {
@@ -2078,30 +2106,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
 	/* client-specific setup... */
 	switch (mid) {
 	case PVR2_CLIENT_ID_CX25840:
-		hdw->decoder_client_id = mid;
-		{
-			/*
-			  Mike Isely <isely@pobox.com> 19-Nov-2006 - This
-			  bit of nuttiness for cx25840 causes that module
-			  to correctly set up its video scaling.  This is
-			  really a problem in the cx25840 module itself,
-			  but we work around it here.  The problem has not
-			  been seen in ivtv because there VBI is supported
-			  and set up.  We don't do VBI here (at least not
-			  yet) and thus we never attempted to even set it
-			  up.
-			*/
-			struct v4l2_format fmt;
-			pvr2_trace(PVR2_TRACE_INIT,
-				   "Module ID %u:"
-				   " Executing cx25840 VBI hack",
-				   mid);
-			memset(&fmt, 0, sizeof(fmt));
-			fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
-			v4l2_device_call_all(&hdw->v4l2_dev, mid,
-					     video, s_fmt, &fmt);
-		}
-		break;
 	case PVR2_CLIENT_ID_SAA7115:
 		hdw->decoder_client_id = mid;
 		break;
@@ -2202,6 +2206,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 		cptr->info->set_value(cptr,~0,cptr->info->default_value);
 	}
 
+	pvr2_hdw_cx25840_vbi_hack(hdw);
+
 	/* Set up special default values for the television and radio
 	   frequencies here.  It's not really important what these defaults
 	   are, but I set them to something usable in the Chicago area just
@@ -4076,6 +4082,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 	if (hdw->decoder_client_id) {
 		v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
 				     core, reset, 0);
+		pvr2_hdw_cx25840_vbi_hack(hdw);
 		return 0;
 	}
 	pvr2_trace(PVR2_TRACE_INIT,
-- 
cgit v1.2.3-70-g09d2


From a6862da2f3c7ce3ec6644958bc8937b630b9e2c1 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 20 Jun 2009 14:50:14 -0300
Subject: V4L/DVB (12119): pvrusb2: Re-fix hardware scaling on video standard
 change

The cx25840 module's VBI initialization logic uses the current video
standard as part of its internal algorithm.  This therefore means that
we probably need to make sure that the correct video standard has been
set before initializing VBI.  (Normally we would not care about VBI,
but as described in an earlier changeset, VBI must be initialized
correctly on the cx25840 in order for the chip's hardware scaler to
operate correctly.)

It's kind of messy to force the video standard to be set before
initializing VBI (mainly because we can't know what the app really
wants that early in the initialization process).  So this patch does
the next best thing: VBI is re-initialized after any point where the
video standard has been set.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index e97f8e0e466..44da3f9b5b6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2960,6 +2960,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
 			vs = hdw->std_mask_cur;
 			v4l2_device_call_all(&hdw->v4l2_dev, 0,
 					     core, s_std, vs);
+			pvr2_hdw_cx25840_vbi_hack(hdw);
 		}
 		hdw->tuner_signal_stale = !0;
 		hdw->cropcap_stale = !0;
-- 
cgit v1.2.3-70-g09d2


From 6f441ed78e28ea02940e58ffa89fbbc734ab6da3 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 20 Jun 2009 14:51:29 -0300
Subject: V4L/DVB (12120): pvrusb2: Change initial default frequency setting

Change default frequency to be US Broadcast channel 3 - with the
transition to d igital the previous value has now become useless.
This change is PURELY to help with my testing (I need to set some kind
of default so it might as well be some thing usable).

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-hdw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 44da3f9b5b6..cbc388729d7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -85,8 +85,8 @@ MODULE_PARM_DESC(video_std,"specify initial video standard");
 module_param_array(tolerance,    int, NULL, 0444);
 MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
 
-/* US Broadcast channel 7 (175.25 MHz) */
-static int default_tv_freq    = 175250000L;
+/* US Broadcast channel 3 (61.25 MHz), to help with testing */
+static int default_tv_freq    = 61250000L;
 /* 104.3 MHz, a usable FM station for my area */
 static int default_radio_freq = 104300000L;
 
-- 
cgit v1.2.3-70-g09d2


From 81e804c9c2e38431c1c01165d06076776c6fcbd6 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 20 Jun 2009 14:55:31 -0300
Subject: V4L/DVB (12121): pvrusb2: Improve handling of routing schemes

The pvrusb2 driver has a concept of "routing scheme" which defines
which physical inputs should be connected based on application's
choice of logical input.  The correct "routing scheme" depends on the
specific device since different devices might wire up their muxes

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-audio.c       | 14 +++++++------
 drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c    | 14 +++++++------
 drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 24 +++++++++++++----------
 drivers/media/video/pvrusb2/pvrusb2-video-v4l.c   | 24 +++++++++++++----------
 4 files changed, 44 insertions(+), 32 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 10ef1a2c13e..416933ca607 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -48,11 +48,13 @@ static const int routing_scheme0[] = {
 						MSP_DSP_IN_SCART),
 };
 
-static const struct routing_scheme routing_schemes[] = {
-	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
-		.def = routing_scheme0,
-		.cnt = ARRAY_SIZE(routing_scheme0),
-	},
+static const struct routing_scheme routing_def0 = {
+	.def = routing_scheme0,
+	.cnt = ARRAY_SIZE(routing_scheme0),
+};
+
+static const struct routing_scheme *routing_schemes[] = {
+	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 };
 
 void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
@@ -65,7 +67,7 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
 
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes + sid) != NULL) &&
+		    ((sp = routing_schemes[sid]) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
 			input = sp->def[hdw->input_val];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
index 9023adf3fdc..41f6e009d5e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -49,11 +49,13 @@ static const int routing_scheme1[] = {
 	[PVR2_CVAL_INPUT_SVIDEO] =  0,
 };
 
-static const struct routing_scheme routing_schemes[] = {
-	[PVR2_ROUTING_SCHEME_ONAIR] = {
-		.def = routing_scheme1,
-		.cnt = ARRAY_SIZE(routing_scheme1),
-	},
+static const struct routing_scheme routing_def1 = {
+	.def = routing_scheme1,
+	.cnt = ARRAY_SIZE(routing_scheme1),
+};
+
+static const struct routing_scheme *routing_schemes[] = {
+	[PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
 };
 
 
@@ -66,7 +68,7 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes + sid) != NULL) &&
+		    ((sp = routing_schemes[sid]) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
 			input = sp->def[hdw->input_val];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 05e52358ae4..8710c6218aa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -68,6 +68,11 @@ static const struct routing_scheme_item routing_scheme0[] = {
 	},
 };
 
+static const struct routing_scheme routing_def0 = {
+	.def = routing_scheme0,
+	.cnt = ARRAY_SIZE(routing_scheme0),
+};
+
 /* Specific to gotview device */
 static const struct routing_scheme_item routing_schemegv[] = {
 	[PVR2_CVAL_INPUT_TV] = {
@@ -90,15 +95,14 @@ static const struct routing_scheme_item routing_schemegv[] = {
 	},
 };
 
-static const struct routing_scheme routing_schemes[] = {
-	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
-		.def = routing_scheme0,
-		.cnt = ARRAY_SIZE(routing_scheme0),
-	},
-	[PVR2_ROUTING_SCHEME_GOTVIEW] = {
-		.def = routing_schemegv,
-		.cnt = ARRAY_SIZE(routing_schemegv),
-	},
+static const struct routing_scheme routing_defgv = {
+	.def = routing_schemegv,
+	.cnt = ARRAY_SIZE(routing_schemegv),
+};
+
+static const struct routing_scheme *routing_schemes[] = {
+	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
+	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 };
 
 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
@@ -111,7 +115,7 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
 
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes + sid) != NULL) &&
+		    ((sp = routing_schemes[sid]) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
 			vid_input = sp->def[hdw->input_val].vid;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index d2fe7c8f2c3..8c32288eebe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -54,6 +54,11 @@ static const int routing_scheme0[] = {
 	[PVR2_CVAL_INPUT_SVIDEO] =  SAA7115_SVIDEO2,
 };
 
+static const struct routing_scheme routing_def0 = {
+	.def = routing_scheme0,
+	.cnt = ARRAY_SIZE(routing_scheme0),
+};
+
 static const int routing_scheme1[] = {
 	[PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
 	[PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
@@ -61,15 +66,14 @@ static const int routing_scheme1[] = {
 	[PVR2_CVAL_INPUT_SVIDEO] =  SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
 };
 
-static const struct routing_scheme routing_schemes[] = {
-	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
-		.def = routing_scheme0,
-		.cnt = ARRAY_SIZE(routing_scheme0),
-	},
-	[PVR2_ROUTING_SCHEME_ONAIR] = {
-		.def = routing_scheme1,
-		.cnt = ARRAY_SIZE(routing_scheme1),
-	},
+static const struct routing_scheme routing_def1 = {
+	.def = routing_scheme1,
+	.cnt = ARRAY_SIZE(routing_scheme1),
+};
+
+static const struct routing_scheme *routing_schemes[] = {
+	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
+	[PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
 };
 
 void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
@@ -82,7 +86,7 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
 		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes + sid) != NULL) &&
+		    ((sp = routing_schemes[sid]) != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
 			input = sp->def[hdw->input_val];
-- 
cgit v1.2.3-70-g09d2


From 90135c96869fa0ef3182282b2a661b57fcdb7230 Mon Sep 17 00:00:00 2001
From: Mike Isely <isely@pobox.com>
Date: Sat, 20 Jun 2009 14:57:24 -0300
Subject: V4L/DVB (12122): pvrusb2: De-obfuscate code which handles routing
 schemes

This change does not change any outward behavior; it merely chops down
some large if-conditions with embedded assignments into something a
little more maintainable for others (I of course never had a problem
with this...).

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c    | 12 ++++++------
 drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 15 +++++++--------
 drivers/media/video/pvrusb2/pvrusb2-video-v4l.c   | 13 +++++++------
 3 files changed, 20 insertions(+), 20 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
index 41f6e009d5e..68980e19409 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -67,12 +67,11 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		u32 input;
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
-		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes[sid]) != NULL) &&
-		    (hdw->input_val >= 0) &&
-		    (hdw->input_val < sp->cnt)) {
-			input = sp->def[hdw->input_val];
-		} else {
+		sp = (sid < ARRAY_SIZE(routing_schemes)) ?
+			routing_schemes[sid] : NULL;
+		if ((sp == NULL) ||
+		    (hdw->input_val < 0) ||
+		    (hdw->input_val >= sp->cnt)) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev v4l2 set_input:"
 				   " Invalid routing scheme (%u)"
@@ -80,6 +79,7 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 				   sid, hdw->input_val);
 			return;
 		}
+		input = sp->def[hdw->input_val];
 		sd->ops->audio->s_routing(sd, input, 0, 0);
 	}
 }
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 8710c6218aa..82c13583575 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -114,13 +114,11 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		const struct routing_scheme *sp;
 		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
 
-		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes[sid]) != NULL) &&
-		    (hdw->input_val >= 0) &&
-		    (hdw->input_val < sp->cnt)) {
-			vid_input = sp->def[hdw->input_val].vid;
-			aud_input = sp->def[hdw->input_val].aud;
-		} else {
+		sp = (sid < ARRAY_SIZE(routing_schemes)) ?
+			routing_schemes[sid] : NULL;
+		if ((sp == NULL) ||
+		    (hdw->input_val < 0) ||
+		    (hdw->input_val >= sp->cnt)) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev cx2584x set_input:"
 				   " Invalid routing scheme (%u)"
@@ -128,7 +126,8 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 				   sid, hdw->input_val);
 			return;
 		}
-
+		vid_input = sp->def[hdw->input_val].vid;
+		aud_input = sp->def[hdw->input_val].aud;
 		pvr2_trace(PVR2_TRACE_CHIPS,
 			   "subdev cx2584x set_input vid=0x%x aud=0x%x",
 			   vid_input, aud_input);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 8c32288eebe..4c96cf48c79 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -85,12 +85,12 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
 			   hdw->input_val);
-		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes[sid]) != NULL) &&
-		    (hdw->input_val >= 0) &&
-		    (hdw->input_val < sp->cnt)) {
-			input = sp->def[hdw->input_val];
-		} else {
+
+		sp = (sid < ARRAY_SIZE(routing_schemes)) ?
+			routing_schemes[sid] : NULL;
+		if ((sp == NULL) ||
+		    (hdw->input_val < 0) ||
+		    (hdw->input_val >= sp->cnt)) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "*** WARNING *** subdev v4l2 set_input:"
 				   " Invalid routing scheme (%u)"
@@ -98,6 +98,7 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 				   sid, hdw->input_val);
 			return;
 		}
+		input = sp->def[hdw->input_val];
 		sd->ops->video->s_routing(sd, input, 0, 0);
 	}
 }
-- 
cgit v1.2.3-70-g09d2


From f0222c7d860f09a61bec5e500539f28db0184b38 Mon Sep 17 00:00:00 2001
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Tue, 9 Jun 2009 17:12:33 -0300
Subject: V4L/DVB (12125): v4l2: add new s_config subdev ops and
 v4l2_i2c_new_subdev_cfg/board calls

Add a new s_config core ops call: this is called with the irq and platform
data to be used to initialize the subdev.

Added new v4l2_i2c_new_subdev_cfg and v4l2_i2c_new_subdev_board calls
that allows you to pass these new arguments.

The existing v4l2_i2c_new_subdev functions were modified to also call
s_config.

In the future the existing v4l2_i2c_new_subdev functions will be replaced
by a single v4l2_i2c_new_subdev function similar to v4l2_i2c_new_subdev_cfg
but without the irq and platform_data arguments.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-common.c | 105 ++++++++++++++++++++++++++++++++++++++
 include/media/v4l2-common.h       |  16 ++++++
 include/media/v4l2-subdev.h       |   7 ++-
 3 files changed, 127 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f96475626da..e7b443c116f 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -802,6 +802,17 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
 	/* Decrease the module use count to match the first try_module_get. */
 	module_put(client->driver->driver.owner);
 
+	if (sd) {
+		/* We return errors from v4l2_subdev_call only if we have the
+		   callback as the .s_config is not mandatory */
+		int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
+
+		if (err && err != -ENOIOCTLCMD) {
+			v4l2_device_unregister_subdev(sd);
+			sd = NULL;
+		}
+	}
+
 error:
 	/* If we have a client but no subdev, then something went wrong and
 	   we must unregister the client. */
@@ -852,6 +863,17 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
 	/* Decrease the module use count to match the first try_module_get. */
 	module_put(client->driver->driver.owner);
 
+	if (sd) {
+		/* We return errors from v4l2_subdev_call only if we have the
+		   callback as the .s_config is not mandatory */
+		int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
+
+		if (err && err != -ENOIOCTLCMD) {
+			v4l2_device_unregister_subdev(sd);
+			sd = NULL;
+		}
+	}
+
 error:
 	/* If we have a client but no subdev, then something went wrong and
 	   we must unregister the client. */
@@ -872,6 +894,89 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
 
+/* Load an i2c sub-device. */
+struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter, const char *module_name,
+		struct i2c_board_info *info, const unsigned short *probe_addrs)
+{
+	struct v4l2_subdev *sd = NULL;
+	struct i2c_client *client;
+
+	BUG_ON(!v4l2_dev);
+
+	if (module_name)
+		request_module(module_name);
+
+	/* Create the i2c client */
+	if (info->addr == 0 && probe_addrs)
+		client = i2c_new_probed_device(adapter, info, probe_addrs);
+	else
+		client = i2c_new_device(adapter, info);
+
+	/* Note: by loading the module first we are certain that c->driver
+	   will be set if the driver was found. If the module was not loaded
+	   first, then the i2c core tries to delay-load the module for us,
+	   and then c->driver is still NULL until the module is finally
+	   loaded. This delay-load mechanism doesn't work if other drivers
+	   want to use the i2c device, so explicitly loading the module
+	   is the best alternative. */
+	if (client == NULL || client->driver == NULL)
+		goto error;
+
+	/* Lock the module so we can safely get the v4l2_subdev pointer */
+	if (!try_module_get(client->driver->driver.owner))
+		goto error;
+	sd = i2c_get_clientdata(client);
+
+	/* Register with the v4l2_device which increases the module's
+	   use count as well. */
+	if (v4l2_device_register_subdev(v4l2_dev, sd))
+		sd = NULL;
+	/* Decrease the module use count to match the first try_module_get. */
+	module_put(client->driver->driver.owner);
+
+	if (sd) {
+		/* We return errors from v4l2_subdev_call only if we have the
+		   callback as the .s_config is not mandatory */
+		int err = v4l2_subdev_call(sd, core, s_config,
+				info->irq, info->platform_data);
+
+		if (err && err != -ENOIOCTLCMD) {
+			v4l2_device_unregister_subdev(sd);
+			sd = NULL;
+		}
+	}
+
+error:
+	/* If we have a client but no subdev, then something went wrong and
+	   we must unregister the client. */
+	if (client && sd == NULL)
+		i2c_unregister_device(client);
+	return sd;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
+
+struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter,
+		const char *module_name, const char *client_type,
+		int irq, void *platform_data,
+		u8 addr, const unsigned short *probe_addrs)
+{
+	struct i2c_board_info info;
+
+	/* Setup the i2c board info with the device type and
+	   the device address. */
+	memset(&info, 0, sizeof(info));
+	strlcpy(info.type, client_type, sizeof(info.type));
+	info.addr = addr;
+	info.irq = irq;
+	info.platform_data = platform_data;
+
+	return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
+			&info, probe_addrs);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
+
 /* Return i2c client address of v4l2_subdev. */
 unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
 {
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index c48c24e4d0f..95f4364322e 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -153,6 +153,22 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
 struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter,
 		const char *module_name, const char *client_type, u8 addr);
+
+/* Load an i2c module and return an initialized v4l2_subdev struct.
+   Only call request_module if module_name != NULL.
+   The client_type argument is the name of the chip that's on the adapter. */
+struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter,
+		const char *module_name, const char *client_type,
+		int irq, void *platform_data,
+		u8 addr, const unsigned short *probe_addrs);
+
+struct i2c_board_info;
+
+struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter, const char *module_name,
+		struct i2c_board_info *info, const unsigned short *probe_addrs);
+
 /* Initialize an v4l2_subdev with data from an i2c_client struct */
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 		const struct v4l2_subdev_ops *ops);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index a503e1cee78..5dcb3678552 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -79,7 +79,11 @@ struct v4l2_decode_vbi_line {
    not yet implemented) since ops provide proper type-checking.
  */
 
-/* init: initialize the sensor registors to some sort of reasonable default
+/* s_config: if set, then it is always called by the v4l2_i2c_new_subdev*
+	functions after the v4l2_subdev was registered. It is used to pass
+	platform data to the subdev which can be used during initialization.
+
+   init: initialize the sensor registors to some sort of reasonable default
 	values. Do not use for new drivers and should be removed in existing
 	drivers.
 
@@ -96,6 +100,7 @@ struct v4l2_decode_vbi_line {
 struct v4l2_subdev_core_ops {
 	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
+	int (*s_config)(struct v4l2_subdev *sd, int irq, void *platform_data);
 	int (*init)(struct v4l2_subdev *sd, u32 val);
 	int (*load_fw)(struct v4l2_subdev *sd);
 	int (*reset)(struct v4l2_subdev *sd, u32 val);
-- 
cgit v1.2.3-70-g09d2


From b0d3159be9a36fd8b7b1cf88b812d951add53d11 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11901): v4l2: Create helper function for bounding and
 aligning images

Most hardware has limits on minimum and maximum image dimensions and also
requirements about alignment.  For example, image width must be even or a
multiple of four.  Some hardware has requirements that the total image size
(width * height) be a multiple of some power of two.

v4l_bound_align_image() will enforce min and max width and height, power of
two alignment on width and height, and power of two alignment on total
image size.

It uses an efficient algorithm that will try to find the "closest" image
size that meets the requirements.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-common.c | 75 ++++++++++++++++++++++++++++++++++++++-
 include/media/v4l2-common.h       | 10 ++++++
 2 files changed, 84 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index e7b443c116f..1ebbe738019 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -1021,4 +1021,77 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
 
-#endif
+/* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
+ * and max don't have to be aligned, but there must be at least one valid
+ * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
+ * of 16 between 17 and 31.  */
+static unsigned int clamp_align(unsigned int x, unsigned int min,
+				unsigned int max, unsigned int align)
+{
+	/* Bits that must be zero to be aligned */
+	unsigned int mask = ~((1 << align) - 1);
+
+	/* Round to nearest aligned value */
+	if (align)
+		x = (x + (1 << (align - 1))) & mask;
+
+	/* Clamp to aligned value of min and max */
+	if (x < min)
+		x = (min + ~mask) & mask;
+	else if (x > max)
+		x = max & mask;
+
+	return x;
+}
+
+/* Bound an image to have a width between wmin and wmax, and height between
+ * hmin and hmax, inclusive.  Additionally, the width will be a multiple of
+ * 2^walign, the height will be a multiple of 2^halign, and the overall size
+ * (width*height) will be a multiple of 2^salign.  The image may be shrunk
+ * or enlarged to fit the alignment constraints.
+ *
+ * The width or height maximum must not be smaller than the corresponding
+ * minimum.  The alignments must not be so high there are no possible image
+ * sizes within the allowed bounds.  wmin and hmin must be at least 1
+ * (don't use 0).  If you don't care about a certain alignment, specify 0,
+ * as 2^0 is 1 and one byte alignment is equivalent to no alignment.  If
+ * you only want to adjust downward, specify a maximum that's the same as
+ * the initial value.
+ */
+void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
+			   unsigned int walign,
+			   u32 *h, unsigned int hmin, unsigned int hmax,
+			   unsigned int halign, unsigned int salign)
+{
+	*w = clamp_align(*w, wmin, wmax, walign);
+	*h = clamp_align(*h, hmin, hmax, halign);
+
+	/* Usually we don't need to align the size and are done now. */
+	if (!salign)
+		return;
+
+	/* How much alignment do we have? */
+	walign = __ffs(*w);
+	halign = __ffs(*h);
+	/* Enough to satisfy the image alignment? */
+	if (walign + halign < salign) {
+		/* Max walign where there is still a valid width */
+		unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
+		/* Max halign where there is still a valid height */
+		unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
+
+		/* up the smaller alignment until we have enough */
+		do {
+			if (halign >= hmaxa ||
+			    (walign <= halign && walign < wmaxa)) {
+				*w = clamp_align(*w, wmin, wmax, walign + 1);
+				walign = __ffs(*w);
+			} else {
+				*h = clamp_align(*h, hmin, hmax, halign + 1);
+				halign = __ffs(*h);
+			}
+		} while (halign + walign < salign);
+	}
+}
+EXPORT_SYMBOL_GPL(v4l_bound_align_image);
+#endif /* defined(CONFIG_I2C) */
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 95f4364322e..33a18426ab9 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -209,4 +209,14 @@ struct v4l2_routing {
 	u32 output;
 };
 
+/* ------------------------------------------------------------------------- */
+
+/* Miscellaneous helper functions */
+
+void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
+			   unsigned int wmax, unsigned int walign,
+			   unsigned int *h, unsigned int hmin,
+			   unsigned int hmax, unsigned int halign,
+			   unsigned int salign);
+
 #endif /* V4L2_COMMON_H_ */
-- 
cgit v1.2.3-70-g09d2


From 4a6b8df2133c1f218a503e0432a9e6cc3d461a30 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11902): pxa-camera: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

For instance the old code would change 159x243 into 156x240 to meet the
alignment requirements.  The new function will use 160x243, which is a lot
closer to what was asked for originally.

Cc: Robert Jarzmik <robert.jarzmik@free.fr>
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/pxa_camera.c | 34 +++++++---------------------------
 1 file changed, 7 insertions(+), 27 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index f60de40fd21..46e0d8ad880 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -162,13 +162,6 @@
 			CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
 			CICR0_EOFM | CICR0_FOM)
 
-/*
- * YUV422P picture size should be a multiple of 16, so the heuristic aligns
- * height, width on 4 byte boundaries to reach the 16 multiple for the size.
- */
-#define YUV422P_X_Y_ALIGN 4
-#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
-
 /*
  * Structures
  */
@@ -1398,28 +1391,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 		return -EINVAL;
 	}
 
-	/* limit to pxa hardware capabilities */
-	if (pix->height < 32)
-		pix->height = 32;
-	if (pix->height > 2048)
-		pix->height = 2048;
-	if (pix->width < 48)
-		pix->width = 48;
-	if (pix->width > 2048)
-		pix->width = 2048;
-	pix->width &= ~0x01;
-
 	/*
-	 * YUV422P planar format requires images size to be a 16 bytes
-	 * multiple. If not, zeros will be inserted between Y and U planes, and
-	 * U and V planes, and YUV422P standard would be violated.
+	 * Limit to pxa hardware capabilities.  YUV422P planar format requires
+	 * images size to be a multiple of 16 bytes.  If not, zeros will be
+	 * inserted between Y and U planes, and U and V planes, which violates
+	 * the YUV422P standard.
 	 */
-	if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
-		if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
-			pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
-		if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
-			pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
-	}
+	v4l_bound_align_image(&pix->width, 48, 2048, 1,
+			      &pix->height, 32, 2048, 0,
+			      xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
 
 	pix->bytesperline = pix->width *
 		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
-- 
cgit v1.2.3-70-g09d2


From bc44fc061ea1f2b7918ec0bb55013b8054c81752 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11903): sh_mobile_ceu_camera: Use v4l bounding/alignment
 function

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/sh_mobile_ceu_camera.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index d369e8409ab..0db88a53d92 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -689,16 +689,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
 
 	/* FIXME: calculate using depth and bus width */
 
-	if (f->fmt.pix.height < 4)
-		f->fmt.pix.height = 4;
-	if (f->fmt.pix.height > 1920)
-		f->fmt.pix.height = 1920;
-	if (f->fmt.pix.width < 2)
-		f->fmt.pix.width = 2;
-	if (f->fmt.pix.width > 2560)
-		f->fmt.pix.width = 2560;
-	f->fmt.pix.width &= ~0x01;
-	f->fmt.pix.height &= ~0x03;
+	v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1,
+			      &f->fmt.pix.height, 4, 1920, 2, 0);
 
 	f->fmt.pix.bytesperline = f->fmt.pix.width *
 		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
-- 
cgit v1.2.3-70-g09d2


From 728f5b93f48cbfebd8e939bec2be1252fce7dae1 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11904): zoran: Use v4l bounding/alignment functiob

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/zoran/zoran_driver.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 643cccaa1aa..3d7df32a3d8 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -2088,16 +2088,10 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
 		return -EINVAL;
 	}
 
-	bpp = (zoran_formats[i].depth + 7) / 8;
-	fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
-	if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
-		fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-	if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
-		fmt->fmt.pix.width = BUZ_MIN_WIDTH;
-	if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
-		fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
-	if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
-		fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
+	bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
+	v4l_bound_align_image(
+		&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2,
+		&fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0);
 	mutex_unlock(&zr->resource_lock);
 
 	return 0;
-- 
cgit v1.2.3-70-g09d2


From 3adbbb8e2a87d58401466c825e9ff191e3b5a7b6 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11905): vivi: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/vivi.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index fbfefae7886..cd726685846 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -883,15 +883,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	maxh  = norm_maxh();
 
 	f->fmt.pix.field = field;
-	if (f->fmt.pix.height < 32)
-		f->fmt.pix.height = 32;
-	if (f->fmt.pix.height > maxh)
-		f->fmt.pix.height = maxh;
-	if (f->fmt.pix.width < 48)
-		f->fmt.pix.width = 48;
-	if (f->fmt.pix.width > maxw)
-		f->fmt.pix.width = maxw;
-	f->fmt.pix.width &= ~0x03;
+	v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
+			      &f->fmt.pix.height, 32, maxh, 0, 0);
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
-- 
cgit v1.2.3-70-g09d2


From bc52d6eb44de8f19934768d4d10d19fdbdc99950 Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11906): saa7134: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/saa7134/saa7134-video.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index e305c1674ce..ba87128542e 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1640,15 +1640,8 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
 	}
 
 	f->fmt.pix.field = field;
-	if (f->fmt.pix.width  < 48)
-		f->fmt.pix.width  = 48;
-	if (f->fmt.pix.height < 32)
-		f->fmt.pix.height = 32;
-	if (f->fmt.pix.width > maxw)
-		f->fmt.pix.width = maxw;
-	if (f->fmt.pix.height > maxh)
-		f->fmt.pix.height = maxh;
-	f->fmt.pix.width &= ~0x03;
+	v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
+			      &f->fmt.pix.height, 32, maxh, 0, 0);
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
-- 
cgit v1.2.3-70-g09d2


From 4b89945e590f94e82a6e7f33e21cbd0d83774b9e Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11907): cx88: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx88/cx88-video.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 0ccac702bea..b12770848c0 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1111,15 +1111,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	}
 
 	f->fmt.pix.field = field;
-	if (f->fmt.pix.height < 32)
-		f->fmt.pix.height = 32;
-	if (f->fmt.pix.height > maxh)
-		f->fmt.pix.height = maxh;
-	if (f->fmt.pix.width < 48)
-		f->fmt.pix.width = 48;
-	if (f->fmt.pix.width > maxw)
-		f->fmt.pix.width = maxw;
-	f->fmt.pix.width &= ~0x03;
+	v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
+			      &f->fmt.pix.height, 32, maxh, 0, 0);
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
-- 
cgit v1.2.3-70-g09d2


From 1c657a99fd655c0daa7450854a914d21c1da805c Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11908): w8968cf: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

The existing code was casting pointers to u32 and to unsigned int into
pointers to u16.  This could mess up if someone passed in an image size
greater than 65,535 and on big-endian platforms it won't work at all.

The existing bounding code would shrink an image if it was too big, but
returned ERANGE if it was too small.  The code will not shrink or expand as
necessary.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/w9968cf.c | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index f59b2bd07e8..6c3f23e31b5 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -460,7 +460,7 @@ static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
 static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
 static int w9968cf_postprocess_frame(struct w9968cf_device*,
 				     struct w9968cf_frame_t*);
-static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);
+static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h);
 static void w9968cf_init_framelist(struct w9968cf_device*);
 static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
@@ -1763,8 +1763,7 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
 	#define UNSC(x) ((x) >> 10)
 
 	/* Make sure we are using a supported resolution */
-	if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
-					      (u16*)&win.height)))
+	if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height)))
 		goto error;
 
 	/* Scaling factors */
@@ -1914,12 +1913,9 @@ error:
   Return 0 on success, -1 otherwise.
   --------------------------------------------------------------------------*/
 static int
-w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
+w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height)
 {
-	u16 maxw, maxh;
-
-	if ((*width < cam->minwidth) || (*height < cam->minheight))
-		return -ERANGE;
+	unsigned int maxw, maxh, align;
 
 	maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
 	       w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
@@ -1927,16 +1923,10 @@ w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height)
 	maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
 	       w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
 			   : cam->maxheight;
+	align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0;
 
-	if (*width > maxw)
-		*width = maxw;
-	if (*height > maxh)
-		*height = maxh;
-
-	if (cam->vpp_flag & VPP_DECOMPRESSION) {
-		*width  &= ~15L; /* multiple of 16 */
-		*height &= ~15L;
-	}
+	v4l_bound_align_image(width, cam->minwidth, maxw, align,
+			      height, cam->minheight, maxh, align, 0);
 
 	PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
 
@@ -3043,8 +3033,8 @@ static long w9968cf_v4l_ioctl(struct file *filp,
 		if (win.clipcount != 0 || win.flags != 0)
 			return -EINVAL;
 
-		if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
-						      (u16*)&win.height))) {
+		if ((err = w9968cf_adjust_window_size(cam, &win.width,
+						      &win.height))) {
 			DBG(4, "Resolution not supported (%ux%u). "
 			       "VIDIOCSWIN failed", win.width, win.height)
 			return err;
@@ -3116,6 +3106,7 @@ static long w9968cf_v4l_ioctl(struct file *filp,
 	{
 		struct video_mmap mmap;
 		struct w9968cf_frame_t* fr;
+		u32 w, h;
 		int err = 0;
 
 		if (copy_from_user(&mmap, arg, sizeof(mmap)))
@@ -3164,8 +3155,10 @@ static long w9968cf_v4l_ioctl(struct file *filp,
 		   }
 		}
 
-		if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width,
-						      (u16*)&mmap.height))) {
+		w = mmap.width; h = mmap.height;
+		err = w9968cf_adjust_window_size(cam, &w, &h);
+		mmap.width = w; mmap.height = h;
+		if (err) {
 			DBG(4, "Resolution not supported (%dx%d). "
 			       "VIDIOCMCAPTURE failed",
 			    mmap.width, mmap.height)
-- 
cgit v1.2.3-70-g09d2


From 2449afcbcc654dbaa9dabeda9daecb69719b0aaa Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11909): cx23885: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx23885/cx23885-video.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 66bbd2e7110..70836af3ab4 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -963,15 +963,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	}
 
 	f->fmt.pix.field = field;
-	if (f->fmt.pix.height < 32)
-		f->fmt.pix.height = 32;
-	if (f->fmt.pix.height > maxh)
-		f->fmt.pix.height = maxh;
-	if (f->fmt.pix.width < 48)
-		f->fmt.pix.width = 48;
-	if (f->fmt.pix.width > maxw)
-		f->fmt.pix.width = maxw;
-	f->fmt.pix.width &= ~0x03;
+	v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
+			      &f->fmt.pix.height, 32, maxh, 0, 0);
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
-- 
cgit v1.2.3-70-g09d2


From 653dc59b6468c2ba51f3b4aee609daa8f67d3e3a Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11910): mt9: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/mt9m001.c | 12 +++---------
 drivers/media/video/mt9t031.c | 14 +++-----------
 drivers/media/video/mt9v022.c | 12 +++---------
 3 files changed, 9 insertions(+), 29 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 459c04cbf69..4d794b42d6c 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -280,15 +280,9 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd,
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (pix->height < 32 + icd->y_skip_top)
-		pix->height = 32 + icd->y_skip_top;
-	if (pix->height > 1024 + icd->y_skip_top)
-		pix->height = 1024 + icd->y_skip_top;
-	if (pix->width < 48)
-		pix->width = 48;
-	if (pix->width > 1280)
-		pix->width = 1280;
-	pix->width &= ~0x01; /* has to be even, unsure why was ~3 */
+	v4l_bound_align_image(&pix->width, 48, 1280, 1,
+			      &pix->height, 32 + icd->y_skip_top,
+			      1024 + icd->y_skip_top, 0, 0);
 
 	return 0;
 }
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index f72aeb7c4de..4207fb34267 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -385,17 +385,9 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (pix->height < MT9T031_MIN_HEIGHT)
-		pix->height = MT9T031_MIN_HEIGHT;
-	if (pix->height > MT9T031_MAX_HEIGHT)
-		pix->height = MT9T031_MAX_HEIGHT;
-	if (pix->width < MT9T031_MIN_WIDTH)
-		pix->width = MT9T031_MIN_WIDTH;
-	if (pix->width > MT9T031_MAX_WIDTH)
-		pix->width = MT9T031_MAX_WIDTH;
-
-	pix->width &= ~0x01; /* has to be even */
-	pix->height &= ~0x01; /* has to be even */
+	v4l_bound_align_image(
+		&pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
+		&pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
 
 	return 0;
 }
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index be20d312b1d..dbdcc86ae50 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -364,15 +364,9 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd,
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (pix->height < 32 + icd->y_skip_top)
-		pix->height = 32 + icd->y_skip_top;
-	if (pix->height > 480 + icd->y_skip_top)
-		pix->height = 480 + icd->y_skip_top;
-	if (pix->width < 48)
-		pix->width = 48;
-	if (pix->width > 752)
-		pix->width = 752;
-	pix->width &= ~0x03; /* ? */
+	v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
+			      &pix->height, 32 + icd->y_skip_top,
+			      480 + icd->y_skip_top, 0, 0);
 
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2


From 9bd0e8d7d1bf0dc586bad905c7878b611da3acdc Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11911): cx231xx: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

Cc: Srinivasa Deevi <srinivasa.deevi@conexant.com>
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-video.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index a23ae73fe63..6a524d84711 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -955,8 +955,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
-	int width = f->fmt.pix.width;
-	int height = f->fmt.pix.height;
+	unsigned int width = f->fmt.pix.width;
+	unsigned int height = f->fmt.pix.height;
 	unsigned int maxw = norm_maxw(dev);
 	unsigned int maxh = norm_maxh(dev);
 	unsigned int hscale, vscale;
@@ -971,17 +971,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 
 	/* width must even because of the YUYV format
 	   height must be even because of interlacing */
-	height &= 0xfffe;
-	width &= 0xfffe;
-
-	if (unlikely(height < 32))
-		height = 32;
-	if (unlikely(height > maxh))
-		height = maxh;
-	if (unlikely(width < 48))
-		width = 48;
-	if (unlikely(width > maxw))
-		width = maxw;
+	v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
 
 	get_scale(dev, width, height, &hscale, &vscale);
 
-- 
cgit v1.2.3-70-g09d2


From ccb83408b258f7e9f9fe763f9a7d06ebcc21134f Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11912): em28xx: Use v4l bounding/alignment function

The v4l function has a better algorithm for aligning image size.

It appears that the em2800 can only scale by 50% or 100%, i.e. the only
heights supported might be 240 and 480.  In that case the old code would
set any height other than 240 to 480.  Request 240 get 240, but request 239
and then you get 480.  Change it to round to the nearest supported value.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/em28xx/em28xx-video.c | 38 ++++++++++---------------------
 1 file changed, 12 insertions(+), 26 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 882796e84db..8fe1beecfff 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -687,8 +687,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct em28xx_fh      *fh    = priv;
 	struct em28xx         *dev   = fh->dev;
-	int                   width  = f->fmt.pix.width;
-	int                   height = f->fmt.pix.height;
+	unsigned int          width  = f->fmt.pix.width;
+	unsigned int          height = f->fmt.pix.height;
 	unsigned int          maxw   = norm_maxw(dev);
 	unsigned int          maxh   = norm_maxh(dev);
 	unsigned int          hscale, vscale;
@@ -701,34 +701,20 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		return -EINVAL;
 	}
 
-	/* width must even because of the YUYV format
-	   height must be even because of interlacing */
-	height &= 0xfffe;
-	width  &= 0xfffe;
-
-	if (unlikely(height < 32))
-		height = 32;
-	if (unlikely(height > maxh))
-		height = maxh;
-	if (unlikely(width < 48))
-		width = 48;
-	if (unlikely(width > maxw))
-		width = maxw;
-
 	if (dev->board.is_em2800) {
 		/* the em2800 can only scale down to 50% */
-		if (height % (maxh / 2))
-			height = maxh;
-		if (width % (maxw / 2))
-			width = maxw;
-		/* according to empiatech support */
-		/* the MaxPacketSize is to small to support */
-		/* framesizes larger than 640x480 @ 30 fps */
-		/* or 640x576 @ 25 fps. As this would cut */
-		/* of a part of the image we prefer */
-		/* 360x576 or 360x480 for now */
+		height = height > (3 * maxh / 4) ? maxh : maxh / 2;
+		width = width > (3 * maxw / 4) ? maxw : maxw / 2;
+		/* According to empiatech support the MaxPacketSize is too small
+		 * to support framesizes larger than 640x480 @ 30 fps or 640x576
+		 * @ 25 fps.  As this would cut of a part of the image we prefer
+		 * 360x576 or 360x480 for now */
 		if (width == maxw && height == maxh)
 			width /= 2;
+	} else {
+		/* width must even because of the YUYV format
+		   height must be even because of interlacing */
+		v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
 	}
 
 	get_scale(dev, width, height, &hscale, &vscale);
-- 
cgit v1.2.3-70-g09d2


From 1ca27379f3673b40edbd2fec53b93c993fdb4f0c Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Sat, 30 May 2009 21:45:46 -0300
Subject: V4L/DVB (11913): cx231xx: TRY_FMT should not actually set anything

In the TRY_FMT handler the function get_scale() is called to find what the
scaler hardware will produce for a requested size.

The problem is that get_scale(struct cx231xx *dev, ..., unsigned int *vscale,
unsigned int *hscale) saves the calculated scale values into both the
pointer arguments and into dev's hscale and vscale fields.  TRY_FMT shouldn't
actually change anything in the device state.

The code to in get_scale() that writes to dev->[hv]scale can just be
deleted.  In all cases when dev's fields should be modified, get_scale()
was called with get_scale(dev, ..., &dev->hscale, &dev->vscale), so dev was
getting updated anyway.

This didn't actually cause a problem because nothing ever actually made use
of the hscale and vscale fields.  I changed cx231xx_resolution_set() to use
those fields rather than re-calculate them with a call to get_scale().

Updating [hv]scale in cx231xx_resolution_set() isn't necessary because
every call of cx231xx_resolution_set() was already preceded by a call to
get_scale() or setting the [hv]scale fields, so they will be always be
up-to-date w.r.t. width and height.

Removing the call to get_scale() from cx231xx_resolution_set() allowed
making get_scale() a static function, which is a good thing for something
with such a short name.  There is already another function with the same
name in the em28xx driver, but that one is static.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/cx231xx/cx231xx-avcore.c | 17 ++++-------------
 drivers/media/video/cx231xx/cx231xx-video.c  | 10 +++-------
 drivers/media/video/cx231xx/cx231xx.h        |  3 ---
 3 files changed, 7 insertions(+), 23 deletions(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 96f07d1473f..28f48f41f21 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -1052,22 +1052,13 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
 /* Set resolution of the video */
 int cx231xx_resolution_set(struct cx231xx *dev)
 {
-	int width, height;
-	u32 hscale, vscale;
-	int status = 0;
-
-	width = dev->width;
-	height = dev->height;
-
-	get_scale(dev, width, height, &hscale, &vscale);
-
 	/* set horzontal scale */
-	status = vid_blk_write_word(dev, HSCALE_CTRL, hscale);
+	int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
+	if (status)
+		return status;
 
 	/* set vertical scale */
-	status = vid_blk_write_word(dev, VSCALE_CTRL, vscale);
-
-	return status;
+	return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);
 }
 
 /******************************************************************************
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 6a524d84711..609bae6098d 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -893,9 +893,9 @@ static int check_dev(struct cx231xx *dev)
 	return 0;
 }
 
-void get_scale(struct cx231xx *dev,
-	       unsigned int width, unsigned int height,
-	       unsigned int *hscale, unsigned int *vscale)
+static void get_scale(struct cx231xx *dev,
+		      unsigned int width, unsigned int height,
+		      unsigned int *hscale, unsigned int *vscale)
 {
 	unsigned int maxw = norm_maxw(dev);
 	unsigned int maxh = norm_maxh(dev);
@@ -907,10 +907,6 @@ void get_scale(struct cx231xx *dev,
 	*vscale = (((unsigned long)maxh) << 12) / height - 4096L;
 	if (*vscale >= 0x4000)
 		*vscale = 0x3fff;
-
-	dev->hscale = *hscale;
-	dev->vscale = *vscale;
-
 }
 
 /* ------------------------------------------------------------------
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index e38eb2d425f..a0f823ac6b8 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -722,9 +722,6 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input);
 int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
 int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
 int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
-void get_scale(struct cx231xx *dev,
-	       unsigned int width, unsigned int height,
-	       unsigned int *hscale, unsigned int *vscale);
 
 /* Provided by cx231xx-video.c */
 int cx231xx_register_extension(struct cx231xx_ops *dev);
-- 
cgit v1.2.3-70-g09d2


From d8b2996607d492ffa99628bafc80da14d3a5482d Mon Sep 17 00:00:00 2001
From: Trent Piepho <xyzzy@speakeasy.org>
Date: Fri, 12 Jun 2009 16:31:29 -0300
Subject: V4L/DVB (12003): v4l2: Move bounding code outside I2C ifdef block

On Fri, 12 Jun 2009, Randy Dunlap wrote:
> From: Randy Dunlap <randy.dunlap@oracle.com>
>
> Move v4l_bound_align_image() outside of an #ifdef CONFIG_I2C block
> so that it is always built.  Fixes a build error:

clamp_align() should be moved as well, since it's only used by
v4l_bound_align_image().  I'm attaching an alternate version that fixes
this.  Labeled the endif too.

Reported-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/video/v4l2-common.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/media/video')

diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 1ebbe738019..b91d66a767d 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -1021,6 +1021,8 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
 
+#endif /* defined(CONFIG_I2C) */
+
 /* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
  * and max don't have to be aligned, but there must be at least one valid
  * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
@@ -1094,4 +1096,3 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 	}
 }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
-#endif /* defined(CONFIG_I2C) */
-- 
cgit v1.2.3-70-g09d2