[media] gspca - ov519: Add the sensor ov2610ae
authorJean-François Moine <moinejf@free.fr>
Thu, 10 Feb 2011 16:32:22 +0000 (13:32 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 21 Mar 2011 23:32:08 +0000 (20:32 -0300)
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/ov519.c

index 8ab2c452c25effdba21d956e494bbe6b7ea3ff39..cda7ee2c8bb4bb43b1ae6fe7b5a93fb8c8f4f7eb 100644 (file)
@@ -118,6 +118,7 @@ struct sd {
 };
 enum sensors {
        SEN_OV2610,
+       SEN_OV2610AE,
        SEN_OV3610,
        SEN_OV6620,
        SEN_OV6630,
@@ -239,6 +240,8 @@ static const struct ctrl sd_ctrls[] = {
 static const unsigned ctrl_dis[] = {
 [SEN_OV2610] =         (1 << NCTRL) - 1,       /* no control */
 
+[SEN_OV2610AE] =       (1 << NCTRL) - 1,       /* no control */
+
 [SEN_OV3610] =         (1 << NCTRL) - 1,       /* no control */
 
 [SEN_OV6620] =         (1 << HFLIP) |
@@ -656,6 +659,24 @@ static const struct ov_i2c_regvals norm_2610[] = {
        { 0x12, 0x80 }, /* reset */
 };
 
+static const struct ov_i2c_regvals norm_2610ae[] = {
+       {0x12, 0x80},   /* reset */
+       {0x13, 0xcd},
+       {0x09, 0x01},
+       {0x0d, 0x00},
+       {0x11, 0x80},
+       {0x12, 0x20},   /* 1600x1200 */
+       {0x33, 0x0c},
+       {0x35, 0x90},
+       {0x36, 0x37},
+/* ms-win traces */
+       {0x11, 0x83},   /* clock / 3 ? */
+       {0x2d, 0x00},   /* 60 Hz filter */
+       {0x24, 0xb0},   /* normal colors */
+       {0x25, 0x90},
+       {0x10, 0x43},
+};
+
 static const struct ov_i2c_regvals norm_3620b[] = {
        /*
         * From the datasheet: "Note that after writing to register COMH
@@ -2621,6 +2642,9 @@ static void ov_hires_configure(struct sd *sd)
        if (high == 0x96 && low == 0x40) {
                PDEBUG(D_PROBE, "Sensor is an OV2610");
                sd->sensor = SEN_OV2610;
+       } else if (high == 0x96 && low == 0x41) {
+               PDEBUG(D_PROBE, "Sensor is an OV2610AE");
+               sd->sensor = SEN_OV2610AE;
        } else if (high == 0x36 && (low & 0x0f) == 0x00) {
                PDEBUG(D_PROBE, "Sensor is an OV3610");
                sd->sensor = SEN_OV3610;
@@ -3295,15 +3319,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
                }
                break;
        case BRIDGE_OVFX2:
-               if (sd->sensor == SEN_OV2610) {
+               switch (sd->sensor) {
+               case SEN_OV2610:
+               case SEN_OV2610AE:
                        cam->cam_mode = ovfx2_ov2610_mode;
                        cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
-               } else if (sd->sensor == SEN_OV3610) {
+                       break;
+               case SEN_OV3610:
                        cam->cam_mode = ovfx2_ov3610_mode;
                        cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
-               } else if (sd->sif) {
-                       cam->cam_mode = ov519_sif_mode;
-                       cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
+                       break;
+               default:
+                       if (sd->sif) {
+                               cam->cam_mode = ov519_sif_mode;
+                               cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
+                       }
+                       break;
                }
                break;
        case BRIDGE_W9968CF:
@@ -3325,6 +3356,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
                /* Enable autogain, autoexpo, awb, bandfilter */
                i2c_w_mask(sd, 0x13, 0x27, 0x27);
                break;
+       case SEN_OV2610AE:
+               write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
+
+               /* enable autoexpo */
+               i2c_w_mask(sd, 0x13, 0x05, 0x05);
+               break;
        case SEN_OV3610:
                write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
 
@@ -3827,6 +3864,25 @@ static void mode_init_ov_sensor_regs(struct sd *sd)
                i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
                i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
                return;
+       case SEN_OV2610AE: {
+               u8 v;
+
+               /* frame rates:
+                *      10fps / 5 fps for 1600x1200
+                *      40fps / 20fps for 800x600
+                */
+               v = 80;
+               if (qvga) {
+                       if (sd->frame_rate < 25)
+                               v = 0x81;
+               } else {
+                       if (sd->frame_rate < 10)
+                               v = 0x81;
+               }
+               i2c_w(sd, 0x11, v);
+               i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
+               return;
+           }
        case SEN_OV3610:
                if (qvga) {
                        xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3975,6 +4031,7 @@ static void set_ov_sensor_window(struct sd *sd)
        /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
        switch (sd->sensor) {
        case SEN_OV2610:
+       case SEN_OV2610AE:
        case SEN_OV3610:
        case SEN_OV7670:
                mode_init_ov_sensor_regs(sd);