diff options
Diffstat (limited to 'drivers/media')
-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 */ |