瀏覽代碼

V4L/DVB (5585): SN9C1xx driver updates

* Default color improvements to the OV7660
@ Fix sn9c102_write_reg()
@ Fix sn9c102_i2c_try_raw_read()
@ Fix MI-0343
+ Add support for pair MI0360+SN9C120
+ Add more USB ids

Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Luca Risolia 18 年之前
父節點
當前提交
480b55c26e

+ 10 - 8
Documentation/video4linux/sn9c102.txt

@@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers:
 
 
 Vendor ID  Product ID
 Vendor ID  Product ID
 ---------  ----------
 ---------  ----------
+0x0458     0x7025
+0x045e     0x00f5
+0x045e     0x00f7
 0x0471     0x0327
 0x0471     0x0327
 0x0471     0x0328
 0x0471     0x0328
 0x0c45     0x6001
 0x0c45     0x6001
@@ -432,7 +435,7 @@ Image sensor / SN9C1xx bridge      | SN9C10[12]  SN9C103  SN9C105  SN9C120
 HV7131D    Hynix Semiconductor     | Yes         No       No       No
 HV7131D    Hynix Semiconductor     | Yes         No       No       No
 HV7131R    Hynix Semiconductor     | No          Yes      Yes      Yes
 HV7131R    Hynix Semiconductor     | No          Yes      Yes      Yes
 MI-0343    Micron Technology       | Yes         No       No       No
 MI-0343    Micron Technology       | Yes         No       No       No
-MI-0360    Micron Technology       | No          Yes      No       No
+MI-0360    Micron Technology       | No          Yes      Yes      Yes
 OV7630     OmniVision Technologies | Yes         Yes      No       No
 OV7630     OmniVision Technologies | Yes         Yes      No       No
 OV7660     OmniVision Technologies | No          No       Yes      Yes
 OV7660     OmniVision Technologies | No          No       Yes      Yes
 PAS106B    PixArt Imaging          | Yes         No       No       No
 PAS106B    PixArt Imaging          | Yes         No       No       No
@@ -478,13 +481,12 @@ scaling factor is restored to 1.
 This driver supports two different video formats: the first one is the "8-bit
 This driver supports two different video formats: the first one is the "8-bit
 Sequential Bayer" format and can be used to obtain uncompressed video data
 Sequential Bayer" format and can be used to obtain uncompressed video data
 from the device through the current I/O method, while the second one provides
 from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without frame headers not related to the
-compressed data). The compression quality may vary from 0 to 1 and can be
-selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
-ioctl's. For maximum flexibility, both the default active video format and the
-default compression quality depend on how the image sensor being used is
-initialized (as described in the documentation of the API for the image sensors
-supplied by this driver).
+either "raw" compressed video data (without frame headers not related to the
+compressed data) or standard JPEG (with frame headers). The compression quality
+may vary from 0 to 1 and can be selected or queried thanks to the
+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
+both the default active video format and the default compression quality
+depend on how the image sensor being used is initialized.
 
 
 
 
 11. Video frame formats [1]
 11. Video frame formats [1]

+ 1 - 1
drivers/media/video/sn9c102/sn9c102.h

@@ -141,7 +141,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
 
 
 void
 void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-		      struct sn9c102_sensor* sensor)
+		      const struct sn9c102_sensor* sensor)
 {
 {
 	memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
 	memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
 }
 }

+ 43 - 48
drivers/media/video/sn9c102/sn9c102_core.c

@@ -48,8 +48,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004-2007 Luca Risolia"
 #define SN9C102_MODULE_AUTHOR   "(C) 2004-2007 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.39"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 39)
+#define SN9C102_MODULE_VERSION  "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 44)
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 
 
@@ -209,38 +209,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
 }
 }
 
 
 /*****************************************************************************/
 /*****************************************************************************/
+
 /*
 /*
- * Write a sequence of count value/register pairs.  Returns -1 after the
- * first failed write, or 0 for no errors.
- */
+   Write a sequence of count value/register pairs. Returns -1 after the first
+   failed write, or 0 for no errors.
+*/
 int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
 int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
 		       int count)
 		       int count)
 {
 {
 	struct usb_device* udev = cam->usbdev;
 	struct usb_device* udev = cam->usbdev;
-	u8* value = cam->control_buffer;  /* Needed for DMA'able memory */
+	u8* buff = cam->control_buffer;
 	int i, res;
 	int i, res;
 
 
 	for (i = 0; i < count; i++) {
 	for (i = 0; i < count; i++) {
 		u8 index = valreg[i][1];
 		u8 index = valreg[i][1];
 
 
 		/*
 		/*
-		 * index is a u8, so it must be <256 and can't be out of range.
-		 * If we put in a check anyway, gcc annoys us with a warning
-		 * that our check is useless.  People get all uppity when they
-		 * see warnings in the kernel compile.
-		 */
-
-		*value = valreg[i][0];
-		res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-				      0x08, 0x41, index, 0,
-				      value, 1, SN9C102_CTRL_TIMEOUT);
+		   index is a u8, so it must be <256 and can't be out of range.
+		   If we put in a check anyway, gcc annoys us with a warning
+		   hat our check is useless. People get all uppity when they
+		   see warnings in the kernel compile.
+		*/
+
+		*buff = valreg[i][0];
+
+		res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+				      0x41, index, 0, buff, 1,
+				      SN9C102_CTRL_TIMEOUT);
+
 		if (res < 0) {
 		if (res < 0) {
 			DBG(3, "Failed to write a register (value 0x%02X, "
 			DBG(3, "Failed to write a register (value 0x%02X, "
-			       "index 0x%02X, error %d)", *value, index, res);
+			       "index 0x%02X, error %d)", *buff, index, res);
 			return -1;
 			return -1;
 		}
 		}
 
 
-		cam->reg[index] = *value;
+		cam->reg[index] = *buff;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -272,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
 }
 }
 
 
 
 
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
 {
 {
 	struct usb_device* udev = cam->usbdev;
 	struct usb_device* udev = cam->usbdev;
 	u8* buff = cam->control_buffer;
 	u8* buff = cam->control_buffer;
@@ -299,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
 
 
 
 
 static int
 static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+		 const struct sn9c102_sensor* sensor)
 {
 {
 	int i, r;
 	int i, r;
 
 
@@ -320,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
 
 
 static int
 static int
 sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
 sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
-			      struct sn9c102_sensor* sensor)
+			      const struct sn9c102_sensor* sensor)
 {
 {
 	int r , err = 0;
 	int r , err = 0;
 
 
@@ -342,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
 
 
 static int
 static int
 sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
 sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
-			       struct sn9c102_sensor* sensor)
+			       const struct sn9c102_sensor* sensor)
 {
 {
 	int r;
 	int r;
 	r = sn9c102_read_reg(cam, 0x08);
 	r = sn9c102_read_reg(cam, 0x08);
@@ -352,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
 
 
 int
 int
 sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-			 struct sn9c102_sensor* sensor, u8 data0, u8 data1,
-			 u8 n, u8 buffer[])
+			 const struct sn9c102_sensor* sensor, u8 data0,
+			 u8 data1, u8 n, u8 buffer[])
 {
 {
 	struct usb_device* udev = cam->usbdev;
 	struct usb_device* udev = cam->usbdev;
 	u8* data = cam->control_buffer;
 	u8* data = cam->control_buffer;
-	int err = 0, res;
+	int i = 0, err = 0, res;
 
 
 	/* Write cycle */
 	/* Write cycle */
 	data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
 	data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -402,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 	}
 	}
 
 
 	if (buffer)
 	if (buffer)
-		memcpy(buffer, data, sizeof(buffer));
+		for (i = 0; i < n && i < 5; i++)
+			buffer[n-i-1] = data[4-i];
 
 
 	return (int)data[4];
 	return (int)data[4];
 }
 }
@@ -410,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 
 
 int
 int
 sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-			  struct sn9c102_sensor* sensor, u8 n, u8 data0,
+			  const struct sn9c102_sensor* sensor, u8 n, u8 data0,
 			  u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
 			  u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
 {
 {
 	struct usb_device* udev = cam->usbdev;
 	struct usb_device* udev = cam->usbdev;
@@ -449,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 
 
 int
 int
 sn9c102_i2c_try_read(struct sn9c102_device* cam,
 sn9c102_i2c_try_read(struct sn9c102_device* cam,
-		     struct sn9c102_sensor* sensor, u8 address)
+		     const struct sn9c102_sensor* sensor, u8 address)
 {
 {
 	return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
 	return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
 					address, 1, NULL);
 					address, 1, NULL);
@@ -458,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
 
 
 int
 int
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
-		      struct sn9c102_sensor* sensor, u8 address, u8 value)
+		      const struct sn9c102_sensor* sensor, u8 address, u8 value)
 {
 {
 	return sn9c102_i2c_try_raw_write(cam, sensor, 3,
 	return sn9c102_i2c_try_raw_write(cam, sensor, 3,
 					 sensor->i2c_slave_id, address,
 					 sensor->i2c_slave_id, address,
@@ -657,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
 }
 }
 
 
 
 
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
-	static const u8 eoi_marker[2] = {0xff, 0xd9};
-
-	memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
-	f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
 static void sn9c102_urb_complete(struct urb *urb)
 static void sn9c102_urb_complete(struct urb *urb)
 {
 {
 	struct sn9c102_device* cam = urb->context;
 	struct sn9c102_device* cam = urb->context;
@@ -3181,14 +3176,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
 
 
 static const struct file_operations sn9c102_fops = {
 static const struct file_operations sn9c102_fops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
-	.open =    sn9c102_open,
+	.open = sn9c102_open,
 	.release = sn9c102_release,
 	.release = sn9c102_release,
-	.ioctl =   sn9c102_ioctl,
+	.ioctl = sn9c102_ioctl,
 	.compat_ioctl = v4l_compat_ioctl32,
 	.compat_ioctl = v4l_compat_ioctl32,
-	.read =    sn9c102_read,
-	.poll =    sn9c102_poll,
-	.mmap =    sn9c102_mmap,
-	.llseek =  no_llseek,
+	.read = sn9c102_read,
+	.poll = sn9c102_poll,
+	.mmap = sn9c102_mmap,
+	.llseek = no_llseek,
 };
 };
 
 
 /*****************************************************************************/
 /*****************************************************************************/
@@ -3251,7 +3246,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 		break;
 		break;
 	}
 	}
 
 
-	for  (i = 0; sn9c102_sensor_table[i]; i++) {
+	for  (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
 		err = sn9c102_sensor_table[i](cam);
 		err = sn9c102_sensor_table[i](cam);
 		if (!err)
 		if (!err)
 			break;
 			break;
@@ -3262,7 +3257,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 		DBG(3, "Support for %s maintained by %s",
 		DBG(3, "Support for %s maintained by %s",
 		    cam->sensor.name, cam->sensor.maintainer);
 		    cam->sensor.name, cam->sensor.maintainer);
 	} else {
 	} else {
-		DBG(1, "No supported image sensor detected");
+		DBG(1, "No supported image sensor detected for this bridge");
 		err = -ENODEV;
 		err = -ENODEV;
 		goto fail;
 		goto fail;
 	}
 	}

+ 3 - 1
drivers/media/video/sn9c102/sn9c102_devtable.h

@@ -86,6 +86,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
 	/* SN9C105 */
 	/* SN9C105 */
+	{ SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+	{ SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -100,6 +102,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
 	/* SN9C120 */
 	/* SN9C120 */
+	{ SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
@@ -148,7 +151,6 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
 	&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
 	&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
 	&sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
 	&sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
 	&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
 	&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-	NULL,
 };
 };
 
 
 #endif /* _SN9C102_DEVTABLE_H_ */
 #endif /* _SN9C102_DEVTABLE_H_ */

+ 2 - 4
drivers/media/video/sn9c102/sn9c102_hv7131d.c

@@ -144,7 +144,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
 	.name = "HV7131D",
 	.name = "HV7131D",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -248,12 +248,10 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
 
 
 	err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
 	err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
 				       {0x28, 0x17});
 				       {0x28, 0x17});
-	if (err)
-		return -EIO;
 
 
 	r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
 	r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
 	r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
 	r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
-	if (r0 < 0 || r1 < 0)
+	if (err || r0 < 0 || r1 < 0)
 		return -EIO;
 		return -EIO;
 
 
 	if (r0 != 0x00 || r1 != 0x04)
 	if (r0 != 0x00 || r1 != 0x04)

+ 2 - 6
drivers/media/video/sn9c102/sn9c102_hv7131r.c

@@ -44,7 +44,6 @@ static int hv7131r_init(struct sn9c102_device* cam)
 					       {0xb0, 0x2b}, {0xc0, 0x2c},
 					       {0xb0, 0x2b}, {0xc0, 0x2c},
 					       {0xd0, 0x2d}, {0xe0, 0x2e},
 					       {0xd0, 0x2d}, {0xe0, 0x2e},
 					       {0xf0, 0x2f}, {0xff, 0x30});
 					       {0xf0, 0x2f}, {0xff, 0x30});
-
 		break;
 		break;
 	case BRIDGE_SN9C105:
 	case BRIDGE_SN9C105:
 	case BRIDGE_SN9C120:
 	case BRIDGE_SN9C120:
@@ -254,7 +253,7 @@ static int hv7131r_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor hv7131r = {
+static const struct sn9c102_sensor hv7131r = {
 	.name = "HV7131R",
 	.name = "HV7131R",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
 	.supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -350,11 +349,8 @@ int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
 				       {0x34, 0x01}, {0x20, 0x17},
 				       {0x34, 0x01}, {0x20, 0x17},
 				       {0x34, 0x01}, {0x46, 0x01});
 				       {0x34, 0x01}, {0x46, 0x01});
 
 
-	if (err)
-		return -EIO;
-
 	devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
 	devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
-	if (devid < 0)
+	if (err || devid < 0)
 		return -EIO;
 		return -EIO;
 
 
 	if (devid != 0x02)
 	if (devid != 0x02)

+ 24 - 27
drivers/media/video/sn9c102/sn9c102_mi0343.c

@@ -55,45 +55,45 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
 			   struct v4l2_control* ctrl)
 			   struct v4l2_control* ctrl)
 {
 {
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-	u8 data[5+1];
+	u8 data[2];
 
 
 	switch (ctrl->id) {
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE:
 	case V4L2_CID_EXPOSURE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[2];
+		ctrl->value = data[0];
 		return 0;
 		return 0;
 	case V4L2_CID_GAIN:
 	case V4L2_CID_GAIN:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
 		break;
 		break;
 	case V4L2_CID_HFLIP:
 	case V4L2_CID_HFLIP:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3] & 0x20 ? 1 : 0;
+		ctrl->value = data[1] & 0x20 ? 1 : 0;
 		return 0;
 		return 0;
 	case V4L2_CID_VFLIP:
 	case V4L2_CID_VFLIP:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3] & 0x80 ? 1 : 0;
+		ctrl->value = data[1] & 0x80 ? 1 : 0;
 		return 0;
 		return 0;
 	case V4L2_CID_RED_BALANCE:
 	case V4L2_CID_RED_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
 		break;
 		break;
 	case V4L2_CID_BLUE_BALANCE:
 	case V4L2_CID_BLUE_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
 		break;
 		break;
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
 		break;
 		break;
 	default:
 	default:
@@ -105,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
 	case V4L2_CID_RED_BALANCE:
 	case V4L2_CID_RED_BALANCE:
 	case V4L2_CID_BLUE_BALANCE:
 	case V4L2_CID_BLUE_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
-		ctrl->value = data[3] | (data[2] << 8);
+		ctrl->value = data[1] | (data[0] << 8);
 		if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
 		if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
 			ctrl->value -= 0x10;
 			ctrl->value -= 0x10;
 		else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
 		else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -223,7 +223,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
 	.name = "MI-0343",
 	.name = "MI-0343",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -332,20 +332,17 @@ static struct sn9c102_sensor mi0343 = {
 
 
 int sn9c102_probe_mi0343(struct sn9c102_device* cam)
 int sn9c102_probe_mi0343(struct sn9c102_device* cam)
 {
 {
-	u8 data[5+1];
-	int err = 0;
-
-	err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-				       {0x28, 0x17});
+	u8 data[2];
 
 
-	if (err)
+	if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+				     {0x28, 0x17}))
 		return -EIO;
 		return -EIO;
 
 
 	if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
 	if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
 				     2, data) < 0)
 				     2, data) < 0)
 		return -EIO;
 		return -EIO;
 
 
-	if (data[4] != 0x32 || data[3] != 0xe3)
+	if (data[1] != 0x42 || data[0] != 0xe3)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	sn9c102_attach_sensor(cam, &mi0343);
 	sn9c102_attach_sensor(cam, &mi0343);

+ 167 - 53
drivers/media/video/sn9c102/sn9c102_mi0360.c

@@ -27,20 +27,105 @@ static int mi0360_init(struct sn9c102_device* cam)
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	int err = 0;
 	int err = 0;
 
 
-	err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
-				       {0x0a, 0x14}, {0x40, 0x01},
-				       {0x20, 0x17}, {0x07, 0x18},
-				       {0xa0, 0x19}, {0x02, 0x1c},
-				       {0x03, 0x1d}, {0x0f, 0x1e},
-				       {0x0c, 0x1f}, {0x00, 0x20},
-				       {0x10, 0x21}, {0x20, 0x22},
-				       {0x30, 0x23}, {0x40, 0x24},
-				       {0x50, 0x25}, {0x60, 0x26},
-				       {0x70, 0x27}, {0x80, 0x28},
-				       {0x90, 0x29}, {0xa0, 0x2a},
-				       {0xb0, 0x2b}, {0xc0, 0x2c},
-				       {0xd0, 0x2d}, {0xe0, 0x2e},
-				       {0xf0, 0x2f}, {0xff, 0x30});
+	switch (sn9c102_get_bridge(cam)) {
+	case BRIDGE_SN9C103:
+		err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+					       {0x0a, 0x14}, {0x40, 0x01},
+					       {0x20, 0x17}, {0x07, 0x18},
+					       {0xa0, 0x19}, {0x02, 0x1c},
+					       {0x03, 0x1d}, {0x0f, 0x1e},
+					       {0x0c, 0x1f}, {0x00, 0x20},
+					       {0x10, 0x21}, {0x20, 0x22},
+					       {0x30, 0x23}, {0x40, 0x24},
+					       {0x50, 0x25}, {0x60, 0x26},
+					       {0x70, 0x27}, {0x80, 0x28},
+					       {0x90, 0x29}, {0xa0, 0x2a},
+					       {0xb0, 0x2b}, {0xc0, 0x2c},
+					       {0xd0, 0x2d}, {0xe0, 0x2e},
+					       {0xf0, 0x2f}, {0xff, 0x30});
+		break;
+	case BRIDGE_SN9C105:
+	case BRIDGE_SN9C120:
+		err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+					       {0x00, 0x03}, {0x1a, 0x04},
+					       {0x50, 0x05}, {0x20, 0x06},
+					       {0x10, 0x07}, {0x03, 0x10},
+					       {0x08, 0x14}, {0xa2, 0x17},
+					       {0x47, 0x18}, {0x00, 0x19},
+					       {0x1d, 0x1a}, {0x10, 0x1b},
+					       {0x02, 0x1c}, {0x03, 0x1d},
+					       {0x0f, 0x1e}, {0x0c, 0x1f},
+					       {0x00, 0x20}, {0x29, 0x21},
+					       {0x40, 0x22}, {0x54, 0x23},
+					       {0x66, 0x24}, {0x76, 0x25},
+					       {0x85, 0x26}, {0x94, 0x27},
+					       {0xa1, 0x28}, {0xae, 0x29},
+					       {0xbb, 0x2a}, {0xc7, 0x2b},
+					       {0xd3, 0x2c}, {0xde, 0x2d},
+					       {0xea, 0x2e}, {0xf4, 0x2f},
+					       {0xff, 0x30}, {0x00, 0x3F},
+					       {0xC7, 0x40}, {0x01, 0x41},
+					       {0x44, 0x42}, {0x00, 0x43},
+					       {0x44, 0x44}, {0x00, 0x45},
+					       {0x44, 0x46}, {0x00, 0x47},
+					       {0xC7, 0x48}, {0x01, 0x49},
+					       {0xC7, 0x4A}, {0x01, 0x4B},
+					       {0xC7, 0x4C}, {0x01, 0x4D},
+					       {0x44, 0x4E}, {0x00, 0x4F},
+					       {0x44, 0x50}, {0x00, 0x51},
+					       {0x44, 0x52}, {0x00, 0x53},
+					       {0xC7, 0x54}, {0x01, 0x55},
+					       {0xC7, 0x56}, {0x01, 0x57},
+					       {0xC7, 0x58}, {0x01, 0x59},
+					       {0x44, 0x5A}, {0x00, 0x5B},
+					       {0x44, 0x5C}, {0x00, 0x5D},
+					       {0x44, 0x5E}, {0x00, 0x5F},
+					       {0xC7, 0x60}, {0x01, 0x61},
+					       {0xC7, 0x62}, {0x01, 0x63},
+					       {0xC7, 0x64}, {0x01, 0x65},
+					       {0x44, 0x66}, {0x00, 0x67},
+					       {0x44, 0x68}, {0x00, 0x69},
+					       {0x44, 0x6A}, {0x00, 0x6B},
+					       {0xC7, 0x6C}, {0x01, 0x6D},
+					       {0xC7, 0x6E}, {0x01, 0x6F},
+					       {0xC7, 0x70}, {0x01, 0x71},
+					       {0x44, 0x72}, {0x00, 0x73},
+					       {0x44, 0x74}, {0x00, 0x75},
+					       {0x44, 0x76}, {0x00, 0x77},
+					       {0xC7, 0x78}, {0x01, 0x79},
+					       {0xC7, 0x7A}, {0x01, 0x7B},
+					       {0xC7, 0x7C}, {0x01, 0x7D},
+					       {0x44, 0x7E}, {0x00, 0x7F},
+					       {0x14, 0x84}, {0x00, 0x85},
+					       {0x27, 0x86}, {0x00, 0x87},
+					       {0x07, 0x88}, {0x00, 0x89},
+					       {0xEC, 0x8A}, {0x0f, 0x8B},
+					       {0xD8, 0x8C}, {0x0f, 0x8D},
+					       {0x3D, 0x8E}, {0x00, 0x8F},
+					       {0x3D, 0x90}, {0x00, 0x91},
+					       {0xCD, 0x92}, {0x0f, 0x93},
+					       {0xf7, 0x94}, {0x0f, 0x95},
+					       {0x0C, 0x96}, {0x00, 0x97},
+					       {0x00, 0x98}, {0x66, 0x99},
+					       {0x05, 0x9A}, {0x00, 0x9B},
+					       {0x04, 0x9C}, {0x00, 0x9D},
+					       {0x08, 0x9E}, {0x00, 0x9F},
+					       {0x2D, 0xC0}, {0x2D, 0xC1},
+					       {0x3A, 0xC2}, {0x05, 0xC3},
+					       {0x04, 0xC4}, {0x3F, 0xC5},
+					       {0x00, 0xC6}, {0x00, 0xC7},
+					       {0x50, 0xC8}, {0x3C, 0xC9},
+					       {0x28, 0xCA}, {0xD8, 0xCB},
+					       {0x14, 0xCC}, {0xEC, 0xCD},
+					       {0x32, 0xCE}, {0xDD, 0xCF},
+					       {0x32, 0xD0}, {0xDD, 0xD1},
+					       {0x6A, 0xD2}, {0x50, 0xD3},
+					       {0x00, 0xD4}, {0x00, 0xD5},
+					       {0x00, 0xD6});
+		break;
+	default:
+		break;
+	}
 
 
 	err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
 	err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
 					 0x00, 0x01, 0, 0);
 					 0x00, 0x01, 0, 0);
@@ -65,50 +150,50 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam,
 			   struct v4l2_control* ctrl)
 			   struct v4l2_control* ctrl)
 {
 {
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-	u8 data[5+1];
+	u8 data[2];
 
 
 	switch (ctrl->id) {
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE:
 	case V4L2_CID_EXPOSURE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[2];
+		ctrl->value = data[0];
 		return 0;
 		return 0;
 	case V4L2_CID_GAIN:
 	case V4L2_CID_GAIN:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3];
+		ctrl->value = data[1];
 		return 0;
 		return 0;
 	case V4L2_CID_RED_BALANCE:
 	case V4L2_CID_RED_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3];
+		ctrl->value = data[1];
 		return 0;
 		return 0;
 	case V4L2_CID_BLUE_BALANCE:
 	case V4L2_CID_BLUE_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3];
+		ctrl->value = data[1];
 		return 0;
 		return 0;
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3];
+		ctrl->value = data[1];
 		return 0;
 		return 0;
 	case V4L2_CID_HFLIP:
 	case V4L2_CID_HFLIP:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3] & 0x20 ? 1 : 0;
+		ctrl->value = data[1] & 0x20 ? 1 : 0;
 		return 0;
 		return 0;
 	case V4L2_CID_VFLIP:
 	case V4L2_CID_VFLIP:
-		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-					     2+1, data) < 0)
+		if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+					     data) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value = data[3] & 0x80 ? 1 : 0;
+		ctrl->value = data[1] & 0x80 ? 1 : 0;
 		return 0;
 		return 0;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -178,8 +263,19 @@ static int mi0360_set_crop(struct sn9c102_device* cam,
 {
 {
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	int err = 0;
 	int err = 0;
-	u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
-	   v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+	u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+	switch (sn9c102_get_bridge(cam)) {
+	case BRIDGE_SN9C103:
+		h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+		break;
+	case BRIDGE_SN9C105:
+	case BRIDGE_SN9C120:
+		h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+		break;
+	default:
+		break;
+	}
 
 
 	err += sn9c102_write_reg(cam, h_start, 0x12);
 	err += sn9c102_write_reg(cam, h_start, 0x12);
 	err += sn9c102_write_reg(cam, v_start, 0x13);
 	err += sn9c102_write_reg(cam, v_start, 0x13);
@@ -194,24 +290,30 @@ static int mi0360_set_pix_format(struct sn9c102_device* cam,
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
 	int err = 0;
 	int err = 0;
 
 
-	if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
-		err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
-						 0x0a, 0x00, 0x02, 0, 0);
-		err += sn9c102_write_reg(cam, 0x20, 0x19);
-	} else {
+	if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
 		err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
 		err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
 						 0x0a, 0x00, 0x05, 0, 0);
 						 0x0a, 0x00, 0x05, 0, 0);
 		err += sn9c102_write_reg(cam, 0x60, 0x19);
 		err += sn9c102_write_reg(cam, 0x60, 0x19);
+		if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+		    sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+			err += sn9c102_write_reg(cam, 0xa6, 0x17);
+	} else {
+		err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+						 0x0a, 0x00, 0x02, 0, 0);
+		err += sn9c102_write_reg(cam, 0x20, 0x19);
+		if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+		    sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+			err += sn9c102_write_reg(cam, 0xa2, 0x17);
 	}
 	}
 
 
 	return err;
 	return err;
 }
 }
 
 
 
 
-static struct sn9c102_sensor mi0360 = {
+static const struct sn9c102_sensor mi0360 = {
 	.name = "MI-0360",
 	.name = "MI-0360",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
-	.supported_bridge = BRIDGE_SN9C103,
+	.supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
 	.frequency = SN9C102_I2C_100KHZ,
 	.frequency = SN9C102_I2C_100KHZ,
 	.interface = SN9C102_I2C_2WIRES,
 	.interface = SN9C102_I2C_2WIRES,
 	.i2c_slave_id = 0x5d,
 	.i2c_slave_id = 0x5d,
@@ -317,19 +419,31 @@ static struct sn9c102_sensor mi0360 = {
 
 
 int sn9c102_probe_mi0360(struct sn9c102_device* cam)
 int sn9c102_probe_mi0360(struct sn9c102_device* cam)
 {
 {
-	u8 data[5+1];
-	int err;
 
 
-	err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-				       {0x28, 0x17});
-	if (err)
-		return -EIO;
+	u8 data[2];
+
+	switch (sn9c102_get_bridge(cam)) {
+	case BRIDGE_SN9C103:
+		if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+					     {0x28, 0x17}))
+			return -EIO;
+		break;
+	case BRIDGE_SN9C105:
+	case BRIDGE_SN9C120:
+		if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+					     {0x01, 0x01}, {0x00, 0x01},
+					     {0x28, 0x17}))
+			return -EIO;
+		break;
+	default:
+		break;
+	}
 
 
 	if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
 	if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
-				     2+1, data) < 0)
+				     2, data) < 0)
 		return -EIO;
 		return -EIO;
 
 
-	if (data[2] != 0x82 || data[3] != 0x43)
+	if (data[0] != 0x82 || data[1] != 0x43)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	sn9c102_attach_sensor(cam, &mi0360);
 	sn9c102_attach_sensor(cam, &mi0360);

+ 10 - 15
drivers/media/video/sn9c102/sn9c102_ov7630.c

@@ -29,9 +29,8 @@ static int ov7630_init(struct sn9c102_device* cam)
 	switch (sn9c102_get_bridge(cam)) {
 	switch (sn9c102_get_bridge(cam)) {
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C102:
 	case BRIDGE_SN9C102:
-		err = sn9c102_write_const_regs(cam, {0x00, 0x14},
-					       {0x60, 0x17}, {0x0f, 0x18},
-					       {0x50, 0x19});
+		err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+					       {0x0f, 0x18}, {0x50, 0x19});
 
 
 		err += sn9c102_i2c_write(cam, 0x12, 0x8d);
 		err += sn9c102_i2c_write(cam, 0x12, 0x8d);
 		err += sn9c102_i2c_write(cam, 0x12, 0x0d);
 		err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -61,7 +60,6 @@ static int ov7630_init(struct sn9c102_device* cam)
 		err += sn9c102_i2c_write(cam, 0x71, 0x00);
 		err += sn9c102_i2c_write(cam, 0x71, 0x00);
 		err += sn9c102_i2c_write(cam, 0x74, 0x21);
 		err += sn9c102_i2c_write(cam, 0x74, 0x21);
 		err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
 		err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
-
 		break;
 		break;
 	case BRIDGE_SN9C103:
 	case BRIDGE_SN9C103:
 		err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
 		err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
@@ -253,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
 	.name = "OV7630",
 	.name = "OV7630",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -408,19 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
 	switch (sn9c102_get_bridge(cam)) {
 	switch (sn9c102_get_bridge(cam)) {
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C102:
 	case BRIDGE_SN9C102:
-		err = sn9c102_write_const_regs(cam, {0x01, 0x01},
-					       {0x00, 0x01}, {0x28, 0x17});
-
+		err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+					       {0x28, 0x17});
 		break;
 		break;
 	case BRIDGE_SN9C103: /* do _not_ change anything! */
 	case BRIDGE_SN9C103: /* do _not_ change anything! */
-		err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-					       {0x42, 0x01}, {0x28, 0x17},
-					       {0x44, 0x02});
+		err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+					       {0x28, 0x17}, {0x44, 0x02});
 		pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
 		pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
-		if (err || pid < 0) { /* try a different initialization */
-			err = sn9c102_write_reg(cam, 0x01, 0x01);
-			err += sn9c102_write_reg(cam, 0x00, 0x01);
-		}
+		if (err || pid < 0) /* try a different initialization */
+			err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+							{0x00, 0x01});
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;

+ 43 - 20
drivers/media/video/sn9c102/sn9c102_ov7660.c

@@ -104,8 +104,8 @@ static int ov7660_init(struct sn9c102_device* cam)
 	err += sn9c102_i2c_write(cam, 0x12, 0x80);
 	err += sn9c102_i2c_write(cam, 0x12, 0x80);
 	err += sn9c102_i2c_write(cam, 0x11, 0x09);
 	err += sn9c102_i2c_write(cam, 0x11, 0x09);
 	err += sn9c102_i2c_write(cam, 0x00, 0x0A);
 	err += sn9c102_i2c_write(cam, 0x00, 0x0A);
-	err += sn9c102_i2c_write(cam, 0x01, 0x78);
-	err += sn9c102_i2c_write(cam, 0x02, 0x90);
+	err += sn9c102_i2c_write(cam, 0x01, 0x80);
+	err += sn9c102_i2c_write(cam, 0x02, 0x80);
 	err += sn9c102_i2c_write(cam, 0x03, 0x00);
 	err += sn9c102_i2c_write(cam, 0x03, 0x00);
 	err += sn9c102_i2c_write(cam, 0x04, 0x00);
 	err += sn9c102_i2c_write(cam, 0x04, 0x00);
 	err += sn9c102_i2c_write(cam, 0x05, 0x08);
 	err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -122,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
 	err += sn9c102_i2c_write(cam, 0x10, 0x20);
 	err += sn9c102_i2c_write(cam, 0x10, 0x20);
 	err += sn9c102_i2c_write(cam, 0x11, 0x03);
 	err += sn9c102_i2c_write(cam, 0x11, 0x03);
 	err += sn9c102_i2c_write(cam, 0x12, 0x05);
 	err += sn9c102_i2c_write(cam, 0x12, 0x05);
-	err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+	err += sn9c102_i2c_write(cam, 0x13, 0xC7);
 	err += sn9c102_i2c_write(cam, 0x14, 0x2C);
 	err += sn9c102_i2c_write(cam, 0x14, 0x2C);
 	err += sn9c102_i2c_write(cam, 0x15, 0x00);
 	err += sn9c102_i2c_write(cam, 0x15, 0x00);
 	err += sn9c102_i2c_write(cam, 0x16, 0x02);
 	err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -162,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
 	err += sn9c102_i2c_write(cam, 0x38, 0x02);
 	err += sn9c102_i2c_write(cam, 0x38, 0x02);
 	err += sn9c102_i2c_write(cam, 0x39, 0x43);
 	err += sn9c102_i2c_write(cam, 0x39, 0x43);
 	err += sn9c102_i2c_write(cam, 0x3A, 0x00);
 	err += sn9c102_i2c_write(cam, 0x3A, 0x00);
-	err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+	err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
 	err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
 	err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
 	err += sn9c102_i2c_write(cam, 0x3D, 0x99);
 	err += sn9c102_i2c_write(cam, 0x3D, 0x99);
 	err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
 	err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -281,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
 			return -EIO;
 			return -EIO;
 		break;
 		break;
 	case V4L2_CID_DO_WHITE_BALANCE:
 	case V4L2_CID_DO_WHITE_BALANCE:
-		ctrl->value = sn9c102_pread_reg(cam, 0x02);
+		if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+			return -EIO;
 		ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
 		ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
 		break;
 		break;
 	case V4L2_CID_RED_BALANCE:
 	case V4L2_CID_RED_BALANCE:
-		ctrl->value = sn9c102_pread_reg(cam, 0x05);
+		if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+			return -EIO;
 		ctrl->value &= 0x7f;
 		ctrl->value &= 0x7f;
 		break;
 		break;
 	case V4L2_CID_BLUE_BALANCE:
 	case V4L2_CID_BLUE_BALANCE:
-		ctrl->value = sn9c102_pread_reg(cam, 0x06);
+		if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+			return -EIO;
 		ctrl->value &= 0x7f;
 		ctrl->value &= 0x7f;
 		break;
 		break;
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
-		ctrl->value = sn9c102_pread_reg(cam, 0x07);
+		if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+			return -EIO;
 		ctrl->value &= 0x7f;
 		ctrl->value &= 0x7f;
 		break;
 		break;
+	case SN9C102_V4L2_CID_BAND_FILTER:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+			return -EIO;
+		ctrl->value &= 0x08;
+		break;
 	case V4L2_CID_GAIN:
 	case V4L2_CID_GAIN:
 		if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
 		if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
 			return -EIO;
 			return -EIO;
-		ctrl->value &= 0x7f;
+		ctrl->value &= 0x1f;
 		break;
 		break;
 	case V4L2_CID_AUTOGAIN:
 	case V4L2_CID_AUTOGAIN:
 		if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
 		if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -335,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 	case SN9C102_V4L2_CID_GREEN_BALANCE:
 		err += sn9c102_write_reg(cam, ctrl->value, 0x07);
 		err += sn9c102_write_reg(cam, ctrl->value, 0x07);
 		break;
 		break;
+	case SN9C102_V4L2_CID_BAND_FILTER:
+		err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+		break;
 	case V4L2_CID_GAIN:
 	case V4L2_CID_GAIN:
-		err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+		err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
 		break;
 		break;
 	case V4L2_CID_AUTOGAIN:
 	case V4L2_CID_AUTOGAIN:
-		err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
-						    (ctrl->value << 1));
+		err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+						    (ctrl->value * 0x07));
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -386,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
 	.name = "OV7660",
 	.name = "OV7660",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
 	.supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -401,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
 			.type = V4L2_CTRL_TYPE_INTEGER,
 			.type = V4L2_CTRL_TYPE_INTEGER,
 			.name = "global gain",
 			.name = "global gain",
 			.minimum = 0x00,
 			.minimum = 0x00,
-			.maximum = 0x7f,
+			.maximum = 0x1f,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x0a,
+			.default_value = 0x09,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 		{
 		{
@@ -413,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
 			.minimum = 0x00,
 			.minimum = 0x00,
 			.maximum = 0xff,
 			.maximum = 0xff,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x50,
+			.default_value = 0x27,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 		{
 		{
@@ -433,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
 			.minimum = 0x00,
 			.minimum = 0x00,
 			.maximum = 0x7f,
 			.maximum = 0x7f,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x1f,
+			.default_value = 0x14,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 		{
 		{
@@ -443,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
 			.minimum = 0x00,
 			.minimum = 0x00,
 			.maximum = 0x7f,
 			.maximum = 0x7f,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x1e,
+			.default_value = 0x14,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 		{
 		{
@@ -453,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
 			.minimum = 0x00,
 			.minimum = 0x00,
 			.maximum = 0x01,
 			.maximum = 0x01,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x00,
+			.default_value = 0x01,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 		{
 		{
@@ -463,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
 			.minimum = 0x00,
 			.minimum = 0x00,
 			.maximum = 0x7f,
 			.maximum = 0x7f,
 			.step = 0x01,
 			.step = 0x01,
-			.default_value = 0x20,
+			.default_value = 0x14,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_BAND_FILTER,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "band filter",
+			.minimum = 0x00,
+			.maximum = 0x01,
+			.step = 0x01,
+			.default_value = 0x00,
 			.flags = 0,
 			.flags = 0,
 		},
 		},
 	},
 	},
@@ -508,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
 		return -EIO;
 		return -EIO;
 	if (pid != 0x76 || ver != 0x60)
 	if (pid != 0x76 || ver != 0x60)
 		return -ENODEV;
 		return -ENODEV;
+
 	sn9c102_attach_sensor(cam, &ov7660);
 	sn9c102_attach_sensor(cam, &ov7660);
 
 
 	return 0;
 	return 0;

+ 6 - 8
drivers/media/video/sn9c102/sn9c102_pas106b.c

@@ -163,7 +163,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
 	.name = "PAS106B",
 	.name = "PAS106B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -273,23 +273,21 @@ static struct sn9c102_sensor pas106b = {
 
 
 int sn9c102_probe_pas106b(struct sn9c102_device* cam)
 int sn9c102_probe_pas106b(struct sn9c102_device* cam)
 {
 {
-	int r0 = 0, r1 = 0, err;
+	int r0 = 0, r1 = 0;
 	unsigned int pid = 0;
 	unsigned int pid = 0;
 
 
 	/*
 	/*
 	   Minimal initialization to enable the I2C communication
 	   Minimal initialization to enable the I2C communication
 	   NOTE: do NOT change the values!
 	   NOTE: do NOT change the values!
 	*/
 	*/
-	err = sn9c102_write_const_regs(cam,
-				       {0x01, 0x01}, /* sensor power down */
-				       {0x00, 0x01}, /* sensor power on */
-				       {0x28, 0x17});/* sensor clock 24 MHz */
-	if (err)
+	if (sn9c102_write_const_regs(cam,
+				     {0x01, 0x01}, /* sensor power down */
+				     {0x00, 0x01}, /* sensor power on */
+				    {0x28, 0x17})) /* sensor clock at 24 MHz */
 		return -EIO;
 		return -EIO;
 
 
 	r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
 	r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
 	r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
 	r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
 	if (r0 < 0 || r1 < 0)
 	if (r0 < 0 || r1 < 0)
 		return -EIO;
 		return -EIO;
 
 

+ 23 - 25
drivers/media/video/sn9c102/sn9c102_pas202bcb.c

@@ -35,29 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
 	switch (sn9c102_get_bridge(cam)) {
 	switch (sn9c102_get_bridge(cam)) {
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C102:
 	case BRIDGE_SN9C102:
-		err = sn9c102_write_const_regs(cam, {0x00, 0x10},
-					       {0x00, 0x11}, {0x00, 0x14},
-					       {0x20, 0x17}, {0x30, 0x19},
-					       {0x09, 0x18});
+		err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+					       {0x00, 0x14}, {0x20, 0x17},
+					       {0x30, 0x19}, {0x09, 0x18});
 		break;
 		break;
 	case BRIDGE_SN9C103:
 	case BRIDGE_SN9C103:
-		err = sn9c102_write_const_regs(cam, {0x00, 0x02},
-					       {0x00, 0x03}, {0x1a, 0x04},
-					       {0x20, 0x05}, {0x20, 0x06},
-					       {0x20, 0x07}, {0x00, 0x10},
-					       {0x00, 0x11}, {0x00, 0x14},
-					       {0x20, 0x17}, {0x30, 0x19},
-					       {0x09, 0x18}, {0x02, 0x1c},
-					       {0x03, 0x1d}, {0x0f, 0x1e},
-					       {0x0c, 0x1f}, {0x00, 0x20},
-					       {0x10, 0x21}, {0x20, 0x22},
-					       {0x30, 0x23}, {0x40, 0x24},
-					       {0x50, 0x25}, {0x60, 0x26},
-					       {0x70, 0x27}, {0x80, 0x28},
-					       {0x90, 0x29}, {0xa0, 0x2a},
-					       {0xb0, 0x2b}, {0xc0, 0x2c},
-					       {0xd0, 0x2d}, {0xe0, 0x2e},
-					       {0xf0, 0x2f}, {0xff, 0x30});
+		err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+					       {0x1a, 0x04}, {0x20, 0x05},
+					       {0x20, 0x06}, {0x20, 0x07},
+					       {0x00, 0x10}, {0x00, 0x11},
+					       {0x00, 0x14}, {0x20, 0x17},
+					       {0x30, 0x19}, {0x09, 0x18},
+					       {0x02, 0x1c}, {0x03, 0x1d},
+					       {0x0f, 0x1e}, {0x0c, 0x1f},
+					       {0x00, 0x20}, {0x10, 0x21},
+					       {0x20, 0x22}, {0x30, 0x23},
+					       {0x40, 0x24}, {0x50, 0x25},
+					       {0x60, 0x26}, {0x70, 0x27},
+					       {0x80, 0x28}, {0x90, 0x29},
+					       {0xa0, 0x2a}, {0xb0, 0x2b},
+					       {0xc0, 0x2c}, {0xd0, 0x2d},
+					       {0xe0, 0x2e}, {0xf0, 0x2f},
+					       {0xff, 0x30});
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
@@ -197,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
 	.name = "PAS202BCB",
 	.name = "PAS202BCB",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -313,9 +312,8 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
 					       {0x28, 0x17});/* clock 24 MHz */
 					       {0x28, 0x17});/* clock 24 MHz */
 		break;
 		break;
 	case BRIDGE_SN9C103: /* do _not_ change anything! */
 	case BRIDGE_SN9C103: /* do _not_ change anything! */
-		err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-					       {0x44, 0x01}, {0x44, 0x02},
-					       {0x29, 0x17});
+		err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+					       {0x44, 0x02}, {0x29, 0x17});
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;

+ 18 - 15
drivers/media/video/sn9c102/sn9c102_sensor.h

@@ -22,7 +22,7 @@
 #define _SN9C102_SENSOR_H_
 #define _SN9C102_SENSOR_H_
 
 
 #include <linux/usb.h>
 #include <linux/usb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/stddef.h>
 #include <linux/stddef.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
@@ -74,7 +74,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
 /* Attach a probed sensor to the camera. */
 /* Attach a probed sensor to the camera. */
 extern void
 extern void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-		      struct sn9c102_sensor* sensor);
+		      const struct sn9c102_sensor* sensor);
 
 
 /*
 /*
    Read/write routines: they always return -1 on error, 0 or the read value
    Read/write routines: they always return -1 on error, 0 or the read value
@@ -85,10 +85,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
 */
 */
 
 
 /* The "try" I2C I/O versions are used when probing the sensor */
 /* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
-				 u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
-				u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+				 const struct sn9c102_sensor*, u8 address,
+				 u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+				const struct sn9c102_sensor*, u8 address);
 
 
 /*
 /*
    These must be used if and only if the sensor doesn't implement the standard
    These must be used if and only if the sensor doesn't implement the standard
@@ -102,29 +103,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
    byte.
    byte.
 */
 */
 extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-				     struct sn9c102_sensor* sensor, u8 n,
+				     const struct sn9c102_sensor* sensor, u8 n,
 				     u8 data0, u8 data1, u8 data2, u8 data3,
 				     u8 data0, u8 data1, u8 data2, u8 data3,
 				     u8 data4, u8 data5);
 				     u8 data4, u8 data5);
 extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-				    struct sn9c102_sensor* sensor, u8 data0,
-				    u8 data1, u8 n, u8 buffer[]);
+				    const struct sn9c102_sensor* sensor,
+				    u8 data0, u8 data1, u8 n, u8 buffer[]);
 
 
 /* To be used after the sensor struct has been attached to the camera struct */
 /* To be used after the sensor struct has been attached to the camera struct */
 extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
 extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
 extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 
 
 /* I/O on registers in the bridge. Could be used by the sensor methods too */
 /* I/O on registers in the bridge. Could be used by the sensor methods too */
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
 extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
 			      int count);
 			      int count);
 /*
 /*
- * Write multiple registers with constant values.  For example:
- * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- */
-#define sn9c102_write_const_regs(device, data...) \
-	({ const static u8 _data[][2] = {data}; \
-	sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); })
+   Write multiple registers with constant values. For example:
+   sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+   Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...)                     \
+	({ const static u8 _valreg[][2] = {data};                             \
+	sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 
 

+ 1 - 1
drivers/media/video/sn9c102/sn9c102_tas5110c1b.c

@@ -88,7 +88,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
 	.name = "TAS5110C1B",
 	.name = "TAS5110C1B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,

+ 1 - 1
drivers/media/video/sn9c102/sn9c102_tas5110d.c

@@ -68,7 +68,7 @@ static int tas5110d_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor tas5110d = {
+static const struct sn9c102_sensor tas5110d = {
 	.name = "TAS5110D",
 	.name = "TAS5110D",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,

+ 1 - 1
drivers/media/video/sn9c102/sn9c102_tas5130d1b.c

@@ -89,7 +89,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
 }
 }
 
 
 
 
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
 	.name = "TAS5130D1B",
 	.name = "TAS5130D1B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
 	.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,