V4L/DVB: gspca - sonixj: Add sensor mi0360b
authorJean-François Moine <moinejf@free.fr>
Fri, 1 Oct 2010 10:51:24 +0000 (07:51 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 03:06:21 +0000 (01:06 -0200)
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/sonixj.c

index 6e04ac7..3c699ac 100644 (file)
@@ -75,6 +75,7 @@ enum sensors {
        SENSOR_GC0307,
        SENSOR_HV7131R,
        SENSOR_MI0360,
+       SENSOR_MI0360B,
        SENSOR_MO4000,
        SENSOR_MT9V111,
        SENSOR_OM6802,
@@ -302,6 +303,10 @@ static const __u32 ctrl_dis[] = {
                        (1 << VFLIP_IDX) |
                        (1 << FREQ_IDX),
 
+[SENSOR_MI0360B] =     (1 << INFRARED_IDX) |
+                       (1 << VFLIP_IDX) |
+                       (1 << FREQ_IDX),
+
 [SENSOR_MO4000] =      (1 << INFRARED_IDX) |
                        (1 << VFLIP_IDX) |
                        (1 << FREQ_IDX),
@@ -411,6 +416,17 @@ static const u8 sn_mi0360[0x1c] = {
        0x06,   0x00,   0x00,   0x00
 };
 
+static const u8 sn_mi0360b[0x1c] = {
+/*     reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
+       0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
+/*     reg8    reg9    rega    regb    regc    regd    rege    regf */
+       0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
+/*     reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
+       0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x40,
+/*     reg18   reg19   reg1a   reg1b */
+       0x06,   0x00,   0x00,   0x00
+};
+
 static const u8 sn_mo4000[0x1c] = {
 /*     reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
        0x00,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
@@ -527,6 +543,7 @@ static const u8 *sn_tb[] = {
 [SENSOR_GC0307] =      sn_gc0307,
 [SENSOR_HV7131R] =     sn_hv7131,
 [SENSOR_MI0360] =      sn_mi0360,
+[SENSOR_MI0360B] =     sn_mi0360b,
 [SENSOR_MO4000] =      sn_mo4000,
 [SENSOR_MT9V111] =     sn_mt9v111,
 [SENSOR_OM6802] =      sn_om6802,
@@ -747,6 +764,62 @@ static const u8 mi0360_sensor_init[][8] = {
        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
        {}
 };
+static const u8 mi0360b_sensor_init[][8] = {
+       {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+       {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
+       {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
+       {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+       {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+       {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+       {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
+       {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+       {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+       {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+       {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+       {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+       {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+       {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
+       {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
+       {}
+};
+static const u8 mi0360b_sensor_param1[][8] = {
+       {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
+       {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+       {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
+       {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
+       {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+       {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+       {}
+};
 static const u8 mo4000_sensor_init[][8] = {
        {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
        {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -1310,6 +1383,7 @@ static const u8 (*sensor_init[])[8] = {
 [SENSOR_GC0307] =      gc0307_sensor_init,
 [SENSOR_HV7131R] =     hv7131r_sensor_init,
 [SENSOR_MI0360] =      mi0360_sensor_init,
+[SENSOR_MI0360B] =     mi0360b_sensor_init,
 [SENSOR_MO4000] =      mo4000_sensor_init,
 [SENSOR_MT9V111] =     mt9v111_sensor_init,
 [SENSOR_OM6802] =      om6802_sensor_init,
@@ -1571,6 +1645,10 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
        if (gspca_dev->usb_err < 0)
                return;
        switch (val) {
+       case 0x8221:
+               PDEBUG(D_PROBE, "Sensor mi0360b");
+               sd->sensor = SENSOR_MI0360B;
+               break;
        case 0x823a:
                PDEBUG(D_PROBE, "Sensor mt9v111");
                sd->sensor = SENSOR_MT9V111;
@@ -1744,6 +1822,12 @@ static void bridge_init(struct gspca_dev *gspca_dev,
                reg_w1(gspca_dev, 0x01, 0x40);
                msleep(50);
                break;
+       case SENSOR_MI0360B:
+               reg_w1(gspca_dev, 0x01, 0x61);
+               reg_w1(gspca_dev, 0x17, 0x60);
+               reg_w1(gspca_dev, 0x01, 0x60);
+               reg_w1(gspca_dev, 0x01, 0x40);
+               break;
        case SENSOR_MT9V111:
                reg_w1(gspca_dev, 0x01, 0x61);
                reg_w1(gspca_dev, 0x17, 0x61);
@@ -1961,7 +2045,8 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
                i2c_w8(gspca_dev, Expodoit);
                break;
            }
-       case SENSOR_MI0360: {
+       case SENSOR_MI0360:
+       case SENSOR_MI0360B: {
                u8 expoMi[] =           /* exposure 0x0635 -> 4 fp/s 0x10 */
                        { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
                static const u8 doit[] =                /* update sensor */
@@ -2061,6 +2146,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
                expo = sd->brightness >> 4;
                sd->exposure = setexposure(gspca_dev, expo);
                break;
+       case SENSOR_MI0360B:
+               expo = sd->brightness >> 6;
+               sd->exposure = setexposure(gspca_dev, expo);
+               break;
        case SENSOR_GC0307:
        case SENSOR_MT9V111:
                expo = sd->brightness >> 8;
@@ -2096,12 +2185,21 @@ static void setcolors(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
        int i, v;
+       const s16 *uv;
        u8 reg8a[12];                   /* U & V gains */
-       static const s16 uv[6] = {      /* same as reg84 in signed decimal */
+       static const s16 uv_com[6] = {  /* same as reg84 in signed decimal */
                -24, -38, 64,           /* UR UG UB */
                 62, -51, -9            /* VR VG VB */
        };
+       static const s16 uv_mi0360b[6] = {
+               -20, -38, 64,           /* UR UG UB */
+                60, -51, -9            /* VR VG VB */
+       };
 
+       if (sd->sensor == SENSOR_MI0360B)
+               uv = uv_mi0360b;
+       else
+               uv = uv_com;
        for (i = 0; i < 6; i++) {
                v = uv[i] * sd->colors / COLOR_DEF;
                reg8a[i * 2] = v;
@@ -2135,6 +2233,7 @@ static void setgamma(struct gspca_dev *gspca_dev)
                gamma_base = gamma_spec_0;
                break;
        case SENSOR_HV7131R:
+       case SENSOR_MI0360B:
        case SENSOR_MT9V111:
                gamma_base = gamma_spec_1;
                break;
@@ -2383,6 +2482,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
                reg17 = 0xa2;
                break;
        case SENSOR_MT9V111:
+       case SENSOR_MI0360B:
                reg17 = 0xe0;
                break;
        case SENSOR_ADCM1700:
@@ -2424,6 +2524,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
                break;
        case SENSOR_GC0307:
        case SENSOR_MT9V111:
+       case SENSOR_MI0360B:
                reg_w1(gspca_dev, 0x9a, 0x07);
                break;
        case SENSOR_OV7630:
@@ -2463,6 +2564,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
                reg17 = 0xa2;
                reg1 = 0x44;
                break;
+       case SENSOR_MI0360B:
+               init = mi0360b_sensor_param1;
+               reg1 &= ~0x02;          /* don't inverse pin S_PWR_DN */
+               reg17 = 0xe2;
+               break;
        case SENSOR_MO4000:
                if (mode) {
 /*                     reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
@@ -2617,6 +2723,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
                data = 0x2b;
                break;
        case SENSOR_MI0360:
+       case SENSOR_MI0360B:
                i2c_w8(gspca_dev, stopmi0360);
                data = 0x29;
                break;
@@ -2690,6 +2797,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
                default:
 /*             case SENSOR_MO4000: */
 /*             case SENSOR_MI0360: */
+/*             case SENSOR_MI0360B: */
 /*             case SENSOR_MT9V111: */
                        expotimes = sd->exposure;
                        expotimes += (luma_mean - delta) >> 6;
@@ -3054,6 +3162,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
 /*     {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
        {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
+                                               /* or MT9V111 */
 /*     {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
 /*     {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
 /*     {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
@@ -3086,6 +3195,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 /*     {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
        {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
+                                               /* or MT9V111 / MI0360B */
 #endif
 /*     {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
        {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},