V4L/DVB (9293): gspca: Separate and fix the sensor dependant sequences in t613.
[sfrench/cifs-2.6.git] / drivers / media / video / gspca / t613.c
index f034c748fc7ef5c3a608ff88e6ca1ab18e94261e..b2823700bd93719377b24ef9c9b8dbc3be2e4398 100644 (file)
@@ -28,8 +28,6 @@
 
 #include "gspca.h"
 
-#define MAX_GAMMA 0x10         /* 0 to 15 */
-
 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
 
 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
@@ -49,6 +47,10 @@ struct sd {
        unsigned char whitebalance;
        unsigned char mirror;
        unsigned char effect;
+
+       __u8 sensor;
+#define SENSOR_TAS5130A 0
+#define SENSOR_OM6802 1
 };
 
 /* V4L2 controls supported by the driver */
@@ -83,9 +85,9 @@ static struct ctrl sd_ctrls[] = {
          .type = V4L2_CTRL_TYPE_INTEGER,
          .name = "Brightness",
          .minimum = 0,
-         .maximum = 0x0f,
+         .maximum = 14,
          .step = 1,
-         .default_value = 0x09,
+         .default_value = 8,
          },
         .set = sd_setbrightness,
         .get = sd_getbrightness,
@@ -118,16 +120,17 @@ static struct ctrl sd_ctrls[] = {
         .set = sd_setcolors,
         .get = sd_getcolors,
         },
-#define SD_GAMMA 3
+#define GAMMA_MAX 16
+#define GAMMA_DEF 10
        {
         {
          .id = V4L2_CID_GAMMA, /* (gamma on win) */
          .type = V4L2_CTRL_TYPE_INTEGER,
-         .name = "Gamma (Untested)",
+         .name = "Gamma",
          .minimum = 0,
-         .maximum = MAX_GAMMA,
+         .maximum = GAMMA_MAX - 1,
          .step = 1,
-         .default_value = 0x09,
+         .default_value = GAMMA_DEF,
          },
         .set = sd_setgamma,
         .get = sd_getgamma,
@@ -185,7 +188,7 @@ static struct ctrl sd_ctrls[] = {
          .minimum = 0,
          .maximum = 1,
          .step = 1,
-         .default_value = 1,
+         .default_value = 0,
          },
         .set = sd_setwhitebalance,
         .get = sd_getwhitebalance
@@ -197,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
          .type = V4L2_CTRL_TYPE_INTEGER,
          .name = "Sharpness",
          .minimum = 0,
-         .maximum = MAX_GAMMA, /* 0 to 16 */
+         .maximum = 15,
          .step = 1,
          .default_value = 0x06,
          },
@@ -258,7 +261,59 @@ static struct v4l2_pix_format vga_mode_t16[] = {
                .priv = 0},
 };
 
-#define T16_OFFSET_DATA 631
+/* sensor specific data */
+struct additional_sensor_data {
+       const __u8 data1[20];
+       const __u8 data2[18];
+       const __u8 data3[18];
+       const __u8 data4[4];
+       const __u8 data5[6];
+       const __u8 stream[4];
+};
+
+const static struct additional_sensor_data sensor_data[] = {
+    {                          /* TAS5130A */
+       .data1 =
+               {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
+                0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
+                0xd8, 0xc8, 0xd9, 0xfc},
+       .data2 =
+               {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
+                0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
+                0xe8, 0xe0},
+       .data3 =
+               {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
+                0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
+                0xcf, 0xe0},
+       .data4 =        /* Freq (50/60Hz). Splitted for test purpose */
+               {0x66, 0x00, 0xa8, 0xe8},
+       .data5 =
+               {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
+       .stream =
+               {0x0b, 0x04, 0x0a, 0x40},
+    },
+    {                          /* OM6802 */
+       .data1 =
+               {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
+                0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
+                0xd8, 0xb3, 0xd9, 0xfc},
+       .data2 =
+               {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
+                0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
+                0xe8, 0xff},
+       .data3 =
+               {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
+                0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
+                0xcf, 0xff},
+       .data4 =        /*Freq (50/60Hz). Splitted for test purpose */
+               {0x66, 0xca, 0xa8, 0xf0 },
+       .data5 =        /* this could be removed later */
+               {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+       .stream =
+               {0x0b, 0x04, 0x0a, 0x78},
+    }
+};
+
 #define MAX_EFFECTS 7
 /* easily done by soft, this table could be removed,
  * i keep it here just in case */
@@ -272,87 +327,87 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
        {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},   /* Negative */
 };
 
-static const __u8 gamma_table[MAX_GAMMA][34] = {
-       {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
+static const __u8 gamma_table[GAMMA_MAX][34] = {
+       {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,        /* 0 */
         0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
         0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
         0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
-        0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
-        0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
-        0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
+       {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75,        /* 1 */
+        0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
+        0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
+        0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
-        0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
-        0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
-        0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
+       {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b,        /* 2 */
+        0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
+        0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
+        0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
-        0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
-        0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
-        0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
+       {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,        /* 3 */
+        0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
+        0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
+        0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
+       {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55,        /* 4 */
         0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
-        0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
-        0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
+        0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
+        0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
+       {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48,        /* 5 */
         0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
-        0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
-        0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
+        0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
+        0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
+       {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,        /* 6 */
         0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
         0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
         0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
-        0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
-        0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
-        0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
+       {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,        /* 7 */
+        0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
+        0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
+        0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
-        0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
-        0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
-        0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
+       {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,        /* 8 */
+        0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
+        0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
+        0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
+       {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,        /* 9 */
         0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
         0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
         0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
-        0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
-        0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
-        0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
+       {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44,        /* 10 */
+        0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
+        0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
+        0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
-        0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
-        0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
-        0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
+       {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52,        /* 11 */
+        0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
+        0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
+        0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
-        0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
-        0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
-        0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
-        0xA0, 0xFF},
-       {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
-        0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
-        0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
-        0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
+       {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e,        /* 12 */
+        0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
+        0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
+        0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
-        0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
-        0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
-        0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
+       {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83,        /* 13 */
+        0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
+        0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
+        0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
         0xa0, 0xff},
-       {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
-        0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
-        0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
-        0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
-        0xA0, 0xFF}
+       {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a,        /* 14 */
+        0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
+        0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
+        0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
+        0xa0, 0xff},
+       {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7,        /* 15 */
+        0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
+        0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
+        0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
+        0xa0, 0xff}
 };
 
 static const __u8 tas5130a_sensor_init[][8] = {
@@ -363,8 +418,10 @@ static const __u8 tas5130a_sensor_init[][8] = {
        {},
 };
 
+static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+
 /* read 1 byte */
-static int reg_r_1(struct gspca_dev *gspca_dev,
+static int reg_r(struct gspca_dev *gspca_dev,
                   __u16 index)
 {
        usb_control_msg(gspca_dev->dev,
@@ -378,26 +435,26 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
 }
 
 static void reg_w(struct gspca_dev *gspca_dev,
-                       __u16 value,
-                       __u16 index,
-                       const __u8 *buffer, __u16 len)
+                 __u16 index)
+{
+       usb_control_msg(gspca_dev->dev,
+                       usb_sndctrlpipe(gspca_dev->dev, 0),
+                       0,
+                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                       0, index,
+                       NULL, 0, 500);
+}
+
+static void reg_w_buf(struct gspca_dev *gspca_dev,
+                 const __u8 *buffer, __u16 len)
 {
-       if (buffer == NULL) {
-               usb_control_msg(gspca_dev->dev,
-                               usb_sndctrlpipe(gspca_dev->dev, 0),
-                               0,
-                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-                               value, index,
-                               NULL, 0, 500);
-               return;
-       }
        if (len <= USB_BUF_SZ) {
                memcpy(gspca_dev->usb_buf, buffer, len);
                usb_control_msg(gspca_dev->dev,
                                usb_sndctrlpipe(gspca_dev->dev, 0),
                                0,
-                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-                               value, index,
+                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0x01, 0,
                                gspca_dev->usb_buf, len, 500);
        } else {
                __u8 *tmpbuf;
@@ -407,13 +464,72 @@ static void reg_w(struct gspca_dev *gspca_dev,
                usb_control_msg(gspca_dev->dev,
                                usb_sndctrlpipe(gspca_dev->dev, 0),
                                0,
-                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-                               value, index,
+                          USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0x01, 0,
                                tmpbuf, len, 500);
                kfree(tmpbuf);
        }
 }
 
+/* Reported as OM6802*/
+static void om6802_sensor_init(struct gspca_dev *gspca_dev)
+{
+       int i;
+       const __u8 *p;
+       __u8 byte;
+       __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+       static const __u8 sensor_init[] = {
+               0xdf, 0x6d,
+               0xdd, 0x18,
+               0x5a, 0xe0,
+               0x5c, 0x07,
+               0x5d, 0xb0,
+               0x5e, 0x1e,
+               0x60, 0x71,
+               0xef, 0x00,
+               0xe9, 0x00,
+               0xea, 0x00,
+               0x90, 0x24,
+               0x91, 0xb2,
+               0x82, 0x32,
+               0xfd, 0x41,
+               0x00                    /* table end */
+       };
+
+       reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+       msleep(5);
+       i = 4;
+       while (--i < 0) {
+               byte = reg_r(gspca_dev, 0x0060);
+               if (!(byte & 0x01))
+                       break;
+               msleep(100);
+       }
+       byte = reg_r(gspca_dev, 0x0063);
+       if (byte != 0x17) {
+               err("Bad sensor reset %02x", byte);
+               /* continue? */
+       }
+
+       p = sensor_init;
+       while (*p != 0) {
+               val[1] = *p++;
+               val[3] = *p++;
+               if (*p == 0)
+                       reg_w(gspca_dev, 0x3c80);
+               reg_w_buf(gspca_dev, val, sizeof val);
+               i = 4;
+               while (--i >= 0) {
+                       msleep(15);
+                       byte = reg_r(gspca_dev, 0x60);
+                       if (!(byte & 0x01))
+                               break;
+               }
+       }
+       msleep(15);
+       reg_w(gspca_dev, 0x3c80);
+}
+
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
                     const struct usb_device_id *id)
@@ -430,7 +546,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
        sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
        sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
-       sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
+       sd->gamma = GAMMA_DEF;
        sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
        sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
        sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
@@ -439,27 +555,98 @@ static int sd_config(struct gspca_dev *gspca_dev,
        return 0;
 }
 
-static int init_default_parameters(struct gspca_dev *gspca_dev)
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       unsigned int brightness;
+       __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+
+       brightness = sd->brightness;
+       if (brightness < 7) {
+               set6[1] = 0x26;
+               set6[3] = 0x70 - brightness * 0x10;
+       } else {
+               set6[3] = 0x00 + ((brightness - 7) * 0x10);
+       }
+
+       reg_w_buf(gspca_dev, set6, sizeof set6);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       unsigned int contrast = sd->contrast;
+       __u16 reg_to_write;
+
+       if (contrast < 7)
+               reg_to_write = 0x8ea9 - contrast * 0x200;
+       else
+               reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
+
+       reg_w(gspca_dev, reg_to_write);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       __u16 reg_to_write;
+
+       reg_to_write = 0x80bb + sd->colors * 0x100;     /* was 0xc0 */
+       reg_w(gspca_dev, reg_to_write);
+}
+
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
+       reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+}
+
+static void setwhitebalance(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       __u8 white_balance[8] =
+               {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
+
+       if (sd->whitebalance)
+               white_balance[7] = 0x3c;
+
+       reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       __u16 reg_to_write;
+
+       reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
+
+       reg_w(gspca_dev, reg_to_write);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
        /* some of this registers are not really neded, because
         * they are overriden by setbrigthness, setcontrast, etc,
         * but wont hurt anyway, and can help someone with similar webcam
         * to see the initial parameters.*/
-       int i = 0;
-       __u8 test_byte;
+       struct sd *sd = (struct sd *) gspca_dev;
+       int i;
+       __u8 byte, test_byte;
 
        static const __u8 read_indexs[] =
                { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
                  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
-       static const __u8 n1[6] =
+       static const __u8 n1[] =
                        {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
-       static const __u8 n2[2] =
+       static const __u8 n2[] =
                        {0x08, 0x00};
-       static const __u8 nset[6] =
-               { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
-       static const __u8 n3[6] =
+       static const __u8 n3[] =
                        {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
-       static const __u8 n4[0x46] =
+       static const __u8 n4[] =
                {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
                 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
                 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -469,131 +656,113 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
                 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
                 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
                 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
-       static const __u8 nset4[18] = {
-               0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
-               0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
-               0xe8, 0xe0
-       };
-       /* ojo puede ser 0xe6 en vez de 0xe9 */
-       static const __u8 nset2[20] = {
-               0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
-               0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
-               0xd8, 0xc8, 0xd9, 0xfc
-       };
-       static const __u8 missing[8] =
-               { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
-       static const __u8 nset3[18] = {
-               0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
-               0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
-               0xcf, 0xe0
-       };
-       static const __u8 nset5[4] =
-               { 0x8f, 0x24, 0xc3, 0x00 };     /* bright */
-       static const __u8 nset6[34] = {
-               0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
-               0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
-               0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
-               0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
-               0xa0, 0xff
-       };                      /* Gamma */
-       static const __u8 nset7[4] =
-                       { 0x66, 0xca, 0xa8, 0xf8 };     /* 50/60 Hz */
        static const __u8 nset9[4] =
                        { 0x0b, 0x04, 0x0a, 0x78 };
        static const __u8 nset8[6] =
                        { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-       static const __u8 nset10[6] =
-                       { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
 
-       reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
-       reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
-       reg_r_1(gspca_dev, 0x0063);
-       reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
+       byte = reg_r(gspca_dev, 0x06);
+       test_byte = reg_r(gspca_dev, 0x07);
+       if (byte == 0x08 && test_byte == 0x07) {
+               PDEBUG(D_CONF, "sensor om6802");
+               sd->sensor = SENSOR_OM6802;
+       } else if (byte == 0x08 && test_byte == 0x01) {
+               PDEBUG(D_CONF, "sensor tas5130a");
+               sd->sensor = SENSOR_TAS5130A;
+       } else {
+               PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
+               sd->sensor = SENSOR_TAS5130A;
+       }
+
+       reg_w_buf(gspca_dev, n1, sizeof n1);
+       test_byte = 0;
+       i = 5;
+       while (--i >= 0) {
+               reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+               test_byte = reg_r(gspca_dev, 0x0063);
+               msleep(100);
+               if (test_byte == 0x17)
+                       break;          /* OK */
+       }
+       if (i < 0) {
+               err("Bad sensor reset %02x", test_byte);
+/*             return -EIO; */
+/*fixme: test - continue */
+       }
+       reg_w_buf(gspca_dev, n2, sizeof n2);
 
+       i = 0;
        while (read_indexs[i] != 0x00) {
-               test_byte = reg_r_1(gspca_dev, read_indexs[i]);
-               PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
+               test_byte = reg_r(gspca_dev, read_indexs[i]);
+               PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
                       test_byte);
                i++;
        }
 
-       reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
-       reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
-       reg_r_1(gspca_dev, 0x0080);
-       reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
-       reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
-       reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
-       reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
-       reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
-       reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
-       reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
-       reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
-       reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
-       reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
-       reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
-       reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
-
-       reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
-
-       reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
-       reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
-       reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
-
-       reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
-       reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
-       reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
-       reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
-
-       reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
-       reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
-       reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
-       reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
+       reg_w_buf(gspca_dev, n3, sizeof n3);
+       reg_w_buf(gspca_dev, n4, sizeof n4);
+       reg_r(gspca_dev, 0x0080);
+       reg_w(gspca_dev, 0x2c80);
 
-       return 0;
-}
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+                       sizeof sensor_data[sd->sensor].data1);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+                       sizeof sensor_data[sd->sensor].data3);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+                       sizeof sensor_data[sd->sensor].data2);
 
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
-       init_default_parameters(gspca_dev);
-       return 0;
-}
+       reg_w(gspca_dev, 0x3880);
+       reg_w(gspca_dev, 0x3880);
+       reg_w(gspca_dev, 0x338e);
 
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       unsigned int brightness;
-       __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
-       brightness = sd->brightness;
+       setbrightness(gspca_dev);
+       setcontrast(gspca_dev);
+       setgamma(gspca_dev);
+       setcolors(gspca_dev);
+       setsharpness(gspca_dev);
+       setwhitebalance(gspca_dev);
 
-       if (brightness < 7) {
-               set6[3] = 0x70 - (brightness * 0xa);
-       } else {
-               set6[1] = 0x24;
-               set6[3] = 0x00 + ((brightness - 7) * 0xa);
-       }
+       reg_w(gspca_dev, 0x2087);       /* tied to white balance? */
+       reg_w(gspca_dev, 0x2088);
+       reg_w(gspca_dev, 0x2089);
+
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+                       sizeof sensor_data[sd->sensor].data4);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
+                       sizeof sensor_data[sd->sensor].data5);
+       reg_w_buf(gspca_dev, nset8, sizeof nset8);
+       reg_w_buf(gspca_dev, nset9, sizeof nset9);
+
+       reg_w(gspca_dev, 0x2880);
+
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+                       sizeof sensor_data[sd->sensor].data1);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+                       sizeof sensor_data[sd->sensor].data3);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+                       sizeof sensor_data[sd->sensor].data2);
 
-       reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
+       return 0;
 }
 
 static void setflip(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-
        __u8 flipcmd[8] =
-           { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
+               {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
 
-       if (sd->mirror == 1)
+       if (sd->mirror)
                flipcmd[3] = 0x01;
 
-       reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
+       reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
 }
 
 static void seteffect(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
-       reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
+       reg_w_buf(gspca_dev, effects_table[sd->effect],
+                               sizeof effects_table[0]);
        if (sd->effect == 1 || sd->effect == 5) {
                PDEBUG(D_CONF,
                       "This effect have been disabled for webcam \"safety\"");
@@ -601,22 +770,9 @@ static void seteffect(struct gspca_dev *gspca_dev)
        }
 
        if (sd->effect == 1 || sd->effect == 4)
-               reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
+               reg_w(gspca_dev, 0x4aa6);
        else
-               reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
-}
-
-static void setwhitebalance(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-
-       __u8 white_balance[8] =
-           { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
-
-       if (sd->whitebalance == 1)
-               white_balance[7] = 0x3c;
-
-       reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
+               reg_w(gspca_dev, 0xfaa6);
 }
 
 static void setlightfreq(struct gspca_dev *gspca_dev)
@@ -627,44 +783,130 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
        if (sd->freq == 2)      /* 60hz */
                freq[1] = 0x00;
 
-       reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
+       reg_w_buf(gspca_dev, freq, sizeof freq);
 }
 
-static void setcontrast(struct gspca_dev *gspca_dev)
+/* Is this really needed?
+ * i added some module parameters for test with some users */
+static void poll_sensor(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       unsigned int contrast = sd->contrast;
-       __u16 reg_to_write = 0x00;
-
-       if (contrast < 7)
-               reg_to_write = 0x8ea9 - (0x200 * contrast);
-       else
-               reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
-
-       reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
+       static const __u8 poll1[] =
+               {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
+                0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
+                0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
+                0x60, 0x14};
+       static const __u8 poll2[] =
+               {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
+                0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
+       static const __u8 poll3[] =
+               {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
+       static const __u8 poll4[] =
+               {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
+                0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
+                0xc2, 0x80, 0xc3, 0x10};
+
+       if (sd->sensor != SENSOR_TAS5130A) {
+               PDEBUG(D_STREAM, "[Sensor requires polling]");
+               reg_w_buf(gspca_dev, poll1, sizeof poll1);
+               reg_w_buf(gspca_dev, poll2, sizeof poll2);
+               reg_w_buf(gspca_dev, poll3, sizeof poll3);
+               reg_w_buf(gspca_dev, poll4, sizeof poll4);
+       }
 }
 
-static void setcolors(struct gspca_dev *gspca_dev)
+static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       __u16 reg_to_write;
+       int i, mode;
+       __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+       static const __u8 t3[] =
+               { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
+                 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
 
-       reg_to_write = 0xc0bb + sd->colors * 0x100;
-       reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
-}
+       mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
+       switch (mode) {
+       case 1:         /* 352x288 */
+               t2[1] = 0x40;
+               break;
+       case 2:         /* 320x240 */
+               t2[1] = 0x10;
+               break;
+       case 3:         /* 176x144 */
+               t2[1] = 0x50;
+               break;
+       case 4:         /* 160x120 */
+               t2[1] = 0x20;
+               break;
+       default:        /* 640x480 (0x00) */
+               break;
+       }
 
-static void setgamma(struct gspca_dev *gspca_dev)
-{
+       if (sd->sensor == SENSOR_TAS5130A) {
+               i = 0;
+               while (tas5130a_sensor_init[i][0] != 0) {
+                       reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
+                                        sizeof tas5130a_sensor_init[0]);
+                       i++;
+               }
+               reg_w(gspca_dev, 0x3c80);
+               /* just in case and to keep sync with logs (for mine) */
+               reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
+                                sizeof tas5130a_sensor_init[0]);
+               reg_w(gspca_dev, 0x3c80);
+       } else {
+               om6802_sensor_init(gspca_dev);
+       }
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+                       sizeof sensor_data[sd->sensor].data4);
+       reg_r(gspca_dev, 0x0012);
+       reg_w_buf(gspca_dev, t2, sizeof t2);
+       reg_w_buf(gspca_dev, t3, sizeof t3);
+       reg_w(gspca_dev, 0x0013);
+       msleep(15);
+       reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+                       sizeof sensor_data[sd->sensor].stream);
+       poll_sensor(gspca_dev);
+
+       /* restart on each start, just in case, sometimes regs goes wrong
+        * when using controls from app */
+       setbrightness(gspca_dev);
+       setcontrast(gspca_dev);
+       setcolors(gspca_dev);
+       return 0;
 }
 
-static void setsharpness(struct gspca_dev *gspca_dev)
+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;
-       __u16 reg_to_write;
+       static __u8 ffd9[] = { 0xff, 0xd9 };
 
-       reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
+       if (data[0] == 0x5a) {
+               /* Control Packet, after this came the header again,
+                * but extra bytes came in the packet before this,
+                * sometimes an EOF arrives, sometimes not... */
+               return;
+       }
+       data += 2;
+       len -= 2;
+       if (data[0] == 0xff && data[1] == 0xd8) {
+               /* extra bytes....., could be processed too but would be
+                * a waste of time, right now leave the application and
+                * libjpeg do it for ourserlves.. */
+               frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+                                       ffd9, 2);
+               gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+               return;
+       }
 
-       reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
+       if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
+               /* Just in case, i have seen packets with the marker,
+                * other's do not include it... */
+               len -= 2;
+       }
+       gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -788,6 +1030,7 @@ static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
 {
        struct sd *sd = (struct sd *) gspca_dev;
+
        *val = sd->gamma;
        return 0;
 }
@@ -835,9 +1078,9 @@ static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
 
        sd->autogain = val;
        if (val != 0)
-               reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
+               reg_w(gspca_dev, 0xf48e);
        else
-               reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
+               reg_w(gspca_dev, 0xb48e);
        return 0;
 }
 
@@ -849,99 +1092,6 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
        return 0;
 }
 
-static void sd_start(struct gspca_dev *gspca_dev)
-{
-       int mode;
-
-       static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
-       __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
-       static const __u8 t3[] =
-               { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
-                 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
-       static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
-
-       mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
-       switch (mode) {
-       case 1:         /* 352x288 */
-               t2[1] = 0x40;
-               break;
-       case 2:         /* 320x240 */
-               t2[1] = 0x10;
-               break;
-       case 3:         /* 176x144 */
-               t2[1] = 0x50;
-               break;
-       case 4:         /* 160x120 */
-               t2[1] = 0x20;
-               break;
-       default:        /* 640x480 (0x00) */
-               break;
-       }
-
-       reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
-       reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
-       reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
-       reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
-       reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
-               /* just in case and to keep sync with logs  (for mine) */
-       reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
-       reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
-               /* just in case and to keep sync with logs  (for mine) */
-       reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
-       reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
-       reg_r_1(gspca_dev, 0x0012);
-       reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
-       reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
-       reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
-       /* restart on each start, just in case, sometimes regs goes wrong
-        * when using controls from app */
-       setbrightness(gspca_dev);
-       setcontrast(gspca_dev);
-       setcolors(gspca_dev);
-}
-
-static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-                       struct gspca_frame *frame,      /* target */
-                       __u8 *data,                     /* isoc packet */
-                       int len)                        /* iso packet length */
-{
-       int sof = 0;
-       static __u8 ffd9[] = { 0xff, 0xd9 };
-
-       if (data[0] == 0x5a) {
-               /* Control Packet, after this came the header again,
-                * but extra bytes came in the packet before this,
-                * sometimes an EOF arrives, sometimes not... */
-               return;
-       }
-
-       if (data[len - 1] == 0xff && data[len] == 0xd9) {
-               /* Just in case, i have seen packets with the marker,
-                * other's do not include it... */
-               data += 2;
-               len -= 4;
-       } else if (data[2] == 0xff && data[3] == 0xd8) {
-               sof = 1;
-               data += 2;
-               len -= 2;
-       } else {
-               data += 2;
-               len -= 2;
-       }
-
-       if (sof) {
-               /* extra bytes....., could be processed too but would be
-                * a waste of time, right now leave the application and
-                * libjpeg do it for ourserlves.. */
-               frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-                                       ffd9, 2);
-               gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
-               return;
-       }
-
-       gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
-}
-
 static int sd_querymenu(struct gspca_dev *gspca_dev,
                        struct v4l2_querymenu *menu)
 {