]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/sn9c102/sn9c102_pas202bcb.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[linux-2.6-omap-h63xx.git] / drivers / media / video / sn9c102 / sn9c102_pas202bcb.c
index e3c1178e339c7cff4148268c028f01c25f42a2aa..ca4a1506ed3df7cee74976afb2973d41152bf15e 100644 (file)
@@ -1,13 +1,13 @@
 /***************************************************************************
- * Plug-in for PAS202BCB image sensor connected to the SN9C10x PC Camera   *
+ * Plug-in for PAS202BCB image sensor connected to the SN9C1xx PC Camera   *
  * Controllers                                                             *
  *                                                                         *
  * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio                  *
  *                       <medaglia@undl.org.br>                            *
  *                       http://cadu.homelinux.com:8080/                   *
  *                                                                         *
- * DAC Magnitude, exposure and green gain controls added by                *
- * Luca Risolia <luca.risolia@studio.unibo.it>                             *
+ * Support for SN9C103, DAC Magnitude, exposure and green gain controls    *
+ * added by Luca Risolia <luca.risolia@studio.unibo.it>                    *
  *                                                                         *
  * 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    *
 #include "sn9c102_sensor.h"
 
 
-static struct sn9c102_sensor pas202bcb;
-
-
 static int pas202bcb_init(struct sn9c102_device* cam)
 {
        int err = 0;
 
-       err += sn9c102_write_reg(cam, 0x00, 0x10);
-       err += sn9c102_write_reg(cam, 0x00, 0x11);
-       err += sn9c102_write_reg(cam, 0x00, 0x14);
-       err += sn9c102_write_reg(cam, 0x20, 0x17);
-       err += sn9c102_write_reg(cam, 0x30, 0x19);
-       err += sn9c102_write_reg(cam, 0x09, 0x18);
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C101:
+       case BRIDGE_SN9C102:
+               err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+                                              {0x00, 0x14}, {0x20, 0x17},
+                                              {0x30, 0x19}, {0x09, 0x18});
+               break;
+       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});
+               break;
+       default:
+               break;
+       }
 
        err += sn9c102_i2c_write(cam, 0x02, 0x14);
        err += sn9c102_i2c_write(cam, 0x03, 0x40);
@@ -107,7 +127,7 @@ static int pas202bcb_set_pix_format(struct sn9c102_device* cam,
        int err = 0;
 
        if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
-               err += sn9c102_write_reg(cam, 0x24, 0x17);
+               err += sn9c102_write_reg(cam, 0x28, 0x17);
        else
                err += sn9c102_write_reg(cam, 0x20, 0x17);
 
@@ -152,11 +172,23 @@ static int pas202bcb_set_ctrl(struct sn9c102_device* cam,
 static int pas202bcb_set_crop(struct sn9c102_device* cam,
                              const struct v4l2_rect* rect)
 {
-       struct sn9c102_sensor* s = &pas202bcb;
+       struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
-       u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
+       u8 h_start = 0,
           v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
 
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C101:
+       case BRIDGE_SN9C102:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
+               break;
+       case BRIDGE_SN9C103:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3;
+               break;
+       default:
+               break;
+       }
+
        err += sn9c102_write_reg(cam, h_start, 0x12);
        err += sn9c102_write_reg(cam, v_start, 0x13);
 
@@ -164,10 +196,10 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
        .name = "PAS202BCB",
-       .maintainer = "Carlos Eduardo Medaglia Dyonisio "
-                     "<medaglia@undl.org.br>",
+       .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+       .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
        .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
        .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
        .interface = SN9C102_I2C_2WIRES,
@@ -191,7 +223,7 @@ static struct sn9c102_sensor pas202bcb = {
                        .minimum = 0x00,
                        .maximum = 0x1f,
                        .step = 0x01,
-                       .default_value = 0x0c,
+                       .default_value = 0x0b,
                        .flags = 0,
                },
                {
@@ -201,7 +233,7 @@ static struct sn9c102_sensor pas202bcb = {
                        .minimum = 0x00,
                        .maximum = 0x0f,
                        .step = 0x01,
-                       .default_value = 0x01,
+                       .default_value = 0x00,
                        .flags = 0,
                },
                {
@@ -271,16 +303,26 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
         *  Minimal initialization to enable the I2C communication
         *  NOTE: do NOT change the values!
         */
-       err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
-       err += sn9c102_write_reg(cam, 0x40, 0x01); /* sensor power on */
-       err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
-       if (err)
-               return -EIO;
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C101:
+       case BRIDGE_SN9C102:
+               err = sn9c102_write_const_regs(cam,
+                                              {0x01, 0x01}, /* power down */
+                                              {0x40, 0x01}, /* power on */
+                                              {0x28, 0x17});/* clock 24 MHz */
+               break;
+       case BRIDGE_SN9C103: /* do _not_ change anything! */
+               err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+                                              {0x44, 0x02}, {0x29, 0x17});
+               break;
+       default:
+               break;
+       }
 
        r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
        r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
 
-       if (r0 < 0 || r1 < 0)
+       if (err || r0 < 0 || r1 < 0)
                return -EIO;
 
        pid = (r0 << 4) | ((r1 & 0xf0) >> 4);