V4L/DVB (8360): gspca: Bad initialization of sn9c103 - ov7630.

Signed-off-by: Andoni Zubimendi <andoni.zubimendi@gmail.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Andoni Zubimendi 2008-07-16 08:33:14 -03:00 committed by Mauro Carvalho Chehab
parent 9a97a2abe4
commit 794af52a4c

View File

@ -254,7 +254,7 @@ static const __u8 ov7630_sensor_init_com[][8] = {
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
{0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10}, /* jfm */ {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
@ -262,8 +262,8 @@ static const __u8 ov7630_sensor_init_com[][8] = {
{0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
{0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
{0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
/* {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, jfm */ {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
{0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, /* jfm */ /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
{0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
{0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
{0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
@ -489,6 +489,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
goto err; goto err;
break; break;
} }
case SENSOR_OV7630_3:
case SENSOR_OV7630: { case SENSOR_OV7630: {
__u8 i2cOV[] = __u8 i2cOV[] =
{0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16}; {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
@ -583,6 +584,14 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
goto err; goto err;
break; break;
} }
case SENSOR_OV7630_3: {
__u8 i2c[] = {0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
i2c[3] = sd->gain >> 2;
if (i2c_w(gspca_dev, i2c) < 0)
goto err;
break;
}
} }
return; return;
err: err:
@ -649,6 +658,34 @@ static void setexposure(struct gspca_dev *gspca_dev)
results in no change */ results in no change */
const int reg10_max = 0x4d; const int reg10_max = 0x4d;
reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1)
reg11 = 1;
else if (reg11 > 16)
reg11 = 16;
/* frame exposure time in ms = 1000 * reg11 / 30 ->
reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
reg10 = 1;
else if (reg10 > reg10_max)
reg10 = reg10_max;
/* Write reg 10 and reg11 low nibble */
i2c[3] = reg10;
i2c[4] |= reg11 - 1;
if (i2c_w(gspca_dev, i2c) < 0)
PDEBUG(D_ERR, "i2c error exposure");
break;
}
case SENSOR_OV7630_3: {
__u8 i2c[] = {0xb0, 0x21, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
int reg10, reg11;
/* No clear idea why, but setting reg10 above this value
results in no change */
const int reg10_max = 0x4d;
reg11 = (60 * sd->exposure + 999) / 1000; reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1) if (reg11 < 1)
reg11 = 1; reg11 = 1;
@ -705,6 +742,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->fr_h_sz = 12; /* default size of the frame header */ sd->fr_h_sz = 12; /* default size of the frame header */
sd->sd_desc.nctrls = 2; /* default nb of ctrls */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */
sd->autogain = AUTOGAIN_DEF; /* default is autogain active */
product = id->idProduct; product = id->idProduct;
/* switch (id->idVendor) { */ /* switch (id->idVendor) { */
@ -740,6 +778,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
case 0x60b0: /* SN9C103 */ case 0x60b0: /* SN9C103 */
sd->sensor = SENSOR_OV7630_3; sd->sensor = SENSOR_OV7630_3;
sd->fr_h_sz = 18; /* size of frame header */ sd->fr_h_sz = 18; /* size of frame header */
sd->sensor_has_gain = 1;
sd->sd_desc.nctrls = 4;
sd->sd_desc.dq_callback = do_autogain;
sd->autogain = 0;
break; break;
case 0x6024: /* SN9C102 */ case 0x6024: /* SN9C102 */
case 0x6025: /* SN9C102 */ case 0x6025: /* SN9C102 */
@ -777,7 +819,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->brightness = BRIGHTNESS_DEF; sd->brightness = BRIGHTNESS_DEF;
sd->gain = GAIN_DEF; sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF; sd->exposure = EXPOSURE_DEF;
sd->autogain = AUTOGAIN_DEF;
if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
return 0; return 0;
@ -940,18 +981,15 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
/* compression register */ /* compression register */
reg_w(gspca_dev, 0x18, &reg17_19[1], 1); reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
if (sd->sensor != SENSOR_OV7630_3) { /* H_start */
/* H_start */ reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); /* V_START */
/* V_START */ reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
}
/* reset 0x17 SensorClk enable inv Clk 0x60 */ /* reset 0x17 SensorClk enable inv Clk 0x60 */
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
reg_w(gspca_dev, 0x17, &reg17_19[0], 1); reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
/*MCKSIZE ->3 */ /*fixme: not ov7630*/ /*MCKSIZE ->3 */ /*fixme: not ov7630*/
if (sd->sensor != SENSOR_OV7630_3) reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */ /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
/* Enable video transfert */ /* Enable video transfert */