[media] gspca - ov519: Add the sensor ov2610ae

Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Jean-François Moine 2011-02-10 13:32:22 -03:00 committed by Mauro Carvalho Chehab
parent 20c957b360
commit 07c6c9c6d0
1 changed files with 62 additions and 5 deletions

View File

@ -118,6 +118,7 @@ struct sd {
}; };
enum sensors { enum sensors {
SEN_OV2610, SEN_OV2610,
SEN_OV2610AE,
SEN_OV3610, SEN_OV3610,
SEN_OV6620, SEN_OV6620,
SEN_OV6630, SEN_OV6630,
@ -239,6 +240,8 @@ static const struct ctrl sd_ctrls[] = {
static const unsigned ctrl_dis[] = { static const unsigned ctrl_dis[] = {
[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ [SEN_OV2610] = (1 << NCTRL) - 1, /* no control */
[SEN_OV2610AE] = (1 << NCTRL) - 1, /* no control */
[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
[SEN_OV6620] = (1 << HFLIP) | [SEN_OV6620] = (1 << HFLIP) |
@ -656,6 +659,24 @@ static const struct ov_i2c_regvals norm_2610[] = {
{ 0x12, 0x80 }, /* reset */ { 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[] = { static const struct ov_i2c_regvals norm_3620b[] = {
/* /*
* From the datasheet: "Note that after writing to register COMH * 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) { if (high == 0x96 && low == 0x40) {
PDEBUG(D_PROBE, "Sensor is an OV2610"); PDEBUG(D_PROBE, "Sensor is an OV2610");
sd->sensor = SEN_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) { } else if (high == 0x36 && (low & 0x0f) == 0x00) {
PDEBUG(D_PROBE, "Sensor is an OV3610"); PDEBUG(D_PROBE, "Sensor is an OV3610");
sd->sensor = SEN_OV3610; sd->sensor = SEN_OV3610;
@ -3295,15 +3319,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
} }
break; break;
case BRIDGE_OVFX2: case BRIDGE_OVFX2:
if (sd->sensor == SEN_OV2610) { switch (sd->sensor) {
case SEN_OV2610:
case SEN_OV2610AE:
cam->cam_mode = ovfx2_ov2610_mode; cam->cam_mode = ovfx2_ov2610_mode;
cam->nmodes = ARRAY_SIZE(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->cam_mode = ovfx2_ov3610_mode;
cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
} else if (sd->sif) { break;
cam->cam_mode = ov519_sif_mode; default:
cam->nmodes = ARRAY_SIZE(ov519_sif_mode); if (sd->sif) {
cam->cam_mode = ov519_sif_mode;
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
break;
} }
break; break;
case BRIDGE_W9968CF: case BRIDGE_W9968CF:
@ -3325,6 +3356,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* Enable autogain, autoexpo, awb, bandfilter */ /* Enable autogain, autoexpo, awb, bandfilter */
i2c_w_mask(sd, 0x13, 0x27, 0x27); i2c_w_mask(sd, 0x13, 0x27, 0x27);
break; 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: case SEN_OV3610:
write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); 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, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
return; 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: case SEN_OV3610:
if (qvga) { if (qvga) {
xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); 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 */ /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
switch (sd->sensor) { switch (sd->sensor) {
case SEN_OV2610: case SEN_OV2610:
case SEN_OV2610AE:
case SEN_OV3610: case SEN_OV3610:
case SEN_OV7670: case SEN_OV7670:
mode_init_ov_sensor_regs(sd); mode_init_ov_sensor_regs(sd);