diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-04 02:52:50 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-04-06 20:44:47 -0400 |
commit | 7460f524980d1d7c39f05b7e95d6d2fba072fd8a (patch) | |
tree | 5e51a44d18a0d0ec2affecd9a906f0e06db1143a | |
parent | be63b722a56f0fe8fbe8e76cbdadaee0429cd291 (diff) |
V4L/DVB (11425): gspca - m5602: Move the vflip quirk to probe stage.
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>
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 63 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.h | 4 |
2 files changed, 46 insertions, 21 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 0cff90579772..9c79a516db61 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -65,7 +65,7 @@ static | |||
65 | DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") | 65 | DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") |
66 | } | 66 | } |
67 | }, | 67 | }, |
68 | { } | 68 | {} |
69 | }; | 69 | }; |
70 | 70 | ||
71 | const static struct ctrl ov9650_ctrls[] = { | 71 | const static struct ctrl ov9650_ctrls[] = { |
@@ -249,7 +249,7 @@ int ov9650_probe(struct sd *sd) | |||
249 | 249 | ||
250 | info("Probing for an ov9650 sensor"); | 250 | info("Probing for an ov9650 sensor"); |
251 | 251 | ||
252 | /* Run the pre-init to actually probe the unit */ | 252 | /* Run the pre-init before probing the sensor */ |
253 | for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { | 253 | for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { |
254 | u8 data = preinit_ov9650[i][2]; | 254 | u8 data = preinit_ov9650[i][2]; |
255 | if (preinit_ov9650[i][0] == SENSOR) | 255 | if (preinit_ov9650[i][0] == SENSOR) |
@@ -273,11 +273,9 @@ int ov9650_probe(struct sd *sd) | |||
273 | info("Detected an ov9650 sensor"); | 273 | info("Detected an ov9650 sensor"); |
274 | goto sensor_found; | 274 | goto sensor_found; |
275 | } | 275 | } |
276 | |||
277 | return -ENODEV; | 276 | return -ENODEV; |
278 | 277 | ||
279 | sensor_found: | 278 | sensor_found: |
280 | |||
281 | sensor_settings = kmalloc( | 279 | sensor_settings = kmalloc( |
282 | ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL); | 280 | ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL); |
283 | if (!sensor_settings) | 281 | if (!sensor_settings) |
@@ -292,6 +290,11 @@ sensor_found: | |||
292 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; | 290 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; |
293 | sd->sensor_priv = sensor_settings; | 291 | sd->sensor_priv = sensor_settings; |
294 | 292 | ||
293 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { | ||
294 | info("vflip quirk active"); | ||
295 | sensor_settings[VFLIP_IDX] = 1; | ||
296 | } | ||
297 | |||
295 | return 0; | 298 | return 0; |
296 | } | 299 | } |
297 | 300 | ||
@@ -299,6 +302,7 @@ int ov9650_init(struct sd *sd) | |||
299 | { | 302 | { |
300 | int i, err = 0; | 303 | int i, err = 0; |
301 | u8 data; | 304 | u8 data; |
305 | s32 *sensor_settings = sd->sensor_priv; | ||
302 | 306 | ||
303 | if (dump_sensor) | 307 | if (dump_sensor) |
304 | ov9650_dump_registers(sd); | 308 | ov9650_dump_registers(sd); |
@@ -312,11 +316,35 @@ int ov9650_init(struct sd *sd) | |||
312 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); | 316 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); |
313 | } | 317 | } |
314 | 318 | ||
315 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { | 319 | err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); |
316 | info("vflip quirk active"); | 320 | if (err < 0) |
317 | data = 0x30; | 321 | return err; |
318 | err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1); | 322 | |
319 | } | 323 | err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); |
324 | if (err < 0) | ||
325 | return err; | ||
326 | |||
327 | err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); | ||
328 | if (err < 0) | ||
329 | return err; | ||
330 | |||
331 | err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); | ||
332 | if (err < 0) | ||
333 | return err; | ||
334 | |||
335 | err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
336 | if (err < 0) | ||
337 | return err; | ||
338 | |||
339 | err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | |||
343 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
344 | if (err < 0) | ||
345 | return err; | ||
346 | |||
347 | err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); | ||
320 | 348 | ||
321 | return err; | 349 | return err; |
322 | } | 350 | } |
@@ -339,6 +367,9 @@ int ov9650_start(struct sd *sd) | |||
339 | if (width <= 320) | 367 | if (width <= 320) |
340 | hor_offs /= 2; | 368 | hor_offs /= 2; |
341 | 369 | ||
370 | if (err < 0) | ||
371 | return err; | ||
372 | |||
342 | /* Synthesize the vsync/hsync setup */ | 373 | /* Synthesize the vsync/hsync setup */ |
343 | for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { | 374 | for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { |
344 | if (res_init_ov9650[i][0] == BRIDGE) | 375 | if (res_init_ov9650[i][0] == BRIDGE) |
@@ -635,12 +666,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
635 | if (err < 0) | 666 | if (err < 0) |
636 | return err; | 667 | return err; |
637 | 668 | ||
638 | if (dmi_check_system(ov9650_flip_dmi_table)) | 669 | i2c_data = ((i2c_data & 0xdf) | ((val & 0x01) << 5)); |
639 | i2c_data = ((i2c_data & 0xdf) | | ||
640 | (((val ? 0 : 1) & 0x01) << 5)); | ||
641 | else | ||
642 | i2c_data = ((i2c_data & 0xdf) | | ||
643 | ((val & 0x01) << 5)); | ||
644 | 670 | ||
645 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 671 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
646 | 672 | ||
@@ -672,12 +698,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
672 | if (err < 0) | 698 | if (err < 0) |
673 | return err; | 699 | return err; |
674 | 700 | ||
675 | if (dmi_check_system(ov9650_flip_dmi_table)) | 701 | i2c_data = ((i2c_data & 0xef) | ((val & 0x01) << 4)); |
676 | i2c_data = ((i2c_data & 0xef) | | ||
677 | (((val ? 0 : 1) & 0x01) << 4)); | ||
678 | else | ||
679 | i2c_data = ((i2c_data & 0xef) | | ||
680 | ((val & 0x01) << 4)); | ||
681 | 702 | ||
682 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 703 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
683 | 704 | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index 1f27a857bf3f..fcc54e4c0f4f 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -218,6 +218,10 @@ static const unsigned char init_ov9650[][3] = | |||
218 | 218 | ||
219 | /* Reset chip */ | 219 | /* Reset chip */ |
220 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 220 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
221 | /* One extra reset is needed in order to make the sensor behave | ||
222 | properly when resuming from ram */ | ||
223 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | ||
224 | |||
221 | /* Enable double clock */ | 225 | /* Enable double clock */ |
222 | {SENSOR, OV9650_CLKRC, 0x80}, | 226 | {SENSOR, OV9650_CLKRC, 0x80}, |
223 | /* Do something out of spec with the power */ | 227 | /* Do something out of spec with the power */ |