diff options
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 68f651fb508..cf917b2aaa8 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -67,18 +67,29 @@ int ov9650_read_sensor(struct sd *sd, const u8 address, | |||
67 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); | 67 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); |
68 | } while ((*i2c_data & I2C_BUSY) && !err); | 68 | } while ((*i2c_data & I2C_BUSY) && !err); |
69 | 69 | ||
70 | m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, | 70 | err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, |
71 | ov9650.i2c_slave_id); | 71 | ov9650.i2c_slave_id); |
72 | m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); | 72 | if (err < 0) |
73 | m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); | 73 | goto out; |
74 | m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); | ||
75 | 74 | ||
76 | for (i = 0; i < len; i++) { | 75 | err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); |
76 | if (err < 0) | ||
77 | goto out; | ||
78 | |||
79 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); | ||
80 | if (err < 0) | ||
81 | goto out; | ||
82 | |||
83 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); | ||
84 | |||
85 | for (i = 0; (i < len) && !err; i++) { | ||
77 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 86 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
78 | 87 | ||
79 | PDEBUG(D_CONF, "Reading sensor register " | 88 | PDEBUG(D_CONF, "Reading sensor register " |
80 | "0x%x containing 0x%x ", address, *i2c_data); | 89 | "0x%x containing 0x%x ", address, *i2c_data); |
81 | } | 90 | } |
91 | |||
92 | out: | ||
82 | return (err < 0) ? err : 0; | 93 | return (err < 0) ? err : 0; |
83 | } | 94 | } |
84 | 95 | ||
@@ -103,7 +114,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address, | |||
103 | /* Special case larger sensor writes */ | 114 | /* Special case larger sensor writes */ |
104 | p = buf + 16; | 115 | p = buf + 16; |
105 | 116 | ||
106 | /* Copy a four byte write sequence for each byte to be written to */ | 117 | /* Copy a four byte write sequence for each byte to write over the I2C bus */ |
107 | for (i = 0; i < len; i++) { | 118 | for (i = 0; i < len; i++) { |
108 | memcpy(p, sensor_urb_skeleton + 16, 4); | 119 | memcpy(p, sensor_urb_skeleton + 16, 4); |
109 | p[3] = i2c_data[i]; | 120 | p[3] = i2c_data[i]; |
@@ -190,28 +201,28 @@ int ov9650_init(struct sd *sd) | |||
190 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); | 201 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); |
191 | } | 202 | } |
192 | 203 | ||
193 | if (!err && dmi_check_system(ov9650_flip_dmi_table)) { | 204 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { |
194 | info("vflip quirk active"); | 205 | info("vflip quirk active"); |
195 | data = 0x30; | 206 | data = 0x30; |
196 | err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); | 207 | err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); |
197 | } | 208 | } |
198 | 209 | ||
199 | return (err < 0) ? err : 0; | 210 | return err; |
200 | } | 211 | } |
201 | 212 | ||
202 | int ov9650_power_down(struct sd *sd) | 213 | int ov9650_power_down(struct sd *sd) |
203 | { | 214 | { |
204 | int i; | 215 | int i, err = 0; |
205 | for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) { | 216 | for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) { |
206 | u8 data = power_down_ov9650[i][2]; | 217 | u8 data = power_down_ov9650[i][2]; |
207 | if (power_down_ov9650[i][0] == SENSOR) | 218 | if (power_down_ov9650[i][0] == SENSOR) |
208 | ov9650_write_sensor(sd, | 219 | err = ov9650_write_sensor(sd, |
209 | power_down_ov9650[i][1], &data, 1); | 220 | power_down_ov9650[i][1], &data, 1); |
210 | else | 221 | else |
211 | m5602_write_bridge(sd, power_down_ov9650[i][1], data); | 222 | err = m5602_write_bridge(sd, power_down_ov9650[i][1], data); |
212 | } | 223 | } |
213 | 224 | ||
214 | return 0; | 225 | return err; |
215 | } | 226 | } |
216 | 227 | ||
217 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 228 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -237,7 +248,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
237 | 248 | ||
238 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 249 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
239 | out: | 250 | out: |
240 | return (err < 0) ? err : 0; | 251 | return err; |
241 | } | 252 | } |
242 | 253 | ||
243 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 254 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
@@ -268,7 +279,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
268 | err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); | 279 | err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); |
269 | 280 | ||
270 | out: | 281 | out: |
271 | return (err < 0) ? err : 0; | 282 | return err; |
272 | } | 283 | } |
273 | 284 | ||
274 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 285 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -283,7 +294,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
283 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); | 294 | err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); |
284 | *val |= i2c_data; | 295 | *val |= i2c_data; |
285 | PDEBUG(D_V4L2, "Read gain %d", *val); | 296 | PDEBUG(D_V4L2, "Read gain %d", *val); |
286 | return (err < 0) ? err : 0; | 297 | return err; |
287 | } | 298 | } |
288 | 299 | ||
289 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 300 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
@@ -304,7 +315,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
304 | /* The 8 LSBs */ | 315 | /* The 8 LSBs */ |
305 | i2c_data = val & 0xff; | 316 | i2c_data = val & 0xff; |
306 | err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); | 317 | err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); |
307 | return (err < 0) ? err : 0; | 318 | return err; |
308 | } | 319 | } |
309 | 320 | ||
310 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 321 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -318,7 +329,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
318 | 329 | ||
319 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 330 | PDEBUG(D_V4L2, "Read red gain %d", *val); |
320 | 331 | ||
321 | return (err < 0) ? err : 0; | 332 | return err; |
322 | } | 333 | } |
323 | 334 | ||
324 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 335 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -333,7 +344,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
333 | i2c_data = val & 0xff; | 344 | i2c_data = val & 0xff; |
334 | err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); | 345 | err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); |
335 | 346 | ||
336 | return (err < 0) ? err : 0; | 347 | return err; |
337 | } | 348 | } |
338 | 349 | ||
339 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 350 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -347,7 +358,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
347 | 358 | ||
348 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | 359 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
349 | 360 | ||
350 | return (err < 0) ? err : 0; | 361 | return err; |
351 | } | 362 | } |
352 | 363 | ||
353 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 364 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -362,7 +373,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
362 | i2c_data = val & 0xff; | 373 | i2c_data = val & 0xff; |
363 | err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); | 374 | err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); |
364 | 375 | ||
365 | return (err < 0) ? err : 0; | 376 | return err; |
366 | } | 377 | } |
367 | 378 | ||
368 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 379 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -378,7 +389,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
378 | *val = (i2c_data & OV9650_HFLIP) >> 5; | 389 | *val = (i2c_data & OV9650_HFLIP) >> 5; |
379 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 390 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
380 | 391 | ||
381 | return (err < 0) ? err : 0; | 392 | return err; |
382 | } | 393 | } |
383 | 394 | ||
384 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 395 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -394,14 +405,14 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
394 | 405 | ||
395 | if (dmi_check_system(ov9650_flip_dmi_table)) | 406 | if (dmi_check_system(ov9650_flip_dmi_table)) |
396 | i2c_data = ((i2c_data & 0xdf) | | 407 | i2c_data = ((i2c_data & 0xdf) | |
397 | (((val ? 0 : 1) & 0x01) << 5)); | 408 | (((val ? 0 : 1) & 0x01) << 5)); |
398 | else | 409 | else |
399 | i2c_data = ((i2c_data & 0xdf) | | 410 | i2c_data = ((i2c_data & 0xdf) | |
400 | ((val & 0x01) << 5)); | 411 | ((val & 0x01) << 5)); |
401 | 412 | ||
402 | err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 413 | err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
403 | out: | 414 | out: |
404 | return (err < 0) ? err : 0; | 415 | return err; |
405 | } | 416 | } |
406 | 417 | ||
407 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 418 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -417,7 +428,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
417 | *val = (i2c_data & 0x10) >> 4; | 428 | *val = (i2c_data & 0x10) >> 4; |
418 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 429 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
419 | 430 | ||
420 | return (err < 0) ? err : 0; | 431 | return err; |
421 | } | 432 | } |
422 | 433 | ||
423 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 434 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -440,7 +451,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
440 | 451 | ||
441 | err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 452 | err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
442 | out: | 453 | out: |
443 | return (err < 0) ? err : 0; | 454 | return err; |
444 | } | 455 | } |
445 | 456 | ||
446 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 457 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -458,7 +469,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | |||
458 | *val |= i2c_data; | 469 | *val |= i2c_data; |
459 | PDEBUG(D_V4L2, "Read gain %d", *val); | 470 | PDEBUG(D_V4L2, "Read gain %d", *val); |
460 | out: | 471 | out: |
461 | return (err < 0) ? err : 0; | 472 | return err; |
462 | } | 473 | } |
463 | 474 | ||
464 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 475 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) |
@@ -486,7 +497,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
486 | err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); | 497 | err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); |
487 | 498 | ||
488 | out: | 499 | out: |
489 | return (err < 0) ? err : 0; | 500 | return err; |
490 | } | 501 | } |
491 | 502 | ||
492 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 503 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -499,7 +510,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
499 | *val = (i2c_data & OV9650_AWB_EN) >> 1; | 510 | *val = (i2c_data & OV9650_AWB_EN) >> 1; |
500 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); | 511 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); |
501 | 512 | ||
502 | return (err < 0) ? err : 0; | 513 | return err; |
503 | } | 514 | } |
504 | 515 | ||
505 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 516 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) |
@@ -516,7 +527,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
516 | i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); | 527 | i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); |
517 | err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | 528 | err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
518 | out: | 529 | out: |
519 | return (err < 0) ? err : 0; | 530 | return err; |
520 | } | 531 | } |
521 | 532 | ||
522 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 533 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -529,7 +540,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
529 | *val = (i2c_data & OV9650_AGC_EN) >> 2; | 540 | *val = (i2c_data & OV9650_AGC_EN) >> 2; |
530 | PDEBUG(D_V4L2, "Read auto gain control %d", *val); | 541 | PDEBUG(D_V4L2, "Read auto gain control %d", *val); |
531 | 542 | ||
532 | return (err < 0) ? err : 0; | 543 | return err; |
533 | } | 544 | } |
534 | 545 | ||
535 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 546 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) |
@@ -546,7 +557,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
546 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); | 557 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); |
547 | err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | 558 | err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
548 | out: | 559 | out: |
549 | return (err < 0) ? err : 0; | 560 | return err; |
550 | } | 561 | } |
551 | 562 | ||
552 | void ov9650_dump_registers(struct sd *sd) | 563 | void ov9650_dump_registers(struct sd *sd) |