Skip to content

Commit

Permalink
V4L/DVB (11425): gspca - m5602: Move the vflip quirk to probe stage.
Browse files Browse the repository at this point in the history
The vflip quirk is better checked at probe time as it's only needed once.
Also add an extra reset at init time to resolve a suspend to ram regression.

Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Erik Andr?n authored and Mauro Carvalho Chehab committed Apr 7, 2009
1 parent be63b72 commit 7460f52
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 21 deletions.
63 changes: 42 additions & 21 deletions drivers/media/video/gspca/m5602/m5602_ov9650.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static
DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
}
},
{ }
{}
};

const static struct ctrl ov9650_ctrls[] = {
Expand Down Expand Up @@ -249,7 +249,7 @@ int ov9650_probe(struct sd *sd)

info("Probing for an ov9650 sensor");

/* Run the pre-init to actually probe the unit */
/* Run the pre-init before probing the sensor */
for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
u8 data = preinit_ov9650[i][2];
if (preinit_ov9650[i][0] == SENSOR)
Expand All @@ -273,11 +273,9 @@ int ov9650_probe(struct sd *sd)
info("Detected an ov9650 sensor");
goto sensor_found;
}

return -ENODEV;

sensor_found:

sensor_settings = kmalloc(
ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
if (!sensor_settings)
Expand All @@ -292,13 +290,19 @@ int ov9650_probe(struct sd *sd)
sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;

if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
info("vflip quirk active");
sensor_settings[VFLIP_IDX] = 1;
}

return 0;
}

int ov9650_init(struct sd *sd)
{
int i, err = 0;
u8 data;
s32 *sensor_settings = sd->sensor_priv;

if (dump_sensor)
ov9650_dump_registers(sd);
Expand All @@ -312,11 +316,35 @@ int ov9650_init(struct sd *sd)
err = m5602_write_bridge(sd, init_ov9650[i][1], data);
}

if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
info("vflip quirk active");
data = 0x30;
err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
}
err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
if (err < 0)
return err;

err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
if (err < 0)
return err;

err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
if (err < 0)
return err;

err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
if (err < 0)
return err;

err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
if (err < 0)
return err;

err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
if (err < 0)
return err;

err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
if (err < 0)
return err;

err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);

return err;
}
Expand All @@ -339,6 +367,9 @@ int ov9650_start(struct sd *sd)
if (width <= 320)
hor_offs /= 2;

if (err < 0)
return err;

/* Synthesize the vsync/hsync setup */
for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
if (res_init_ov9650[i][0] == BRIDGE)
Expand Down Expand Up @@ -635,12 +666,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;

if (dmi_check_system(ov9650_flip_dmi_table))
i2c_data = ((i2c_data & 0xdf) |
(((val ? 0 : 1) & 0x01) << 5));
else
i2c_data = ((i2c_data & 0xdf) |
((val & 0x01) << 5));
i2c_data = ((i2c_data & 0xdf) | ((val & 0x01) << 5));

err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);

Expand Down Expand Up @@ -672,12 +698,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;

if (dmi_check_system(ov9650_flip_dmi_table))
i2c_data = ((i2c_data & 0xef) |
(((val ? 0 : 1) & 0x01) << 4));
else
i2c_data = ((i2c_data & 0xef) |
((val & 0x01) << 4));
i2c_data = ((i2c_data & 0xef) | ((val & 0x01) << 4));

err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);

Expand Down
4 changes: 4 additions & 0 deletions drivers/media/video/gspca/m5602/m5602_ov9650.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ static const unsigned char init_ov9650[][3] =

/* Reset chip */
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
/* One extra reset is needed in order to make the sensor behave
properly when resuming from ram */
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},

/* Enable double clock */
{SENSOR, OV9650_CLKRC, 0x80},
/* Do something out of spec with the power */
Expand Down

0 comments on commit 7460f52

Please sign in to comment.