diff options
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 1683 |
1 files changed, 997 insertions, 686 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 6cf6855aa506..e1c3b9328ace 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -75,14 +75,14 @@ struct sd { | |||
75 | 75 | ||
76 | struct gspca_ctrl ctrls[NCTRL]; | 76 | struct gspca_ctrl ctrls[NCTRL]; |
77 | 77 | ||
78 | __u8 packet_nr; | 78 | u8 packet_nr; |
79 | 79 | ||
80 | char bridge; | 80 | char bridge; |
81 | #define BRIDGE_OV511 0 | 81 | #define BRIDGE_OV511 0 |
82 | #define BRIDGE_OV511PLUS 1 | 82 | #define BRIDGE_OV511PLUS 1 |
83 | #define BRIDGE_OV518 2 | 83 | #define BRIDGE_OV518 2 |
84 | #define BRIDGE_OV518PLUS 3 | 84 | #define BRIDGE_OV518PLUS 3 |
85 | #define BRIDGE_OV519 4 | 85 | #define BRIDGE_OV519 4 /* = ov530 */ |
86 | #define BRIDGE_OVFX2 5 | 86 | #define BRIDGE_OVFX2 5 |
87 | #define BRIDGE_W9968CF 6 | 87 | #define BRIDGE_W9968CF 6 |
88 | #define BRIDGE_MASK 7 | 88 | #define BRIDGE_MASK 7 |
@@ -94,42 +94,44 @@ struct sd { | |||
94 | char snapshot_needs_reset; | 94 | char snapshot_needs_reset; |
95 | 95 | ||
96 | /* Determined by sensor type */ | 96 | /* Determined by sensor type */ |
97 | __u8 sif; | 97 | u8 sif; |
98 | 98 | ||
99 | __u8 quality; | 99 | u8 quality; |
100 | #define QUALITY_MIN 50 | 100 | #define QUALITY_MIN 50 |
101 | #define QUALITY_MAX 70 | 101 | #define QUALITY_MAX 70 |
102 | #define QUALITY_DEF 50 | 102 | #define QUALITY_DEF 50 |
103 | 103 | ||
104 | __u8 stopped; /* Streaming is temporarily paused */ | 104 | u8 stopped; /* Streaming is temporarily paused */ |
105 | __u8 first_frame; | 105 | u8 first_frame; |
106 | 106 | ||
107 | __u8 frame_rate; /* current Framerate */ | 107 | u8 frame_rate; /* current Framerate */ |
108 | __u8 clockdiv; /* clockdiv override */ | 108 | u8 clockdiv; /* clockdiv override */ |
109 | 109 | ||
110 | char sensor; /* Type of image sensor chip (SEN_*) */ | 110 | s8 sensor; /* Type of image sensor chip (SEN_*) */ |
111 | #define SEN_UNKNOWN 0 | ||
112 | #define SEN_OV2610 1 | ||
113 | #define SEN_OV3610 2 | ||
114 | #define SEN_OV6620 3 | ||
115 | #define SEN_OV6630 4 | ||
116 | #define SEN_OV66308AF 5 | ||
117 | #define SEN_OV7610 6 | ||
118 | #define SEN_OV7620 7 | ||
119 | #define SEN_OV7620AE 8 | ||
120 | #define SEN_OV7640 9 | ||
121 | #define SEN_OV7648 10 | ||
122 | #define SEN_OV7670 11 | ||
123 | #define SEN_OV76BE 12 | ||
124 | #define SEN_OV8610 13 | ||
125 | 111 | ||
126 | u8 sensor_addr; | 112 | u8 sensor_addr; |
127 | int sensor_width; | 113 | u16 sensor_width; |
128 | int sensor_height; | 114 | u16 sensor_height; |
129 | int sensor_reg_cache[256]; | 115 | s16 sensor_reg_cache[256]; |
130 | 116 | ||
131 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 117 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
132 | }; | 118 | }; |
119 | enum sensors { | ||
120 | SEN_OV2610, | ||
121 | SEN_OV3610, | ||
122 | SEN_OV6620, | ||
123 | SEN_OV6630, | ||
124 | SEN_OV66308AF, | ||
125 | SEN_OV7610, | ||
126 | SEN_OV7620, | ||
127 | SEN_OV7620AE, | ||
128 | SEN_OV7640, | ||
129 | SEN_OV7648, | ||
130 | SEN_OV7660, | ||
131 | SEN_OV7670, | ||
132 | SEN_OV76BE, | ||
133 | SEN_OV8610, | ||
134 | }; | ||
133 | 135 | ||
134 | /* Note this is a bit of a hack, but the w9968cf driver needs the code for all | 136 | /* Note this is a bit of a hack, but the w9968cf driver needs the code for all |
135 | the ov sensors which is already present here. When we have the time we | 137 | the ov sensors which is already present here. When we have the time we |
@@ -182,7 +184,7 @@ static const struct ctrl sd_ctrls[] = { | |||
182 | }, | 184 | }, |
183 | .set_control = setcolors, | 185 | .set_control = setcolors, |
184 | }, | 186 | }, |
185 | /* The flip controls work with ov7670 only */ | 187 | /* The flip controls work for sensors ov7660 and ov7670 only */ |
186 | [HFLIP] = { | 188 | [HFLIP] = { |
187 | { | 189 | { |
188 | .id = V4L2_CID_HFLIP, | 190 | .id = V4L2_CID_HFLIP, |
@@ -225,7 +227,7 @@ static const struct ctrl sd_ctrls[] = { | |||
225 | .type = V4L2_CTRL_TYPE_MENU, | 227 | .type = V4L2_CTRL_TYPE_MENU, |
226 | .name = "Light frequency filter", | 228 | .name = "Light frequency filter", |
227 | .minimum = 0, | 229 | .minimum = 0, |
228 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | 230 | .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */ |
229 | .step = 1, | 231 | .step = 1, |
230 | .default_value = 0, | 232 | .default_value = 0, |
231 | }, | 233 | }, |
@@ -233,6 +235,53 @@ static const struct ctrl sd_ctrls[] = { | |||
233 | }, | 235 | }, |
234 | }; | 236 | }; |
235 | 237 | ||
238 | /* table of the disabled controls */ | ||
239 | static const unsigned ctrl_dis[] = { | ||
240 | [SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ | ||
241 | |||
242 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ | ||
243 | |||
244 | [SEN_OV6620] = (1 << HFLIP) | | ||
245 | (1 << VFLIP), | ||
246 | |||
247 | [SEN_OV6630] = (1 << HFLIP) | | ||
248 | (1 << VFLIP), | ||
249 | |||
250 | [SEN_OV66308AF] = (1 << HFLIP) | | ||
251 | (1 << VFLIP), | ||
252 | |||
253 | [SEN_OV7610] = (1 << HFLIP) | | ||
254 | (1 << VFLIP), | ||
255 | |||
256 | [SEN_OV7620] = (1 << HFLIP) | | ||
257 | (1 << VFLIP), | ||
258 | |||
259 | [SEN_OV7620AE] = (1 << HFLIP) | | ||
260 | (1 << VFLIP), | ||
261 | |||
262 | [SEN_OV7640] = (1 << HFLIP) | | ||
263 | (1 << VFLIP) | | ||
264 | (1 << AUTOBRIGHT) | | ||
265 | (1 << CONTRAST), | ||
266 | |||
267 | [SEN_OV7648] = (1 << HFLIP) | | ||
268 | (1 << VFLIP) | | ||
269 | (1 << AUTOBRIGHT) | | ||
270 | (1 << CONTRAST), | ||
271 | |||
272 | [SEN_OV7660] = (1 << AUTOBRIGHT), | ||
273 | |||
274 | [SEN_OV7670] = (1 << COLORS) | | ||
275 | (1 << AUTOBRIGHT), | ||
276 | |||
277 | [SEN_OV76BE] = (1 << HFLIP) | | ||
278 | (1 << VFLIP), | ||
279 | |||
280 | [SEN_OV8610] = (1 << HFLIP) | | ||
281 | (1 << VFLIP) | | ||
282 | (1 << FREQ), | ||
283 | }; | ||
284 | |||
236 | static const struct v4l2_pix_format ov519_vga_mode[] = { | 285 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
237 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 286 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
238 | .bytesperline = 320, | 287 | .bytesperline = 320, |
@@ -412,7 +461,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
412 | .priv = 0}, | 461 | .priv = 0}, |
413 | }; | 462 | }; |
414 | 463 | ||
415 | |||
416 | /* Registers common to OV511 / OV518 */ | 464 | /* Registers common to OV511 / OV518 */ |
417 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ | 465 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ |
418 | #define R51x_SYS_RESET 0x50 | 466 | #define R51x_SYS_RESET 0x50 |
@@ -420,7 +468,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
420 | #define OV511_RESET_OMNICE 0x08 | 468 | #define OV511_RESET_OMNICE 0x08 |
421 | #define R51x_SYS_INIT 0x53 | 469 | #define R51x_SYS_INIT 0x53 |
422 | #define R51x_SYS_SNAP 0x52 | 470 | #define R51x_SYS_SNAP 0x52 |
423 | #define R51x_SYS_CUST_ID 0x5F | 471 | #define R51x_SYS_CUST_ID 0x5f |
424 | #define R51x_COMP_LUT_BEGIN 0x80 | 472 | #define R51x_COMP_LUT_BEGIN 0x80 |
425 | 473 | ||
426 | /* OV511 Camera interface register numbers */ | 474 | /* OV511 Camera interface register numbers */ |
@@ -435,13 +483,13 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
435 | #define R511_CAM_OPTS 0x18 | 483 | #define R511_CAM_OPTS 0x18 |
436 | 484 | ||
437 | #define R511_SNAP_FRAME 0x19 | 485 | #define R511_SNAP_FRAME 0x19 |
438 | #define R511_SNAP_PXCNT 0x1A | 486 | #define R511_SNAP_PXCNT 0x1a |
439 | #define R511_SNAP_LNCNT 0x1B | 487 | #define R511_SNAP_LNCNT 0x1b |
440 | #define R511_SNAP_PXDIV 0x1C | 488 | #define R511_SNAP_PXDIV 0x1c |
441 | #define R511_SNAP_LNDIV 0x1D | 489 | #define R511_SNAP_LNDIV 0x1d |
442 | #define R511_SNAP_UV_EN 0x1E | 490 | #define R511_SNAP_UV_EN 0x1e |
443 | #define R511_SNAP_UV_EN 0x1E | 491 | #define R511_SNAP_UV_EN 0x1e |
444 | #define R511_SNAP_OPTS 0x1F | 492 | #define R511_SNAP_OPTS 0x1f |
445 | 493 | ||
446 | #define R511_DRAM_FLOW_CTL 0x20 | 494 | #define R511_DRAM_FLOW_CTL 0x20 |
447 | #define R511_FIFO_OPTS 0x31 | 495 | #define R511_FIFO_OPTS 0x31 |
@@ -466,13 +514,14 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
466 | #define OV519_R25_FORMAT 0x25 | 514 | #define OV519_R25_FORMAT 0x25 |
467 | 515 | ||
468 | /* OV519 System Controller register numbers */ | 516 | /* OV519 System Controller register numbers */ |
469 | #define OV519_SYS_RESET1 0x51 | 517 | #define OV519_R51_RESET1 0x51 |
470 | #define OV519_SYS_EN_CLK1 0x54 | 518 | #define OV519_R54_EN_CLK1 0x54 |
519 | #define OV519_R57_SNAPSHOT 0x57 | ||
471 | 520 | ||
472 | #define OV519_GPIO_DATA_OUT0 0x71 | 521 | #define OV519_GPIO_DATA_OUT0 0x71 |
473 | #define OV519_GPIO_IO_CTRL0 0x72 | 522 | #define OV519_GPIO_IO_CTRL0 0x72 |
474 | 523 | ||
475 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ | 524 | /*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */ |
476 | 525 | ||
477 | /* | 526 | /* |
478 | * The FX2 chip does not give us a zero length read at end of frame. | 527 | * The FX2 chip does not give us a zero length read at end of frame. |
@@ -526,80 +575,81 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
526 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ | 575 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ |
527 | #define OV7610_REG_COM_I 0x29 /* misc settings */ | 576 | #define OV7610_REG_COM_I 0x29 /* misc settings */ |
528 | 577 | ||
529 | /* OV7670 registers */ | 578 | /* OV7660 and OV7670 registers */ |
530 | #define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ | 579 | #define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ |
531 | #define OV7670_REG_BLUE 0x01 /* blue gain */ | 580 | #define OV7670_R01_BLUE 0x01 /* blue gain */ |
532 | #define OV7670_REG_RED 0x02 /* red gain */ | 581 | #define OV7670_R02_RED 0x02 /* red gain */ |
533 | #define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ | 582 | #define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ |
534 | #define OV7670_REG_COM1 0x04 /* Control 1 */ | 583 | #define OV7670_R04_COM1 0x04 /* Control 1 */ |
535 | #define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */ | 584 | /*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */ |
536 | #define OV7670_REG_COM3 0x0c /* Control 3 */ | 585 | #define OV7670_R0C_COM3 0x0c /* Control 3 */ |
537 | #define OV7670_REG_COM4 0x0d /* Control 4 */ | 586 | #define OV7670_R0D_COM4 0x0d /* Control 4 */ |
538 | #define OV7670_REG_COM5 0x0e /* All "reserved" */ | 587 | #define OV7670_R0E_COM5 0x0e /* All "reserved" */ |
539 | #define OV7670_REG_COM6 0x0f /* Control 6 */ | 588 | #define OV7670_R0F_COM6 0x0f /* Control 6 */ |
540 | #define OV7670_REG_AECH 0x10 /* More bits of AEC value */ | 589 | #define OV7670_R10_AECH 0x10 /* More bits of AEC value */ |
541 | #define OV7670_REG_CLKRC 0x11 /* Clock control */ | 590 | #define OV7670_R11_CLKRC 0x11 /* Clock control */ |
542 | #define OV7670_REG_COM7 0x12 /* Control 7 */ | 591 | #define OV7670_R12_COM7 0x12 /* Control 7 */ |
543 | #define OV7670_COM7_FMT_VGA 0x00 | 592 | #define OV7670_COM7_FMT_VGA 0x00 |
544 | #define OV7670_COM7_YUV 0x00 /* YUV */ | 593 | /*#define OV7670_COM7_YUV 0x00 * YUV */ |
545 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ | 594 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ |
546 | #define OV7670_COM7_FMT_MASK 0x38 | 595 | #define OV7670_COM7_FMT_MASK 0x38 |
547 | #define OV7670_COM7_RESET 0x80 /* Register reset */ | 596 | #define OV7670_COM7_RESET 0x80 /* Register reset */ |
548 | #define OV7670_REG_COM8 0x13 /* Control 8 */ | 597 | #define OV7670_R13_COM8 0x13 /* Control 8 */ |
549 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ | 598 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ |
550 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ | 599 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ |
551 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ | 600 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ |
552 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ | 601 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ |
553 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ | 602 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ |
554 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ | 603 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ |
555 | #define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */ | 604 | #define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */ |
556 | #define OV7670_REG_COM10 0x15 /* Control 10 */ | 605 | #define OV7670_R15_COM10 0x15 /* Control 10 */ |
557 | #define OV7670_REG_HSTART 0x17 /* Horiz start high bits */ | 606 | #define OV7670_R17_HSTART 0x17 /* Horiz start high bits */ |
558 | #define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */ | 607 | #define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */ |
559 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | 608 | #define OV7670_R19_VSTART 0x19 /* Vert start high bits */ |
560 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | 609 | #define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */ |
561 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | 610 | #define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */ |
562 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ | 611 | #define OV7670_MVFP_VFLIP 0x10 /* vertical flip */ |
563 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | 612 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ |
564 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | 613 | #define OV7670_R24_AEW 0x24 /* AGC upper limit */ |
565 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | 614 | #define OV7670_R25_AEB 0x25 /* AGC lower limit */ |
566 | #define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */ | 615 | #define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */ |
567 | #define OV7670_REG_HREF 0x32 /* HREF pieces */ | 616 | #define OV7670_R32_HREF 0x32 /* HREF pieces */ |
568 | #define OV7670_REG_TSLB 0x3a /* lots of stuff */ | 617 | #define OV7670_R3A_TSLB 0x3a /* lots of stuff */ |
569 | #define OV7670_REG_COM11 0x3b /* Control 11 */ | 618 | #define OV7670_R3B_COM11 0x3b /* Control 11 */ |
570 | #define OV7670_COM11_EXP 0x02 | 619 | #define OV7670_COM11_EXP 0x02 |
571 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ | 620 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ |
572 | #define OV7670_REG_COM12 0x3c /* Control 12 */ | 621 | #define OV7670_R3C_COM12 0x3c /* Control 12 */ |
573 | #define OV7670_REG_COM13 0x3d /* Control 13 */ | 622 | #define OV7670_R3D_COM13 0x3d /* Control 13 */ |
574 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ | 623 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ |
575 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ | 624 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ |
576 | #define OV7670_REG_COM14 0x3e /* Control 14 */ | 625 | #define OV7670_R3E_COM14 0x3e /* Control 14 */ |
577 | #define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */ | 626 | #define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */ |
578 | #define OV7670_REG_COM15 0x40 /* Control 15 */ | 627 | #define OV7670_R40_COM15 0x40 /* Control 15 */ |
579 | #define OV7670_COM15_R00FF 0xc0 /* 00 to FF */ | 628 | /*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */ |
580 | #define OV7670_REG_COM16 0x41 /* Control 16 */ | 629 | #define OV7670_R41_COM16 0x41 /* Control 16 */ |
581 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ | 630 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ |
582 | #define OV7670_REG_BRIGHT 0x55 /* Brightness */ | 631 | /* end of ov7660 common registers */ |
583 | #define OV7670_REG_CONTRAS 0x56 /* Contrast control */ | 632 | #define OV7670_R55_BRIGHT 0x55 /* Brightness */ |
584 | #define OV7670_REG_GFIX 0x69 /* Fix gain control */ | 633 | #define OV7670_R56_CONTRAS 0x56 /* Contrast control */ |
585 | #define OV7670_REG_RGB444 0x8c /* RGB 444 control */ | 634 | #define OV7670_R69_GFIX 0x69 /* Fix gain control */ |
586 | #define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ | 635 | /*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */ |
587 | #define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ | 636 | #define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */ |
588 | #define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */ | 637 | #define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ |
589 | #define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ | 638 | #define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */ |
590 | #define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ | 639 | #define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ |
591 | #define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ | 640 | #define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ |
592 | #define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ | 641 | #define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ |
593 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | 642 | #define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ |
594 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | 643 | #define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */ |
644 | #define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */ | ||
595 | 645 | ||
596 | struct ov_regvals { | 646 | struct ov_regvals { |
597 | __u8 reg; | 647 | u8 reg; |
598 | __u8 val; | 648 | u8 val; |
599 | }; | 649 | }; |
600 | struct ov_i2c_regvals { | 650 | struct ov_i2c_regvals { |
601 | __u8 reg; | 651 | u8 reg; |
602 | __u8 val; | 652 | u8 val; |
603 | }; | 653 | }; |
604 | 654 | ||
605 | /* Settings for OV2610 camera chip */ | 655 | /* Settings for OV2610 camera chip */ |
@@ -617,7 +667,6 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
617 | * "wait 4096 external clock ... to make sure the sensor is | 667 | * "wait 4096 external clock ... to make sure the sensor is |
618 | * stable and ready to access registers" i.e. 160us at 24MHz | 668 | * stable and ready to access registers" i.e. 160us at 24MHz |
619 | */ | 669 | */ |
620 | |||
621 | { 0x12, 0x80 }, /* COMH reset */ | 670 | { 0x12, 0x80 }, /* COMH reset */ |
622 | { 0x12, 0x00 }, /* QXGA, master */ | 671 | { 0x12, 0x00 }, /* QXGA, master */ |
623 | 672 | ||
@@ -650,7 +699,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
650 | * COMI[0] "Exposure control" | 699 | * COMI[0] "Exposure control" |
651 | * = 0 (0x00) .......0 "Manual" | 700 | * = 0 (0x00) .......0 "Manual" |
652 | */ | 701 | */ |
653 | { 0x13, 0xC0 }, | 702 | { 0x13, 0xc0 }, |
654 | 703 | ||
655 | /* | 704 | /* |
656 | * 09 COMC "Common Control C" | 705 | * 09 COMC "Common Control C" |
@@ -706,7 +755,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
706 | * COME[0] "Auto zero circuit select" | 755 | * COME[0] "Auto zero circuit select" |
707 | * = 1 (0x01) .......1 "On" | 756 | * = 1 (0x01) .......1 "On" |
708 | */ | 757 | */ |
709 | { 0x0d, 0xA1 }, | 758 | { 0x0d, 0xa1 }, |
710 | 759 | ||
711 | /* | 760 | /* |
712 | * 0E COMF "Common Control F" | 761 | * 0E COMF "Common Control F" |
@@ -770,7 +819,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
770 | * COMJ[0] "Reserved" | 819 | * COMJ[0] "Reserved" |
771 | * = 0 (0x00) .......0 | 820 | * = 0 (0x00) .......0 |
772 | */ | 821 | */ |
773 | { 0x14, 0xC6 }, | 822 | { 0x14, 0xc6 }, |
774 | 823 | ||
775 | /* | 824 | /* |
776 | * 15 COMK "Common Control K" | 825 | * 15 COMK "Common Control K" |
@@ -876,7 +925,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
876 | * FVOPT[7:0] "Range" | 925 | * FVOPT[7:0] "Range" |
877 | * = 31 (0x1F) 00011111 | 926 | * = 31 (0x1F) 00011111 |
878 | */ | 927 | */ |
879 | { 0x3c, 0x1F }, | 928 | { 0x3c, 0x1f }, |
880 | 929 | ||
881 | /* | 930 | /* |
882 | * 44 Undocumented = 0 (0x00) 00000000 | 931 | * 44 Undocumented = 0 (0x00) 00000000 |
@@ -925,7 +974,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
925 | * 48[7:0] "It's a secret" | 974 | * 48[7:0] "It's a secret" |
926 | * = 192 (0xC0) 11000000 | 975 | * = 192 (0xC0) 11000000 |
927 | */ | 976 | */ |
928 | { 0x48, 0xC0 }, | 977 | { 0x48, 0xc0 }, |
929 | 978 | ||
930 | /* | 979 | /* |
931 | * 49 Undocumented = 25 (0x19) 00011001 | 980 | * 49 Undocumented = 25 (0x19) 00011001 |
@@ -939,18 +988,18 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
939 | * 4B[7:0] "It's a secret" | 988 | * 4B[7:0] "It's a secret" |
940 | * = 128 (0x80) 10000000 | 989 | * = 128 (0x80) 10000000 |
941 | */ | 990 | */ |
942 | { 0x4B, 0x80 }, | 991 | { 0x4b, 0x80 }, |
943 | 992 | ||
944 | /* | 993 | /* |
945 | * 4D Undocumented = 196 (0xC4) 11000100 | 994 | * 4D Undocumented = 196 (0xC4) 11000100 |
946 | * 4D[7:0] "It's a secret" | 995 | * 4D[7:0] "It's a secret" |
947 | * = 196 (0xC4) 11000100 | 996 | * = 196 (0xC4) 11000100 |
948 | */ | 997 | */ |
949 | { 0x4D, 0xC4 }, | 998 | { 0x4d, 0xc4 }, |
950 | 999 | ||
951 | /* | 1000 | /* |
952 | * 35 VREF "Reference Voltage Control" | 1001 | * 35 VREF "Reference Voltage Control" |
953 | * = 76 (0x4C) 01001100 | 1002 | * = 76 (0x4c) 01001100 |
954 | * VREF[7:5] "Column high reference control" | 1003 | * VREF[7:5] "Column high reference control" |
955 | * = 2 (0x02) 010..... "higher voltage" | 1004 | * = 2 (0x02) 010..... "higher voltage" |
956 | * VREF[4:2] "Column low reference control" | 1005 | * VREF[4:2] "Column low reference control" |
@@ -958,21 +1007,21 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
958 | * VREF[1:0] "Reserved" | 1007 | * VREF[1:0] "Reserved" |
959 | * = 0 (0x00) ......00 | 1008 | * = 0 (0x00) ......00 |
960 | */ | 1009 | */ |
961 | { 0x35, 0x4C }, | 1010 | { 0x35, 0x4c }, |
962 | 1011 | ||
963 | /* | 1012 | /* |
964 | * 3D Undocumented = 0 (0x00) 00000000 | 1013 | * 3D Undocumented = 0 (0x00) 00000000 |
965 | * 3D[7:0] "It's a secret" | 1014 | * 3D[7:0] "It's a secret" |
966 | * = 0 (0x00) 00000000 | 1015 | * = 0 (0x00) 00000000 |
967 | */ | 1016 | */ |
968 | { 0x3D, 0x00 }, | 1017 | { 0x3d, 0x00 }, |
969 | 1018 | ||
970 | /* | 1019 | /* |
971 | * 3E Undocumented = 0 (0x00) 00000000 | 1020 | * 3E Undocumented = 0 (0x00) 00000000 |
972 | * 3E[7:0] "It's a secret" | 1021 | * 3E[7:0] "It's a secret" |
973 | * = 0 (0x00) 00000000 | 1022 | * = 0 (0x00) 00000000 |
974 | */ | 1023 | */ |
975 | { 0x3E, 0x00 }, | 1024 | { 0x3e, 0x00 }, |
976 | 1025 | ||
977 | /* | 1026 | /* |
978 | * 3B FREFB "Internal Reference Adjustment" | 1027 | * 3B FREFB "Internal Reference Adjustment" |
@@ -1012,7 +1061,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1012 | * VBLM[3:0] "Sensor current control" | 1061 | * VBLM[3:0] "Sensor current control" |
1013 | * = 10 (0x0A) ....1010 | 1062 | * = 10 (0x0A) ....1010 |
1014 | */ | 1063 | */ |
1015 | { 0x34, 0x5A }, | 1064 | { 0x34, 0x5a }, |
1016 | 1065 | ||
1017 | /* | 1066 | /* |
1018 | * 3B FREFB "Internal Reference Adjustment" | 1067 | * 3B FREFB "Internal Reference Adjustment" |
@@ -1078,7 +1127,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1078 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | 1127 | * HREFST[7:0] "Horizontal window start, 8 MSBs" |
1079 | * = 31 (0x1F) 00011111 | 1128 | * = 31 (0x1F) 00011111 |
1080 | */ | 1129 | */ |
1081 | { 0x17, 0x1F }, | 1130 | { 0x17, 0x1f }, |
1082 | 1131 | ||
1083 | /* | 1132 | /* |
1084 | * 18 HREFEND "Horizontal window end" | 1133 | * 18 HREFEND "Horizontal window end" |
@@ -1086,7 +1135,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1086 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | 1135 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" |
1087 | * = 95 (0x5F) 01011111 | 1136 | * = 95 (0x5F) 01011111 |
1088 | */ | 1137 | */ |
1089 | { 0x18, 0x5F }, | 1138 | { 0x18, 0x5f }, |
1090 | 1139 | ||
1091 | /* | 1140 | /* |
1092 | * 19 VSTRT "Vertical window start" | 1141 | * 19 VSTRT "Vertical window start" |
@@ -1126,7 +1175,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1126 | * COMA[1:0] "Vertical window start line control 2 LSBs" | 1175 | * COMA[1:0] "Vertical window start line control 2 LSBs" |
1127 | * = 2 (0x02) ......10 | 1176 | * = 2 (0x02) ......10 |
1128 | */ | 1177 | */ |
1129 | { 0x03, 0x4A }, | 1178 | { 0x03, 0x4a }, |
1130 | 1179 | ||
1131 | /* | 1180 | /* |
1132 | * 11 CLKRC "Clock Rate Control" | 1181 | * 11 CLKRC "Clock Rate Control" |
@@ -1183,7 +1232,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1183 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | 1232 | * HREFST[7:0] "Horizontal window start, 8 MSBs" |
1184 | * = 31 (0x1F) 00011111 | 1233 | * = 31 (0x1F) 00011111 |
1185 | */ | 1234 | */ |
1186 | { 0x17, 0x1F }, | 1235 | { 0x17, 0x1f }, |
1187 | 1236 | ||
1188 | /* | 1237 | /* |
1189 | * 18 HREFEND "Horizontal window end" | 1238 | * 18 HREFEND "Horizontal window end" |
@@ -1191,7 +1240,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1191 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | 1240 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" |
1192 | * = 95 (0x5F) 01011111 | 1241 | * = 95 (0x5F) 01011111 |
1193 | */ | 1242 | */ |
1194 | { 0x18, 0x5F }, | 1243 | { 0x18, 0x5f }, |
1195 | 1244 | ||
1196 | /* | 1245 | /* |
1197 | * 19 VSTRT "Vertical window start" | 1246 | * 19 VSTRT "Vertical window start" |
@@ -1231,7 +1280,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1231 | * COMA[1:0] "Vertical window start line control 2 LSBs" | 1280 | * COMA[1:0] "Vertical window start line control 2 LSBs" |
1232 | * = 2 (0x02) ......10 | 1281 | * = 2 (0x02) ......10 |
1233 | */ | 1282 | */ |
1234 | { 0x03, 0x4A }, | 1283 | { 0x03, 0x4a }, |
1235 | 1284 | ||
1236 | /* | 1285 | /* |
1237 | * 02 RED "Red Gain Control" | 1286 | * 02 RED "Red Gain Control" |
@@ -1241,7 +1290,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1241 | * RED[6:0] "Value" | 1290 | * RED[6:0] "Value" |
1242 | * = 47 (0x2F) .0101111 | 1291 | * = 47 (0x2F) .0101111 |
1243 | */ | 1292 | */ |
1244 | { 0x02, 0xAF }, | 1293 | { 0x02, 0xaf }, |
1245 | 1294 | ||
1246 | /* | 1295 | /* |
1247 | * 2D ADDVSL "VSYNC Pulse Width" | 1296 | * 2D ADDVSL "VSYNC Pulse Width" |
@@ -1249,7 +1298,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1249 | * ADDVSL[7:0] "VSYNC pulse width, LSB" | 1298 | * ADDVSL[7:0] "VSYNC pulse width, LSB" |
1250 | * = 210 (0xD2) 11010010 | 1299 | * = 210 (0xD2) 11010010 |
1251 | */ | 1300 | */ |
1252 | { 0x2d, 0xD2 }, | 1301 | { 0x2d, 0xd2 }, |
1253 | 1302 | ||
1254 | /* | 1303 | /* |
1255 | * 00 GAIN = 24 (0x18) 00011000 | 1304 | * 00 GAIN = 24 (0x18) 00011000 |
@@ -1272,7 +1321,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1272 | * BLUE[6:0] "Value" | 1321 | * BLUE[6:0] "Value" |
1273 | * = 112 (0x70) .1110000 | 1322 | * = 112 (0x70) .1110000 |
1274 | */ | 1323 | */ |
1275 | { 0x01, 0xF0 }, | 1324 | { 0x01, 0xf0 }, |
1276 | 1325 | ||
1277 | /* | 1326 | /* |
1278 | * 10 AEC "Automatic Exposure Control" | 1327 | * 10 AEC "Automatic Exposure Control" |
@@ -1280,14 +1329,14 @@ static const struct ov_i2c_regvals norm_3620b[] = { | |||
1280 | * AEC[7:0] "Automatic Exposure Control, 8 MSBs" | 1329 | * AEC[7:0] "Automatic Exposure Control, 8 MSBs" |
1281 | * = 10 (0x0A) 00001010 | 1330 | * = 10 (0x0A) 00001010 |
1282 | */ | 1331 | */ |
1283 | { 0x10, 0x0A }, | 1332 | { 0x10, 0x0a }, |
1284 | 1333 | ||
1285 | { 0xE1, 0x67 }, | 1334 | { 0xe1, 0x67 }, |
1286 | { 0xE3, 0x03 }, | 1335 | { 0xe3, 0x03 }, |
1287 | { 0xE4, 0x26 }, | 1336 | { 0xe4, 0x26 }, |
1288 | { 0xE5, 0x3E }, | 1337 | { 0xe5, 0x3e }, |
1289 | { 0xF8, 0x01 }, | 1338 | { 0xf8, 0x01 }, |
1290 | { 0xFF, 0x01 }, | 1339 | { 0xff, 0x01 }, |
1291 | }; | 1340 | }; |
1292 | 1341 | ||
1293 | static const struct ov_i2c_regvals norm_6x20[] = { | 1342 | static const struct ov_i2c_regvals norm_6x20[] = { |
@@ -1296,7 +1345,7 @@ static const struct ov_i2c_regvals norm_6x20[] = { | |||
1296 | { 0x03, 0x60 }, | 1345 | { 0x03, 0x60 }, |
1297 | { 0x05, 0x7f }, /* For when autoadjust is off */ | 1346 | { 0x05, 0x7f }, /* For when autoadjust is off */ |
1298 | { 0x07, 0xa8 }, | 1347 | { 0x07, 0xa8 }, |
1299 | /* The ratio of 0x0c and 0x0d controls the white point */ | 1348 | /* The ratio of 0x0c and 0x0d controls the white point */ |
1300 | { 0x0c, 0x24 }, | 1349 | { 0x0c, 0x24 }, |
1301 | { 0x0d, 0x24 }, | 1350 | { 0x0d, 0x24 }, |
1302 | { 0x0f, 0x15 }, /* COMS */ | 1351 | { 0x0f, 0x15 }, /* COMS */ |
@@ -1464,7 +1513,7 @@ static const struct ov_i2c_regvals norm_7620[] = { | |||
1464 | { 0x00, 0x00 }, /* gain */ | 1513 | { 0x00, 0x00 }, /* gain */ |
1465 | { 0x01, 0x80 }, /* blue gain */ | 1514 | { 0x01, 0x80 }, /* blue gain */ |
1466 | { 0x02, 0x80 }, /* red gain */ | 1515 | { 0x02, 0x80 }, /* red gain */ |
1467 | { 0x03, 0xc0 }, /* OV7670_REG_VREF */ | 1516 | { 0x03, 0xc0 }, /* OV7670_R03_VREF */ |
1468 | { 0x06, 0x60 }, | 1517 | { 0x06, 0x60 }, |
1469 | { 0x07, 0x00 }, | 1518 | { 0x07, 0x00 }, |
1470 | { 0x0c, 0x24 }, | 1519 | { 0x0c, 0x24 }, |
@@ -1532,33 +1581,177 @@ static const struct ov_i2c_regvals norm_7640[] = { | |||
1532 | { 0x12, 0x14 }, | 1581 | { 0x12, 0x14 }, |
1533 | }; | 1582 | }; |
1534 | 1583 | ||
1584 | static const struct ov_regvals init_519_ov7660[] = { | ||
1585 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1586 | { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */ | ||
1587 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1588 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1589 | { 0xa3, 0x18 }, | ||
1590 | { 0xa4, 0x04 }, | ||
1591 | { 0xa5, 0x28 }, | ||
1592 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1593 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1594 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1595 | { 0x20, 0x0c }, /* 0x0d does U <-> V swap */ | ||
1596 | { 0x21, 0x38 }, | ||
1597 | { 0x22, 0x1d }, | ||
1598 | { 0x17, 0x50 }, /* undocumented */ | ||
1599 | { 0x37, 0x00 }, /* undocumented */ | ||
1600 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1601 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1602 | }; | ||
1603 | static const struct ov_i2c_regvals norm_7660[] = { | ||
1604 | {OV7670_R12_COM7, OV7670_COM7_RESET}, | ||
1605 | {OV7670_R11_CLKRC, 0x81}, | ||
1606 | {0x92, 0x00}, /* DM_LNL */ | ||
1607 | {0x93, 0x00}, /* DM_LNH */ | ||
1608 | {0x9d, 0x4c}, /* BD50ST */ | ||
1609 | {0x9e, 0x3f}, /* BD60ST */ | ||
1610 | {OV7670_R3B_COM11, 0x02}, | ||
1611 | {OV7670_R13_COM8, 0xf5}, | ||
1612 | {OV7670_R10_AECH, 0x00}, | ||
1613 | {OV7670_R00_GAIN, 0x00}, | ||
1614 | {OV7670_R01_BLUE, 0x7c}, | ||
1615 | {OV7670_R02_RED, 0x9d}, | ||
1616 | {OV7670_R12_COM7, 0x00}, | ||
1617 | {OV7670_R04_COM1, 00}, | ||
1618 | {OV7670_R18_HSTOP, 0x01}, | ||
1619 | {OV7670_R17_HSTART, 0x13}, | ||
1620 | {OV7670_R32_HREF, 0x92}, | ||
1621 | {OV7670_R19_VSTART, 0x02}, | ||
1622 | {OV7670_R1A_VSTOP, 0x7a}, | ||
1623 | {OV7670_R03_VREF, 0x00}, | ||
1624 | {OV7670_R0E_COM5, 0x04}, | ||
1625 | {OV7670_R0F_COM6, 0x62}, | ||
1626 | {OV7670_R15_COM10, 0x00}, | ||
1627 | {0x16, 0x02}, /* RSVD */ | ||
1628 | {0x1b, 0x00}, /* PSHFT */ | ||
1629 | {OV7670_R1E_MVFP, 0x01}, | ||
1630 | {0x29, 0x3c}, /* RSVD */ | ||
1631 | {0x33, 0x00}, /* CHLF */ | ||
1632 | {0x34, 0x07}, /* ARBLM */ | ||
1633 | {0x35, 0x84}, /* RSVD */ | ||
1634 | {0x36, 0x00}, /* RSVD */ | ||
1635 | {0x37, 0x04}, /* ADC */ | ||
1636 | {0x39, 0x43}, /* OFON */ | ||
1637 | {OV7670_R3A_TSLB, 0x00}, | ||
1638 | {OV7670_R3C_COM12, 0x6c}, | ||
1639 | {OV7670_R3D_COM13, 0x98}, | ||
1640 | {OV7670_R3F_EDGE, 0x23}, | ||
1641 | {OV7670_R40_COM15, 0xc1}, | ||
1642 | {OV7670_R41_COM16, 0x22}, | ||
1643 | {0x6b, 0x0a}, /* DBLV */ | ||
1644 | {0xa1, 0x08}, /* RSVD */ | ||
1645 | {0x69, 0x80}, /* HV */ | ||
1646 | {0x43, 0xf0}, /* RSVD.. */ | ||
1647 | {0x44, 0x10}, | ||
1648 | {0x45, 0x78}, | ||
1649 | {0x46, 0xa8}, | ||
1650 | {0x47, 0x60}, | ||
1651 | {0x48, 0x80}, | ||
1652 | {0x59, 0xba}, | ||
1653 | {0x5a, 0x9a}, | ||
1654 | {0x5b, 0x22}, | ||
1655 | {0x5c, 0xb9}, | ||
1656 | {0x5d, 0x9b}, | ||
1657 | {0x5e, 0x10}, | ||
1658 | {0x5f, 0xe0}, | ||
1659 | {0x60, 0x85}, | ||
1660 | {0x61, 0x60}, | ||
1661 | {0x9f, 0x9d}, /* RSVD */ | ||
1662 | {0xa0, 0xa0}, /* DSPC2 */ | ||
1663 | {0x4f, 0x60}, /* matrix */ | ||
1664 | {0x50, 0x64}, | ||
1665 | {0x51, 0x04}, | ||
1666 | {0x52, 0x18}, | ||
1667 | {0x53, 0x3c}, | ||
1668 | {0x54, 0x54}, | ||
1669 | {0x55, 0x40}, | ||
1670 | {0x56, 0x40}, | ||
1671 | {0x57, 0x40}, | ||
1672 | {0x58, 0x0d}, /* matrix sign */ | ||
1673 | {0x8b, 0xcc}, /* RSVD */ | ||
1674 | {0x8c, 0xcc}, | ||
1675 | {0x8d, 0xcf}, | ||
1676 | {0x6c, 0x40}, /* gamma curve */ | ||
1677 | {0x6d, 0xe0}, | ||
1678 | {0x6e, 0xa0}, | ||
1679 | {0x6f, 0x80}, | ||
1680 | {0x70, 0x70}, | ||
1681 | {0x71, 0x80}, | ||
1682 | {0x72, 0x60}, | ||
1683 | {0x73, 0x60}, | ||
1684 | {0x74, 0x50}, | ||
1685 | {0x75, 0x40}, | ||
1686 | {0x76, 0x38}, | ||
1687 | {0x77, 0x3c}, | ||
1688 | {0x78, 0x32}, | ||
1689 | {0x79, 0x1a}, | ||
1690 | {0x7a, 0x28}, | ||
1691 | {0x7b, 0x24}, | ||
1692 | {0x7c, 0x04}, /* gamma curve */ | ||
1693 | {0x7d, 0x12}, | ||
1694 | {0x7e, 0x26}, | ||
1695 | {0x7f, 0x46}, | ||
1696 | {0x80, 0x54}, | ||
1697 | {0x81, 0x64}, | ||
1698 | {0x82, 0x70}, | ||
1699 | {0x83, 0x7c}, | ||
1700 | {0x84, 0x86}, | ||
1701 | {0x85, 0x8e}, | ||
1702 | {0x86, 0x9c}, | ||
1703 | {0x87, 0xab}, | ||
1704 | {0x88, 0xc4}, | ||
1705 | {0x89, 0xd1}, | ||
1706 | {0x8a, 0xe5}, | ||
1707 | {OV7670_R14_COM9, 0x1e}, | ||
1708 | {OV7670_R24_AEW, 0x80}, | ||
1709 | {OV7670_R25_AEB, 0x72}, | ||
1710 | {OV7670_R26_VPT, 0xb3}, | ||
1711 | {0x62, 0x80}, /* LCC1 */ | ||
1712 | {0x63, 0x80}, /* LCC2 */ | ||
1713 | {0x64, 0x06}, /* LCC3 */ | ||
1714 | {0x65, 0x00}, /* LCC4 */ | ||
1715 | {0x66, 0x01}, /* LCC5 */ | ||
1716 | {0x94, 0x0e}, /* RSVD.. */ | ||
1717 | {0x95, 0x14}, | ||
1718 | {OV7670_R13_COM8, OV7670_COM8_FASTAEC | ||
1719 | | OV7670_COM8_AECSTEP | ||
1720 | | OV7670_COM8_BFILT | ||
1721 | | 0x10 | ||
1722 | | OV7670_COM8_AGC | ||
1723 | | OV7670_COM8_AWB | ||
1724 | | OV7670_COM8_AEC}, | ||
1725 | {0xa1, 0xc8} | ||
1726 | }; | ||
1727 | |||
1535 | /* 7670. Defaults taken from OmniVision provided data, | 1728 | /* 7670. Defaults taken from OmniVision provided data, |
1536 | * as provided by Jonathan Corbet of OLPC */ | 1729 | * as provided by Jonathan Corbet of OLPC */ |
1537 | static const struct ov_i2c_regvals norm_7670[] = { | 1730 | static const struct ov_i2c_regvals norm_7670[] = { |
1538 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | 1731 | { OV7670_R12_COM7, OV7670_COM7_RESET }, |
1539 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | 1732 | { OV7670_R3A_TSLB, 0x04 }, /* OV */ |
1540 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | 1733 | { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ |
1541 | { OV7670_REG_CLKRC, 0x01 }, | 1734 | { OV7670_R11_CLKRC, 0x01 }, |
1542 | /* | 1735 | /* |
1543 | * Set the hardware window. These values from OV don't entirely | 1736 | * Set the hardware window. These values from OV don't entirely |
1544 | * make sense - hstop is less than hstart. But they work... | 1737 | * make sense - hstop is less than hstart. But they work... |
1545 | */ | 1738 | */ |
1546 | { OV7670_REG_HSTART, 0x13 }, | 1739 | { OV7670_R17_HSTART, 0x13 }, |
1547 | { OV7670_REG_HSTOP, 0x01 }, | 1740 | { OV7670_R18_HSTOP, 0x01 }, |
1548 | { OV7670_REG_HREF, 0xb6 }, | 1741 | { OV7670_R32_HREF, 0xb6 }, |
1549 | { OV7670_REG_VSTART, 0x02 }, | 1742 | { OV7670_R19_VSTART, 0x02 }, |
1550 | { OV7670_REG_VSTOP, 0x7a }, | 1743 | { OV7670_R1A_VSTOP, 0x7a }, |
1551 | { OV7670_REG_VREF, 0x0a }, | 1744 | { OV7670_R03_VREF, 0x0a }, |
1552 | 1745 | ||
1553 | { OV7670_REG_COM3, 0x00 }, | 1746 | { OV7670_R0C_COM3, 0x00 }, |
1554 | { OV7670_REG_COM14, 0x00 }, | 1747 | { OV7670_R3E_COM14, 0x00 }, |
1555 | /* Mystery scaling numbers */ | 1748 | /* Mystery scaling numbers */ |
1556 | { 0x70, 0x3a }, | 1749 | { 0x70, 0x3a }, |
1557 | { 0x71, 0x35 }, | 1750 | { 0x71, 0x35 }, |
1558 | { 0x72, 0x11 }, | 1751 | { 0x72, 0x11 }, |
1559 | { 0x73, 0xf0 }, | 1752 | { 0x73, 0xf0 }, |
1560 | { 0xa2, 0x02 }, | 1753 | { 0xa2, 0x02 }, |
1561 | /* { OV7670_REG_COM10, 0x0 }, */ | 1754 | /* { OV7670_R15_COM10, 0x0 }, */ |
1562 | 1755 | ||
1563 | /* Gamma curve values */ | 1756 | /* Gamma curve values */ |
1564 | { 0x7a, 0x20 }, | 1757 | { 0x7a, 0x20 }, |
@@ -1580,37 +1773,37 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1580 | 1773 | ||
1581 | /* AGC and AEC parameters. Note we start by disabling those features, | 1774 | /* AGC and AEC parameters. Note we start by disabling those features, |
1582 | then turn them only after tweaking the values. */ | 1775 | then turn them only after tweaking the values. */ |
1583 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1776 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1584 | | OV7670_COM8_AECSTEP | 1777 | | OV7670_COM8_AECSTEP |
1585 | | OV7670_COM8_BFILT }, | 1778 | | OV7670_COM8_BFILT }, |
1586 | { OV7670_REG_GAIN, 0x00 }, | 1779 | { OV7670_R00_GAIN, 0x00 }, |
1587 | { OV7670_REG_AECH, 0x00 }, | 1780 | { OV7670_R10_AECH, 0x00 }, |
1588 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | 1781 | { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */ |
1589 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | 1782 | { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ |
1590 | { OV7670_REG_BD50MAX, 0x05 }, | 1783 | { OV7670_RA5_BD50MAX, 0x05 }, |
1591 | { OV7670_REG_BD60MAX, 0x07 }, | 1784 | { OV7670_RAB_BD60MAX, 0x07 }, |
1592 | { OV7670_REG_AEW, 0x95 }, | 1785 | { OV7670_R24_AEW, 0x95 }, |
1593 | { OV7670_REG_AEB, 0x33 }, | 1786 | { OV7670_R25_AEB, 0x33 }, |
1594 | { OV7670_REG_VPT, 0xe3 }, | 1787 | { OV7670_R26_VPT, 0xe3 }, |
1595 | { OV7670_REG_HAECC1, 0x78 }, | 1788 | { OV7670_R9F_HAECC1, 0x78 }, |
1596 | { OV7670_REG_HAECC2, 0x68 }, | 1789 | { OV7670_RA0_HAECC2, 0x68 }, |
1597 | { 0xa1, 0x03 }, /* magic */ | 1790 | { 0xa1, 0x03 }, /* magic */ |
1598 | { OV7670_REG_HAECC3, 0xd8 }, | 1791 | { OV7670_RA6_HAECC3, 0xd8 }, |
1599 | { OV7670_REG_HAECC4, 0xd8 }, | 1792 | { OV7670_RA7_HAECC4, 0xd8 }, |
1600 | { OV7670_REG_HAECC5, 0xf0 }, | 1793 | { OV7670_RA8_HAECC5, 0xf0 }, |
1601 | { OV7670_REG_HAECC6, 0x90 }, | 1794 | { OV7670_RA9_HAECC6, 0x90 }, |
1602 | { OV7670_REG_HAECC7, 0x94 }, | 1795 | { OV7670_RAA_HAECC7, 0x94 }, |
1603 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1796 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1604 | | OV7670_COM8_AECSTEP | 1797 | | OV7670_COM8_AECSTEP |
1605 | | OV7670_COM8_BFILT | 1798 | | OV7670_COM8_BFILT |
1606 | | OV7670_COM8_AGC | 1799 | | OV7670_COM8_AGC |
1607 | | OV7670_COM8_AEC }, | 1800 | | OV7670_COM8_AEC }, |
1608 | 1801 | ||
1609 | /* Almost all of these are magic "reserved" values. */ | 1802 | /* Almost all of these are magic "reserved" values. */ |
1610 | { OV7670_REG_COM5, 0x61 }, | 1803 | { OV7670_R0E_COM5, 0x61 }, |
1611 | { OV7670_REG_COM6, 0x4b }, | 1804 | { OV7670_R0F_COM6, 0x4b }, |
1612 | { 0x16, 0x02 }, | 1805 | { 0x16, 0x02 }, |
1613 | { OV7670_REG_MVFP, 0x07 }, | 1806 | { OV7670_R1E_MVFP, 0x07 }, |
1614 | { 0x21, 0x02 }, | 1807 | { 0x21, 0x02 }, |
1615 | { 0x22, 0x91 }, | 1808 | { 0x22, 0x91 }, |
1616 | { 0x29, 0x07 }, | 1809 | { 0x29, 0x07 }, |
@@ -1619,10 +1812,10 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1619 | { 0x37, 0x1d }, | 1812 | { 0x37, 0x1d }, |
1620 | { 0x38, 0x71 }, | 1813 | { 0x38, 0x71 }, |
1621 | { 0x39, 0x2a }, | 1814 | { 0x39, 0x2a }, |
1622 | { OV7670_REG_COM12, 0x78 }, | 1815 | { OV7670_R3C_COM12, 0x78 }, |
1623 | { 0x4d, 0x40 }, | 1816 | { 0x4d, 0x40 }, |
1624 | { 0x4e, 0x20 }, | 1817 | { 0x4e, 0x20 }, |
1625 | { OV7670_REG_GFIX, 0x00 }, | 1818 | { OV7670_R69_GFIX, 0x00 }, |
1626 | { 0x6b, 0x4a }, | 1819 | { 0x6b, 0x4a }, |
1627 | { 0x74, 0x10 }, | 1820 | { 0x74, 0x10 }, |
1628 | { 0x8d, 0x4f }, | 1821 | { 0x8d, 0x4f }, |
@@ -1657,9 +1850,9 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1657 | { 0x6f, 0x9f }, | 1850 | { 0x6f, 0x9f }, |
1658 | /* "9e for advance AWB" */ | 1851 | /* "9e for advance AWB" */ |
1659 | { 0x6a, 0x40 }, | 1852 | { 0x6a, 0x40 }, |
1660 | { OV7670_REG_BLUE, 0x40 }, | 1853 | { OV7670_R01_BLUE, 0x40 }, |
1661 | { OV7670_REG_RED, 0x60 }, | 1854 | { OV7670_R02_RED, 0x60 }, |
1662 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | 1855 | { OV7670_R13_COM8, OV7670_COM8_FASTAEC |
1663 | | OV7670_COM8_AECSTEP | 1856 | | OV7670_COM8_AECSTEP |
1664 | | OV7670_COM8_BFILT | 1857 | | OV7670_COM8_BFILT |
1665 | | OV7670_COM8_AGC | 1858 | | OV7670_COM8_AGC |
@@ -1675,22 +1868,22 @@ static const struct ov_i2c_regvals norm_7670[] = { | |||
1675 | { 0x54, 0x80 }, | 1868 | { 0x54, 0x80 }, |
1676 | { 0x58, 0x9e }, | 1869 | { 0x58, 0x9e }, |
1677 | 1870 | ||
1678 | { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, | 1871 | { OV7670_R41_COM16, OV7670_COM16_AWBGAIN }, |
1679 | { OV7670_REG_EDGE, 0x00 }, | 1872 | { OV7670_R3F_EDGE, 0x00 }, |
1680 | { 0x75, 0x05 }, | 1873 | { 0x75, 0x05 }, |
1681 | { 0x76, 0xe1 }, | 1874 | { 0x76, 0xe1 }, |
1682 | { 0x4c, 0x00 }, | 1875 | { 0x4c, 0x00 }, |
1683 | { 0x77, 0x01 }, | 1876 | { 0x77, 0x01 }, |
1684 | { OV7670_REG_COM13, OV7670_COM13_GAMMA | 1877 | { OV7670_R3D_COM13, OV7670_COM13_GAMMA |
1685 | | OV7670_COM13_UVSAT | 1878 | | OV7670_COM13_UVSAT |
1686 | | 2}, /* was 3 */ | 1879 | | 2}, /* was 3 */ |
1687 | { 0x4b, 0x09 }, | 1880 | { 0x4b, 0x09 }, |
1688 | { 0xc9, 0x60 }, | 1881 | { 0xc9, 0x60 }, |
1689 | { OV7670_REG_COM16, 0x38 }, | 1882 | { OV7670_R41_COM16, 0x38 }, |
1690 | { 0x56, 0x40 }, | 1883 | { 0x56, 0x40 }, |
1691 | 1884 | ||
1692 | { 0x34, 0x11 }, | 1885 | { 0x34, 0x11 }, |
1693 | { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, | 1886 | { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, |
1694 | { 0xa4, 0x88 }, | 1887 | { 0xa4, 0x88 }, |
1695 | { 0x96, 0x00 }, | 1888 | { 0x96, 0x00 }, |
1696 | { 0x97, 0x30 }, | 1889 | { 0x97, 0x30 }, |
@@ -1825,10 +2018,13 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
1825 | } | 2018 | } |
1826 | 2019 | ||
1827 | /* Write a OV519 register */ | 2020 | /* Write a OV519 register */ |
1828 | static int reg_w(struct sd *sd, __u16 index, __u16 value) | 2021 | static void reg_w(struct sd *sd, u16 index, u16 value) |
1829 | { | 2022 | { |
1830 | int ret, req = 0; | 2023 | int ret, req = 0; |
1831 | 2024 | ||
2025 | if (sd->gspca_dev.usb_err < 0) | ||
2026 | return; | ||
2027 | |||
1832 | switch (sd->bridge) { | 2028 | switch (sd->bridge) { |
1833 | case BRIDGE_OV511: | 2029 | case BRIDGE_OV511: |
1834 | case BRIDGE_OV511PLUS: | 2030 | case BRIDGE_OV511PLUS: |
@@ -1838,6 +2034,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1838 | req = 0x0a; | 2034 | req = 0x0a; |
1839 | /* fall through */ | 2035 | /* fall through */ |
1840 | case BRIDGE_W9968CF: | 2036 | case BRIDGE_W9968CF: |
2037 | PDEBUG(D_USBO, "SET %02x %04x %04x", | ||
2038 | req, value, index); | ||
1841 | ret = usb_control_msg(sd->gspca_dev.dev, | 2039 | ret = usb_control_msg(sd->gspca_dev.dev, |
1842 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2040 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
1843 | req, | 2041 | req, |
@@ -1848,6 +2046,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1848 | req = 1; | 2046 | req = 1; |
1849 | } | 2047 | } |
1850 | 2048 | ||
2049 | PDEBUG(D_USBO, "SET %02x 0000 %04x %02x", | ||
2050 | req, index, value); | ||
1851 | sd->gspca_dev.usb_buf[0] = value; | 2051 | sd->gspca_dev.usb_buf[0] = value; |
1852 | ret = usb_control_msg(sd->gspca_dev.dev, | 2052 | ret = usb_control_msg(sd->gspca_dev.dev, |
1853 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2053 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
@@ -1857,22 +2057,22 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value) | |||
1857 | sd->gspca_dev.usb_buf, 1, 500); | 2057 | sd->gspca_dev.usb_buf, 1, 500); |
1858 | leave: | 2058 | leave: |
1859 | if (ret < 0) { | 2059 | if (ret < 0) { |
1860 | err("Write reg 0x%04x -> [0x%02x] failed", | 2060 | err("reg_w %02x failed %d", index, ret); |
1861 | value, index); | 2061 | sd->gspca_dev.usb_err = ret; |
1862 | return ret; | 2062 | return; |
1863 | } | 2063 | } |
1864 | |||
1865 | PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index); | ||
1866 | return 0; | ||
1867 | } | 2064 | } |
1868 | 2065 | ||
1869 | /* Read from a OV519 register, note not valid for the w9968cf!! */ | 2066 | /* Read from a OV519 register, note not valid for the w9968cf!! */ |
1870 | /* returns: negative is error, pos or zero is data */ | 2067 | /* returns: negative is error, pos or zero is data */ |
1871 | static int reg_r(struct sd *sd, __u16 index) | 2068 | static int reg_r(struct sd *sd, u16 index) |
1872 | { | 2069 | { |
1873 | int ret; | 2070 | int ret; |
1874 | int req; | 2071 | int req; |
1875 | 2072 | ||
2073 | if (sd->gspca_dev.usb_err < 0) | ||
2074 | return -1; | ||
2075 | |||
1876 | switch (sd->bridge) { | 2076 | switch (sd->bridge) { |
1877 | case BRIDGE_OV511: | 2077 | case BRIDGE_OV511: |
1878 | case BRIDGE_OV511PLUS: | 2078 | case BRIDGE_OV511PLUS: |
@@ -1893,29 +2093,37 @@ static int reg_r(struct sd *sd, __u16 index) | |||
1893 | 2093 | ||
1894 | if (ret >= 0) { | 2094 | if (ret >= 0) { |
1895 | ret = sd->gspca_dev.usb_buf[0]; | 2095 | ret = sd->gspca_dev.usb_buf[0]; |
1896 | PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); | 2096 | PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", |
1897 | } else | 2097 | req, index, ret); |
1898 | err("Read reg [0x%02x] failed", index); | 2098 | } else { |
2099 | err("reg_r %02x failed %d", index, ret); | ||
2100 | sd->gspca_dev.usb_err = ret; | ||
2101 | } | ||
1899 | 2102 | ||
1900 | return ret; | 2103 | return ret; |
1901 | } | 2104 | } |
1902 | 2105 | ||
1903 | /* Read 8 values from a OV519 register */ | 2106 | /* Read 8 values from a OV519 register */ |
1904 | static int reg_r8(struct sd *sd, | 2107 | static int reg_r8(struct sd *sd, |
1905 | __u16 index) | 2108 | u16 index) |
1906 | { | 2109 | { |
1907 | int ret; | 2110 | int ret; |
1908 | 2111 | ||
2112 | if (sd->gspca_dev.usb_err < 0) | ||
2113 | return -1; | ||
2114 | |||
1909 | ret = usb_control_msg(sd->gspca_dev.dev, | 2115 | ret = usb_control_msg(sd->gspca_dev.dev, |
1910 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 2116 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
1911 | 1, /* REQ_IO */ | 2117 | 1, /* REQ_IO */ |
1912 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2118 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1913 | 0, index, sd->gspca_dev.usb_buf, 8, 500); | 2119 | 0, index, sd->gspca_dev.usb_buf, 8, 500); |
1914 | 2120 | ||
1915 | if (ret >= 0) | 2121 | if (ret >= 0) { |
1916 | ret = sd->gspca_dev.usb_buf[0]; | 2122 | ret = sd->gspca_dev.usb_buf[0]; |
1917 | else | 2123 | } else { |
1918 | err("Read reg 8 [0x%02x] failed", index); | 2124 | err("reg_r8 %02x failed %d", index, ret); |
2125 | sd->gspca_dev.usb_err = ret; | ||
2126 | } | ||
1919 | 2127 | ||
1920 | return ret; | 2128 | return ret; |
1921 | } | 2129 | } |
@@ -1926,34 +2134,37 @@ static int reg_r8(struct sd *sd, | |||
1926 | * that are in the same position as 0's in "mask" are preserved, regardless | 2134 | * that are in the same position as 0's in "mask" are preserved, regardless |
1927 | * of their respective state in "value". | 2135 | * of their respective state in "value". |
1928 | */ | 2136 | */ |
1929 | static int reg_w_mask(struct sd *sd, | 2137 | static void reg_w_mask(struct sd *sd, |
1930 | __u16 index, | 2138 | u16 index, |
1931 | __u8 value, | 2139 | u8 value, |
1932 | __u8 mask) | 2140 | u8 mask) |
1933 | { | 2141 | { |
1934 | int ret; | 2142 | int ret; |
1935 | __u8 oldval; | 2143 | u8 oldval; |
1936 | 2144 | ||
1937 | if (mask != 0xff) { | 2145 | if (mask != 0xff) { |
1938 | value &= mask; /* Enforce mask on value */ | 2146 | value &= mask; /* Enforce mask on value */ |
1939 | ret = reg_r(sd, index); | 2147 | ret = reg_r(sd, index); |
1940 | if (ret < 0) | 2148 | if (ret < 0) |
1941 | return ret; | 2149 | return; |
1942 | 2150 | ||
1943 | oldval = ret & ~mask; /* Clear the masked bits */ | 2151 | oldval = ret & ~mask; /* Clear the masked bits */ |
1944 | value |= oldval; /* Set the desired bits */ | 2152 | value |= oldval; /* Set the desired bits */ |
1945 | } | 2153 | } |
1946 | return reg_w(sd, index, value); | 2154 | reg_w(sd, index, value); |
1947 | } | 2155 | } |
1948 | 2156 | ||
1949 | /* | 2157 | /* |
1950 | * Writes multiple (n) byte value to a single register. Only valid with certain | 2158 | * Writes multiple (n) byte value to a single register. Only valid with certain |
1951 | * registers (0x30 and 0xc4 - 0xce). | 2159 | * registers (0x30 and 0xc4 - 0xce). |
1952 | */ | 2160 | */ |
1953 | static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | 2161 | static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n) |
1954 | { | 2162 | { |
1955 | int ret; | 2163 | int ret; |
1956 | 2164 | ||
2165 | if (sd->gspca_dev.usb_err < 0) | ||
2166 | return; | ||
2167 | |||
1957 | *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | 2168 | *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); |
1958 | 2169 | ||
1959 | ret = usb_control_msg(sd->gspca_dev.dev, | 2170 | ret = usb_control_msg(sd->gspca_dev.dev, |
@@ -1963,69 +2174,55 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | |||
1963 | 0, index, | 2174 | 0, index, |
1964 | sd->gspca_dev.usb_buf, n, 500); | 2175 | sd->gspca_dev.usb_buf, n, 500); |
1965 | if (ret < 0) { | 2176 | if (ret < 0) { |
1966 | err("Write reg32 [%02x] %08x failed", index, value); | 2177 | err("reg_w32 %02x failed %d", index, ret); |
1967 | return ret; | 2178 | sd->gspca_dev.usb_err = ret; |
1968 | } | 2179 | } |
1969 | |||
1970 | return 0; | ||
1971 | } | 2180 | } |
1972 | 2181 | ||
1973 | static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2182 | static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value) |
1974 | { | 2183 | { |
1975 | int rc, retries; | 2184 | int rc, retries; |
1976 | 2185 | ||
1977 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | 2186 | PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value); |
1978 | 2187 | ||
1979 | /* Three byte write cycle */ | 2188 | /* Three byte write cycle */ |
1980 | for (retries = 6; ; ) { | 2189 | for (retries = 6; ; ) { |
1981 | /* Select camera register */ | 2190 | /* Select camera register */ |
1982 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | 2191 | reg_w(sd, R51x_I2C_SADDR_3, reg); |
1983 | if (rc < 0) | ||
1984 | return rc; | ||
1985 | 2192 | ||
1986 | /* Write "value" to I2C data port of OV511 */ | 2193 | /* Write "value" to I2C data port of OV511 */ |
1987 | rc = reg_w(sd, R51x_I2C_DATA, value); | 2194 | reg_w(sd, R51x_I2C_DATA, value); |
1988 | if (rc < 0) | ||
1989 | return rc; | ||
1990 | 2195 | ||
1991 | /* Initiate 3-byte write cycle */ | 2196 | /* Initiate 3-byte write cycle */ |
1992 | rc = reg_w(sd, R511_I2C_CTL, 0x01); | 2197 | reg_w(sd, R511_I2C_CTL, 0x01); |
1993 | if (rc < 0) | ||
1994 | return rc; | ||
1995 | 2198 | ||
1996 | do { | 2199 | do { |
1997 | rc = reg_r(sd, R511_I2C_CTL); | 2200 | rc = reg_r(sd, R511_I2C_CTL); |
1998 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ | 2201 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ |
1999 | 2202 | ||
2000 | if (rc < 0) | 2203 | if (rc < 0) |
2001 | return rc; | 2204 | return; |
2002 | 2205 | ||
2003 | if ((rc & 2) == 0) /* Ack? */ | 2206 | if ((rc & 2) == 0) /* Ack? */ |
2004 | break; | 2207 | break; |
2005 | if (--retries < 0) { | 2208 | if (--retries < 0) { |
2006 | PDEBUG(D_USBO, "i2c write retries exhausted"); | 2209 | PDEBUG(D_USBO, "i2c write retries exhausted"); |
2007 | return -1; | 2210 | return; |
2008 | } | 2211 | } |
2009 | } | 2212 | } |
2010 | |||
2011 | return 0; | ||
2012 | } | 2213 | } |
2013 | 2214 | ||
2014 | static int ov511_i2c_r(struct sd *sd, __u8 reg) | 2215 | static int ov511_i2c_r(struct sd *sd, u8 reg) |
2015 | { | 2216 | { |
2016 | int rc, value, retries; | 2217 | int rc, value, retries; |
2017 | 2218 | ||
2018 | /* Two byte write cycle */ | 2219 | /* Two byte write cycle */ |
2019 | for (retries = 6; ; ) { | 2220 | for (retries = 6; ; ) { |
2020 | /* Select camera register */ | 2221 | /* Select camera register */ |
2021 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | 2222 | reg_w(sd, R51x_I2C_SADDR_2, reg); |
2022 | if (rc < 0) | ||
2023 | return rc; | ||
2024 | 2223 | ||
2025 | /* Initiate 2-byte write cycle */ | 2224 | /* Initiate 2-byte write cycle */ |
2026 | rc = reg_w(sd, R511_I2C_CTL, 0x03); | 2225 | reg_w(sd, R511_I2C_CTL, 0x03); |
2027 | if (rc < 0) | ||
2028 | return rc; | ||
2029 | 2226 | ||
2030 | do { | 2227 | do { |
2031 | rc = reg_r(sd, R511_I2C_CTL); | 2228 | rc = reg_r(sd, R511_I2C_CTL); |
@@ -2049,9 +2246,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2049 | /* Two byte read cycle */ | 2246 | /* Two byte read cycle */ |
2050 | for (retries = 6; ; ) { | 2247 | for (retries = 6; ; ) { |
2051 | /* Initiate 2-byte read cycle */ | 2248 | /* Initiate 2-byte read cycle */ |
2052 | rc = reg_w(sd, R511_I2C_CTL, 0x05); | 2249 | reg_w(sd, R511_I2C_CTL, 0x05); |
2053 | if (rc < 0) | ||
2054 | return rc; | ||
2055 | 2250 | ||
2056 | do { | 2251 | do { |
2057 | rc = reg_r(sd, R511_I2C_CTL); | 2252 | rc = reg_r(sd, R511_I2C_CTL); |
@@ -2064,9 +2259,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2064 | break; | 2259 | break; |
2065 | 2260 | ||
2066 | /* I2C abort */ | 2261 | /* I2C abort */ |
2067 | rc = reg_w(sd, R511_I2C_CTL, 0x10); | 2262 | reg_w(sd, R511_I2C_CTL, 0x10); |
2068 | if (rc < 0) | ||
2069 | return rc; | ||
2070 | 2263 | ||
2071 | if (--retries < 0) { | 2264 | if (--retries < 0) { |
2072 | PDEBUG(D_USBI, "i2c read retries exhausted"); | 2265 | PDEBUG(D_USBI, "i2c read retries exhausted"); |
@@ -2076,12 +2269,10 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2076 | 2269 | ||
2077 | value = reg_r(sd, R51x_I2C_DATA); | 2270 | value = reg_r(sd, R51x_I2C_DATA); |
2078 | 2271 | ||
2079 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | 2272 | PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value); |
2080 | 2273 | ||
2081 | /* This is needed to make i2c_w() work */ | 2274 | /* This is needed to make i2c_w() work */ |
2082 | rc = reg_w(sd, R511_I2C_CTL, 0x05); | 2275 | reg_w(sd, R511_I2C_CTL, 0x05); |
2083 | if (rc < 0) | ||
2084 | return rc; | ||
2085 | 2276 | ||
2086 | return value; | 2277 | return value; |
2087 | } | 2278 | } |
@@ -2091,32 +2282,24 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2091 | * This is normally only called from i2c_w(). Note that this function | 2282 | * This is normally only called from i2c_w(). Note that this function |
2092 | * always succeeds regardless of whether the sensor is present and working. | 2283 | * always succeeds regardless of whether the sensor is present and working. |
2093 | */ | 2284 | */ |
2094 | static int ov518_i2c_w(struct sd *sd, | 2285 | static void ov518_i2c_w(struct sd *sd, |
2095 | __u8 reg, | 2286 | u8 reg, |
2096 | __u8 value) | 2287 | u8 value) |
2097 | { | 2288 | { |
2098 | int rc; | 2289 | PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value); |
2099 | |||
2100 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
2101 | 2290 | ||
2102 | /* Select camera register */ | 2291 | /* Select camera register */ |
2103 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | 2292 | reg_w(sd, R51x_I2C_SADDR_3, reg); |
2104 | if (rc < 0) | ||
2105 | return rc; | ||
2106 | 2293 | ||
2107 | /* Write "value" to I2C data port of OV511 */ | 2294 | /* Write "value" to I2C data port of OV511 */ |
2108 | rc = reg_w(sd, R51x_I2C_DATA, value); | 2295 | reg_w(sd, R51x_I2C_DATA, value); |
2109 | if (rc < 0) | ||
2110 | return rc; | ||
2111 | 2296 | ||
2112 | /* Initiate 3-byte write cycle */ | 2297 | /* Initiate 3-byte write cycle */ |
2113 | rc = reg_w(sd, R518_I2C_CTL, 0x01); | 2298 | reg_w(sd, R518_I2C_CTL, 0x01); |
2114 | if (rc < 0) | ||
2115 | return rc; | ||
2116 | 2299 | ||
2117 | /* wait for write complete */ | 2300 | /* wait for write complete */ |
2118 | msleep(4); | 2301 | msleep(4); |
2119 | return reg_r8(sd, R518_I2C_CTL); | 2302 | reg_r8(sd, R518_I2C_CTL); |
2120 | } | 2303 | } |
2121 | 2304 | ||
2122 | /* | 2305 | /* |
@@ -2126,105 +2309,102 @@ static int ov518_i2c_w(struct sd *sd, | |||
2126 | * This is normally only called from i2c_r(). Note that this function | 2309 | * This is normally only called from i2c_r(). Note that this function |
2127 | * always succeeds regardless of whether the sensor is present and working. | 2310 | * always succeeds regardless of whether the sensor is present and working. |
2128 | */ | 2311 | */ |
2129 | static int ov518_i2c_r(struct sd *sd, __u8 reg) | 2312 | static int ov518_i2c_r(struct sd *sd, u8 reg) |
2130 | { | 2313 | { |
2131 | int rc, value; | 2314 | int value; |
2132 | 2315 | ||
2133 | /* Select camera register */ | 2316 | /* Select camera register */ |
2134 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | 2317 | reg_w(sd, R51x_I2C_SADDR_2, reg); |
2135 | if (rc < 0) | ||
2136 | return rc; | ||
2137 | 2318 | ||
2138 | /* Initiate 2-byte write cycle */ | 2319 | /* Initiate 2-byte write cycle */ |
2139 | rc = reg_w(sd, R518_I2C_CTL, 0x03); | 2320 | reg_w(sd, R518_I2C_CTL, 0x03); |
2140 | if (rc < 0) | ||
2141 | return rc; | ||
2142 | 2321 | ||
2143 | /* Initiate 2-byte read cycle */ | 2322 | /* Initiate 2-byte read cycle */ |
2144 | rc = reg_w(sd, R518_I2C_CTL, 0x05); | 2323 | reg_w(sd, R518_I2C_CTL, 0x05); |
2145 | if (rc < 0) | ||
2146 | return rc; | ||
2147 | value = reg_r(sd, R51x_I2C_DATA); | 2324 | value = reg_r(sd, R51x_I2C_DATA); |
2148 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | 2325 | PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value); |
2149 | return value; | 2326 | return value; |
2150 | } | 2327 | } |
2151 | 2328 | ||
2152 | static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2329 | static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value) |
2153 | { | 2330 | { |
2154 | int ret; | 2331 | int ret; |
2155 | 2332 | ||
2333 | if (sd->gspca_dev.usb_err < 0) | ||
2334 | return; | ||
2335 | |||
2156 | ret = usb_control_msg(sd->gspca_dev.dev, | 2336 | ret = usb_control_msg(sd->gspca_dev.dev, |
2157 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 2337 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
2158 | 0x02, | 2338 | 0x02, |
2159 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2339 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
2160 | (__u16)value, (__u16)reg, NULL, 0, 500); | 2340 | (u16) value, (u16) reg, NULL, 0, 500); |
2161 | 2341 | ||
2162 | if (ret < 0) { | 2342 | if (ret < 0) { |
2163 | err("i2c 0x%02x -> [0x%02x] failed", value, reg); | 2343 | err("ovfx2_i2c_w %02x failed %d", reg, ret); |
2164 | return ret; | 2344 | sd->gspca_dev.usb_err = ret; |
2165 | } | 2345 | } |
2166 | 2346 | ||
2167 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | 2347 | PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value); |
2168 | return 0; | ||
2169 | } | 2348 | } |
2170 | 2349 | ||
2171 | static int ovfx2_i2c_r(struct sd *sd, __u8 reg) | 2350 | static int ovfx2_i2c_r(struct sd *sd, u8 reg) |
2172 | { | 2351 | { |
2173 | int ret; | 2352 | int ret; |
2174 | 2353 | ||
2354 | if (sd->gspca_dev.usb_err < 0) | ||
2355 | return -1; | ||
2356 | |||
2175 | ret = usb_control_msg(sd->gspca_dev.dev, | 2357 | ret = usb_control_msg(sd->gspca_dev.dev, |
2176 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 2358 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
2177 | 0x03, | 2359 | 0x03, |
2178 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 2360 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
2179 | 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500); | 2361 | 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500); |
2180 | 2362 | ||
2181 | if (ret >= 0) { | 2363 | if (ret >= 0) { |
2182 | ret = sd->gspca_dev.usb_buf[0]; | 2364 | ret = sd->gspca_dev.usb_buf[0]; |
2183 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); | 2365 | PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret); |
2184 | } else | 2366 | } else { |
2185 | err("i2c read [0x%02x] failed", reg); | 2367 | err("ovfx2_i2c_r %02x failed %d", reg, ret); |
2368 | sd->gspca_dev.usb_err = ret; | ||
2369 | } | ||
2186 | 2370 | ||
2187 | return ret; | 2371 | return ret; |
2188 | } | 2372 | } |
2189 | 2373 | ||
2190 | static int i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2374 | static void i2c_w(struct sd *sd, u8 reg, u8 value) |
2191 | { | 2375 | { |
2192 | int ret = -1; | ||
2193 | |||
2194 | if (sd->sensor_reg_cache[reg] == value) | 2376 | if (sd->sensor_reg_cache[reg] == value) |
2195 | return 0; | 2377 | return; |
2196 | 2378 | ||
2197 | switch (sd->bridge) { | 2379 | switch (sd->bridge) { |
2198 | case BRIDGE_OV511: | 2380 | case BRIDGE_OV511: |
2199 | case BRIDGE_OV511PLUS: | 2381 | case BRIDGE_OV511PLUS: |
2200 | ret = ov511_i2c_w(sd, reg, value); | 2382 | ov511_i2c_w(sd, reg, value); |
2201 | break; | 2383 | break; |
2202 | case BRIDGE_OV518: | 2384 | case BRIDGE_OV518: |
2203 | case BRIDGE_OV518PLUS: | 2385 | case BRIDGE_OV518PLUS: |
2204 | case BRIDGE_OV519: | 2386 | case BRIDGE_OV519: |
2205 | ret = ov518_i2c_w(sd, reg, value); | 2387 | ov518_i2c_w(sd, reg, value); |
2206 | break; | 2388 | break; |
2207 | case BRIDGE_OVFX2: | 2389 | case BRIDGE_OVFX2: |
2208 | ret = ovfx2_i2c_w(sd, reg, value); | 2390 | ovfx2_i2c_w(sd, reg, value); |
2209 | break; | 2391 | break; |
2210 | case BRIDGE_W9968CF: | 2392 | case BRIDGE_W9968CF: |
2211 | ret = w9968cf_i2c_w(sd, reg, value); | 2393 | w9968cf_i2c_w(sd, reg, value); |
2212 | break; | 2394 | break; |
2213 | } | 2395 | } |
2214 | 2396 | ||
2215 | if (ret >= 0) { | 2397 | if (sd->gspca_dev.usb_err >= 0) { |
2216 | /* Up on sensor reset empty the register cache */ | 2398 | /* Up on sensor reset empty the register cache */ |
2217 | if (reg == 0x12 && (value & 0x80)) | 2399 | if (reg == 0x12 && (value & 0x80)) |
2218 | memset(sd->sensor_reg_cache, -1, | 2400 | memset(sd->sensor_reg_cache, -1, |
2219 | sizeof(sd->sensor_reg_cache)); | 2401 | sizeof(sd->sensor_reg_cache)); |
2220 | else | 2402 | else |
2221 | sd->sensor_reg_cache[reg] = value; | 2403 | sd->sensor_reg_cache[reg] = value; |
2222 | } | 2404 | } |
2223 | |||
2224 | return ret; | ||
2225 | } | 2405 | } |
2226 | 2406 | ||
2227 | static int i2c_r(struct sd *sd, __u8 reg) | 2407 | static int i2c_r(struct sd *sd, u8 reg) |
2228 | { | 2408 | { |
2229 | int ret = -1; | 2409 | int ret = -1; |
2230 | 2410 | ||
@@ -2260,95 +2440,99 @@ static int i2c_r(struct sd *sd, __u8 reg) | |||
2260 | * that are in the same position as 0's in "mask" are preserved, regardless | 2440 | * that are in the same position as 0's in "mask" are preserved, regardless |
2261 | * of their respective state in "value". | 2441 | * of their respective state in "value". |
2262 | */ | 2442 | */ |
2263 | static int i2c_w_mask(struct sd *sd, | 2443 | static void i2c_w_mask(struct sd *sd, |
2264 | __u8 reg, | 2444 | u8 reg, |
2265 | __u8 value, | 2445 | u8 value, |
2266 | __u8 mask) | 2446 | u8 mask) |
2267 | { | 2447 | { |
2268 | int rc; | 2448 | int rc; |
2269 | __u8 oldval; | 2449 | u8 oldval; |
2270 | 2450 | ||
2271 | value &= mask; /* Enforce mask on value */ | 2451 | value &= mask; /* Enforce mask on value */ |
2272 | rc = i2c_r(sd, reg); | 2452 | rc = i2c_r(sd, reg); |
2273 | if (rc < 0) | 2453 | if (rc < 0) |
2274 | return rc; | 2454 | return; |
2275 | oldval = rc & ~mask; /* Clear the masked bits */ | 2455 | oldval = rc & ~mask; /* Clear the masked bits */ |
2276 | value |= oldval; /* Set the desired bits */ | 2456 | value |= oldval; /* Set the desired bits */ |
2277 | return i2c_w(sd, reg, value); | 2457 | i2c_w(sd, reg, value); |
2278 | } | 2458 | } |
2279 | 2459 | ||
2280 | /* Temporarily stops OV511 from functioning. Must do this before changing | 2460 | /* Temporarily stops OV511 from functioning. Must do this before changing |
2281 | * registers while the camera is streaming */ | 2461 | * registers while the camera is streaming */ |
2282 | static inline int ov51x_stop(struct sd *sd) | 2462 | static inline void ov51x_stop(struct sd *sd) |
2283 | { | 2463 | { |
2284 | PDEBUG(D_STREAM, "stopping"); | 2464 | PDEBUG(D_STREAM, "stopping"); |
2285 | sd->stopped = 1; | 2465 | sd->stopped = 1; |
2286 | switch (sd->bridge) { | 2466 | switch (sd->bridge) { |
2287 | case BRIDGE_OV511: | 2467 | case BRIDGE_OV511: |
2288 | case BRIDGE_OV511PLUS: | 2468 | case BRIDGE_OV511PLUS: |
2289 | return reg_w(sd, R51x_SYS_RESET, 0x3d); | 2469 | reg_w(sd, R51x_SYS_RESET, 0x3d); |
2470 | break; | ||
2290 | case BRIDGE_OV518: | 2471 | case BRIDGE_OV518: |
2291 | case BRIDGE_OV518PLUS: | 2472 | case BRIDGE_OV518PLUS: |
2292 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | 2473 | reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); |
2474 | break; | ||
2293 | case BRIDGE_OV519: | 2475 | case BRIDGE_OV519: |
2294 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 2476 | reg_w(sd, OV519_R51_RESET1, 0x0f); |
2477 | reg_w(sd, OV519_R51_RESET1, 0x00); | ||
2478 | reg_w(sd, 0x22, 0x00); /* FRAR */ | ||
2479 | break; | ||
2295 | case BRIDGE_OVFX2: | 2480 | case BRIDGE_OVFX2: |
2296 | return reg_w_mask(sd, 0x0f, 0x00, 0x02); | 2481 | reg_w_mask(sd, 0x0f, 0x00, 0x02); |
2482 | break; | ||
2297 | case BRIDGE_W9968CF: | 2483 | case BRIDGE_W9968CF: |
2298 | return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ | 2484 | reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ |
2485 | break; | ||
2299 | } | 2486 | } |
2300 | |||
2301 | return 0; | ||
2302 | } | 2487 | } |
2303 | 2488 | ||
2304 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | 2489 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not |
2305 | * actually stopped (for performance). */ | 2490 | * actually stopped (for performance). */ |
2306 | static inline int ov51x_restart(struct sd *sd) | 2491 | static inline void ov51x_restart(struct sd *sd) |
2307 | { | 2492 | { |
2308 | int rc; | ||
2309 | |||
2310 | PDEBUG(D_STREAM, "restarting"); | 2493 | PDEBUG(D_STREAM, "restarting"); |
2311 | if (!sd->stopped) | 2494 | if (!sd->stopped) |
2312 | return 0; | 2495 | return; |
2313 | sd->stopped = 0; | 2496 | sd->stopped = 0; |
2314 | 2497 | ||
2315 | /* Reinitialize the stream */ | 2498 | /* Reinitialize the stream */ |
2316 | switch (sd->bridge) { | 2499 | switch (sd->bridge) { |
2317 | case BRIDGE_OV511: | 2500 | case BRIDGE_OV511: |
2318 | case BRIDGE_OV511PLUS: | 2501 | case BRIDGE_OV511PLUS: |
2319 | return reg_w(sd, R51x_SYS_RESET, 0x00); | 2502 | reg_w(sd, R51x_SYS_RESET, 0x00); |
2503 | break; | ||
2320 | case BRIDGE_OV518: | 2504 | case BRIDGE_OV518: |
2321 | case BRIDGE_OV518PLUS: | 2505 | case BRIDGE_OV518PLUS: |
2322 | rc = reg_w(sd, 0x2f, 0x80); | 2506 | reg_w(sd, 0x2f, 0x80); |
2323 | if (rc < 0) | 2507 | reg_w(sd, R51x_SYS_RESET, 0x00); |
2324 | return rc; | 2508 | break; |
2325 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
2326 | case BRIDGE_OV519: | 2509 | case BRIDGE_OV519: |
2327 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 2510 | reg_w(sd, OV519_R51_RESET1, 0x0f); |
2511 | reg_w(sd, OV519_R51_RESET1, 0x00); | ||
2512 | reg_w(sd, 0x22, 0x1d); /* FRAR */ | ||
2513 | break; | ||
2328 | case BRIDGE_OVFX2: | 2514 | case BRIDGE_OVFX2: |
2329 | return reg_w_mask(sd, 0x0f, 0x02, 0x02); | 2515 | reg_w_mask(sd, 0x0f, 0x02, 0x02); |
2516 | break; | ||
2330 | case BRIDGE_W9968CF: | 2517 | case BRIDGE_W9968CF: |
2331 | return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ | 2518 | reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ |
2519 | break; | ||
2332 | } | 2520 | } |
2333 | |||
2334 | return 0; | ||
2335 | } | 2521 | } |
2336 | 2522 | ||
2337 | static int ov51x_set_slave_ids(struct sd *sd, __u8 slave); | 2523 | static void ov51x_set_slave_ids(struct sd *sd, u8 slave); |
2338 | 2524 | ||
2339 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 2525 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
2340 | * is synchronized. Returns <0 on failure. | 2526 | * is synchronized. Returns <0 on failure. |
2341 | */ | 2527 | */ |
2342 | static int init_ov_sensor(struct sd *sd, __u8 slave) | 2528 | static int init_ov_sensor(struct sd *sd, u8 slave) |
2343 | { | 2529 | { |
2344 | int i; | 2530 | int i; |
2345 | 2531 | ||
2346 | if (ov51x_set_slave_ids(sd, slave) < 0) | 2532 | ov51x_set_slave_ids(sd, slave); |
2347 | return -EIO; | ||
2348 | 2533 | ||
2349 | /* Reset the sensor */ | 2534 | /* Reset the sensor */ |
2350 | if (i2c_w(sd, 0x12, 0x80) < 0) | 2535 | i2c_w(sd, 0x12, 0x80); |
2351 | return -EIO; | ||
2352 | 2536 | ||
2353 | /* Wait for it to initialize */ | 2537 | /* Wait for it to initialize */ |
2354 | msleep(150); | 2538 | msleep(150); |
@@ -2361,15 +2545,16 @@ static int init_ov_sensor(struct sd *sd, __u8 slave) | |||
2361 | } | 2545 | } |
2362 | 2546 | ||
2363 | /* Reset the sensor */ | 2547 | /* Reset the sensor */ |
2364 | if (i2c_w(sd, 0x12, 0x80) < 0) | 2548 | i2c_w(sd, 0x12, 0x80); |
2365 | return -EIO; | 2549 | |
2366 | /* Wait for it to initialize */ | 2550 | /* Wait for it to initialize */ |
2367 | msleep(150); | 2551 | msleep(150); |
2552 | |||
2368 | /* Dummy read to sync I2C */ | 2553 | /* Dummy read to sync I2C */ |
2369 | if (i2c_r(sd, 0x00) < 0) | 2554 | if (i2c_r(sd, 0x00) < 0) |
2370 | return -EIO; | 2555 | return -1; |
2371 | } | 2556 | } |
2372 | return -EIO; | 2557 | return -1; |
2373 | } | 2558 | } |
2374 | 2559 | ||
2375 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | 2560 | /* Set the read and write slave IDs. The "slave" argument is the write slave, |
@@ -2377,53 +2562,40 @@ static int init_ov_sensor(struct sd *sd, __u8 slave) | |||
2377 | * This should not be called from outside the i2c I/O functions. | 2562 | * This should not be called from outside the i2c I/O functions. |
2378 | * Sets I2C read and write slave IDs. Returns <0 for error | 2563 | * Sets I2C read and write slave IDs. Returns <0 for error |
2379 | */ | 2564 | */ |
2380 | static int ov51x_set_slave_ids(struct sd *sd, | 2565 | static void ov51x_set_slave_ids(struct sd *sd, |
2381 | __u8 slave) | 2566 | u8 slave) |
2382 | { | 2567 | { |
2383 | int rc; | ||
2384 | |||
2385 | switch (sd->bridge) { | 2568 | switch (sd->bridge) { |
2386 | case BRIDGE_OVFX2: | 2569 | case BRIDGE_OVFX2: |
2387 | return reg_w(sd, OVFX2_I2C_ADDR, slave); | 2570 | reg_w(sd, OVFX2_I2C_ADDR, slave); |
2571 | return; | ||
2388 | case BRIDGE_W9968CF: | 2572 | case BRIDGE_W9968CF: |
2389 | sd->sensor_addr = slave; | 2573 | sd->sensor_addr = slave; |
2390 | return 0; | 2574 | return; |
2391 | } | 2575 | } |
2392 | 2576 | ||
2393 | rc = reg_w(sd, R51x_I2C_W_SID, slave); | 2577 | reg_w(sd, R51x_I2C_W_SID, slave); |
2394 | if (rc < 0) | 2578 | reg_w(sd, R51x_I2C_R_SID, slave + 1); |
2395 | return rc; | ||
2396 | return reg_w(sd, R51x_I2C_R_SID, slave + 1); | ||
2397 | } | 2579 | } |
2398 | 2580 | ||
2399 | static int write_regvals(struct sd *sd, | 2581 | static void write_regvals(struct sd *sd, |
2400 | const struct ov_regvals *regvals, | 2582 | const struct ov_regvals *regvals, |
2401 | int n) | 2583 | int n) |
2402 | { | 2584 | { |
2403 | int rc; | ||
2404 | |||
2405 | while (--n >= 0) { | 2585 | while (--n >= 0) { |
2406 | rc = reg_w(sd, regvals->reg, regvals->val); | 2586 | reg_w(sd, regvals->reg, regvals->val); |
2407 | if (rc < 0) | ||
2408 | return rc; | ||
2409 | regvals++; | 2587 | regvals++; |
2410 | } | 2588 | } |
2411 | return 0; | ||
2412 | } | 2589 | } |
2413 | 2590 | ||
2414 | static int write_i2c_regvals(struct sd *sd, | 2591 | static void write_i2c_regvals(struct sd *sd, |
2415 | const struct ov_i2c_regvals *regvals, | 2592 | const struct ov_i2c_regvals *regvals, |
2416 | int n) | 2593 | int n) |
2417 | { | 2594 | { |
2418 | int rc; | ||
2419 | |||
2420 | while (--n >= 0) { | 2595 | while (--n >= 0) { |
2421 | rc = i2c_w(sd, regvals->reg, regvals->val); | 2596 | i2c_w(sd, regvals->reg, regvals->val); |
2422 | if (rc < 0) | ||
2423 | return rc; | ||
2424 | regvals++; | 2597 | regvals++; |
2425 | } | 2598 | } |
2426 | return 0; | ||
2427 | } | 2599 | } |
2428 | 2600 | ||
2429 | /**************************************************************************** | 2601 | /**************************************************************************** |
@@ -2433,13 +2605,13 @@ static int write_i2c_regvals(struct sd *sd, | |||
2433 | ***************************************************************************/ | 2605 | ***************************************************************************/ |
2434 | 2606 | ||
2435 | /* This initializes the OV2x10 / OV3610 / OV3620 */ | 2607 | /* This initializes the OV2x10 / OV3610 / OV3620 */ |
2436 | static int ov_hires_configure(struct sd *sd) | 2608 | static void ov_hires_configure(struct sd *sd) |
2437 | { | 2609 | { |
2438 | int high, low; | 2610 | int high, low; |
2439 | 2611 | ||
2440 | if (sd->bridge != BRIDGE_OVFX2) { | 2612 | if (sd->bridge != BRIDGE_OVFX2) { |
2441 | err("error hires sensors only supported with ovfx2"); | 2613 | err("error hires sensors only supported with ovfx2"); |
2442 | return -1; | 2614 | return; |
2443 | } | 2615 | } |
2444 | 2616 | ||
2445 | PDEBUG(D_PROBE, "starting ov hires configuration"); | 2617 | PDEBUG(D_PROBE, "starting ov hires configuration"); |
@@ -2455,20 +2627,15 @@ static int ov_hires_configure(struct sd *sd) | |||
2455 | PDEBUG(D_PROBE, "Sensor is an OV3610"); | 2627 | PDEBUG(D_PROBE, "Sensor is an OV3610"); |
2456 | sd->sensor = SEN_OV3610; | 2628 | sd->sensor = SEN_OV3610; |
2457 | } else { | 2629 | } else { |
2458 | err("Error unknown sensor type: 0x%02x%02x", | 2630 | err("Error unknown sensor type: %02x%02x", |
2459 | high, low); | 2631 | high, low); |
2460 | return -1; | ||
2461 | } | 2632 | } |
2462 | |||
2463 | /* Set sensor-specific vars */ | ||
2464 | return 0; | ||
2465 | } | 2633 | } |
2466 | 2634 | ||
2467 | |||
2468 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses | 2635 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses |
2469 | * the same register settings as the OV8610, since they are very similar. | 2636 | * the same register settings as the OV8610, since they are very similar. |
2470 | */ | 2637 | */ |
2471 | static int ov8xx0_configure(struct sd *sd) | 2638 | static void ov8xx0_configure(struct sd *sd) |
2472 | { | 2639 | { |
2473 | int rc; | 2640 | int rc; |
2474 | 2641 | ||
@@ -2478,27 +2645,21 @@ static int ov8xx0_configure(struct sd *sd) | |||
2478 | rc = i2c_r(sd, OV7610_REG_COM_I); | 2645 | rc = i2c_r(sd, OV7610_REG_COM_I); |
2479 | if (rc < 0) { | 2646 | if (rc < 0) { |
2480 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2647 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2481 | return -1; | 2648 | return; |
2482 | } | 2649 | } |
2483 | if ((rc & 3) == 1) { | 2650 | if ((rc & 3) == 1) |
2484 | sd->sensor = SEN_OV8610; | 2651 | sd->sensor = SEN_OV8610; |
2485 | } else { | 2652 | else |
2486 | err("Unknown image sensor version: %d", rc & 3); | 2653 | err("Unknown image sensor version: %d", rc & 3); |
2487 | return -1; | ||
2488 | } | ||
2489 | |||
2490 | /* Set sensor-specific vars */ | ||
2491 | return 0; | ||
2492 | } | 2654 | } |
2493 | 2655 | ||
2494 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses | 2656 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses |
2495 | * the same register settings as the OV7610, since they are very similar. | 2657 | * the same register settings as the OV7610, since they are very similar. |
2496 | */ | 2658 | */ |
2497 | static int ov7xx0_configure(struct sd *sd) | 2659 | static void ov7xx0_configure(struct sd *sd) |
2498 | { | 2660 | { |
2499 | int rc, high, low; | 2661 | int rc, high, low; |
2500 | 2662 | ||
2501 | |||
2502 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | 2663 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); |
2503 | 2664 | ||
2504 | /* Detect sensor (sub)type */ | 2665 | /* Detect sensor (sub)type */ |
@@ -2508,15 +2669,15 @@ static int ov7xx0_configure(struct sd *sd) | |||
2508 | * it appears to be wrongly detected as a 7610 by default */ | 2669 | * it appears to be wrongly detected as a 7610 by default */ |
2509 | if (rc < 0) { | 2670 | if (rc < 0) { |
2510 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2671 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2511 | return -1; | 2672 | return; |
2512 | } | 2673 | } |
2513 | if ((rc & 3) == 3) { | 2674 | if ((rc & 3) == 3) { |
2514 | /* quick hack to make OV7670s work */ | 2675 | /* quick hack to make OV7670s work */ |
2515 | high = i2c_r(sd, 0x0a); | 2676 | high = i2c_r(sd, 0x0a); |
2516 | low = i2c_r(sd, 0x0b); | 2677 | low = i2c_r(sd, 0x0b); |
2517 | /* info("%x, %x", high, low); */ | 2678 | /* info("%x, %x", high, low); */ |
2518 | if (high == 0x76 && low == 0x73) { | 2679 | if (high == 0x76 && (low & 0xf0) == 0x70) { |
2519 | PDEBUG(D_PROBE, "Sensor is an OV7670"); | 2680 | PDEBUG(D_PROBE, "Sensor is an OV76%02x", low); |
2520 | sd->sensor = SEN_OV7670; | 2681 | sd->sensor = SEN_OV7670; |
2521 | } else { | 2682 | } else { |
2522 | PDEBUG(D_PROBE, "Sensor is an OV7610"); | 2683 | PDEBUG(D_PROBE, "Sensor is an OV7610"); |
@@ -2536,19 +2697,19 @@ static int ov7xx0_configure(struct sd *sd) | |||
2536 | high = i2c_r(sd, 0x0a); | 2697 | high = i2c_r(sd, 0x0a); |
2537 | if (high < 0) { | 2698 | if (high < 0) { |
2538 | PDEBUG(D_ERR, "Error detecting camera chip PID"); | 2699 | PDEBUG(D_ERR, "Error detecting camera chip PID"); |
2539 | return high; | 2700 | return; |
2540 | } | 2701 | } |
2541 | low = i2c_r(sd, 0x0b); | 2702 | low = i2c_r(sd, 0x0b); |
2542 | if (low < 0) { | 2703 | if (low < 0) { |
2543 | PDEBUG(D_ERR, "Error detecting camera chip VER"); | 2704 | PDEBUG(D_ERR, "Error detecting camera chip VER"); |
2544 | return low; | 2705 | return; |
2545 | } | 2706 | } |
2546 | if (high == 0x76) { | 2707 | if (high == 0x76) { |
2547 | switch (low) { | 2708 | switch (low) { |
2548 | case 0x30: | 2709 | case 0x30: |
2549 | err("Sensor is an OV7630/OV7635"); | 2710 | err("Sensor is an OV7630/OV7635"); |
2550 | err("7630 is not supported by this driver"); | 2711 | err("7630 is not supported by this driver"); |
2551 | return -1; | 2712 | return; |
2552 | case 0x40: | 2713 | case 0x40: |
2553 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 2714 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
2554 | sd->sensor = SEN_OV7640; /* FIXME */ | 2715 | sd->sensor = SEN_OV7640; /* FIXME */ |
@@ -2561,9 +2722,14 @@ static int ov7xx0_configure(struct sd *sd) | |||
2561 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 2722 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
2562 | sd->sensor = SEN_OV7648; | 2723 | sd->sensor = SEN_OV7648; |
2563 | break; | 2724 | break; |
2725 | case 0x60: | ||
2726 | PDEBUG(D_PROBE, "Sensor is a OV7660"); | ||
2727 | sd->sensor = SEN_OV7660; | ||
2728 | sd->invert_led = 0; | ||
2729 | break; | ||
2564 | default: | 2730 | default: |
2565 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | 2731 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); |
2566 | return -1; | 2732 | return; |
2567 | } | 2733 | } |
2568 | } else { | 2734 | } else { |
2569 | PDEBUG(D_PROBE, "Sensor is an OV7620"); | 2735 | PDEBUG(D_PROBE, "Sensor is an OV7620"); |
@@ -2571,15 +2737,11 @@ static int ov7xx0_configure(struct sd *sd) | |||
2571 | } | 2737 | } |
2572 | } else { | 2738 | } else { |
2573 | err("Unknown image sensor version: %d", rc & 3); | 2739 | err("Unknown image sensor version: %d", rc & 3); |
2574 | return -1; | ||
2575 | } | 2740 | } |
2576 | |||
2577 | /* Set sensor-specific vars */ | ||
2578 | return 0; | ||
2579 | } | 2741 | } |
2580 | 2742 | ||
2581 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ | 2743 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ |
2582 | static int ov6xx0_configure(struct sd *sd) | 2744 | static void ov6xx0_configure(struct sd *sd) |
2583 | { | 2745 | { |
2584 | int rc; | 2746 | int rc; |
2585 | PDEBUG(D_PROBE, "starting OV6xx0 configuration"); | 2747 | PDEBUG(D_PROBE, "starting OV6xx0 configuration"); |
@@ -2588,7 +2750,7 @@ static int ov6xx0_configure(struct sd *sd) | |||
2588 | rc = i2c_r(sd, OV7610_REG_COM_I); | 2750 | rc = i2c_r(sd, OV7610_REG_COM_I); |
2589 | if (rc < 0) { | 2751 | if (rc < 0) { |
2590 | PDEBUG(D_ERR, "Error detecting sensor type"); | 2752 | PDEBUG(D_ERR, "Error detecting sensor type"); |
2591 | return -1; | 2753 | return; |
2592 | } | 2754 | } |
2593 | 2755 | ||
2594 | /* Ugh. The first two bits are the version bits, but | 2756 | /* Ugh. The first two bits are the version bits, but |
@@ -2619,13 +2781,11 @@ static int ov6xx0_configure(struct sd *sd) | |||
2619 | break; | 2781 | break; |
2620 | default: | 2782 | default: |
2621 | err("FATAL: Unknown sensor version: 0x%02x", rc); | 2783 | err("FATAL: Unknown sensor version: 0x%02x", rc); |
2622 | return -1; | 2784 | return; |
2623 | } | 2785 | } |
2624 | 2786 | ||
2625 | /* Set sensor-specific vars */ | 2787 | /* Set sensor-specific vars */ |
2626 | sd->sif = 1; | 2788 | sd->sif = 1; |
2627 | |||
2628 | return 0; | ||
2629 | } | 2789 | } |
2630 | 2790 | ||
2631 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 2791 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
@@ -2637,14 +2797,14 @@ static void ov51x_led_control(struct sd *sd, int on) | |||
2637 | switch (sd->bridge) { | 2797 | switch (sd->bridge) { |
2638 | /* OV511 has no LED control */ | 2798 | /* OV511 has no LED control */ |
2639 | case BRIDGE_OV511PLUS: | 2799 | case BRIDGE_OV511PLUS: |
2640 | reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); | 2800 | reg_w(sd, R511_SYS_LED_CTL, on); |
2641 | break; | 2801 | break; |
2642 | case BRIDGE_OV518: | 2802 | case BRIDGE_OV518: |
2643 | case BRIDGE_OV518PLUS: | 2803 | case BRIDGE_OV518PLUS: |
2644 | reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); | 2804 | reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02); |
2645 | break; | 2805 | break; |
2646 | case BRIDGE_OV519: | 2806 | case BRIDGE_OV519: |
2647 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | 2807 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1); |
2648 | break; | 2808 | break; |
2649 | } | 2809 | } |
2650 | } | 2810 | } |
@@ -2679,7 +2839,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev) | |||
2679 | } | 2839 | } |
2680 | } | 2840 | } |
2681 | 2841 | ||
2682 | static int ov51x_upload_quan_tables(struct sd *sd) | 2842 | static void ov51x_upload_quan_tables(struct sd *sd) |
2683 | { | 2843 | { |
2684 | const unsigned char yQuanTable511[] = { | 2844 | const unsigned char yQuanTable511[] = { |
2685 | 0, 1, 1, 2, 2, 3, 3, 4, | 2845 | 0, 1, 1, 2, 2, 3, 3, 4, |
@@ -2710,7 +2870,6 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2710 | 6, 6, 6, 6, 7, 7, 7, 8, | 2870 | 6, 6, 6, 6, 7, 7, 7, 8, |
2711 | 7, 7, 6, 7, 7, 7, 8, 8 | 2871 | 7, 7, 6, 7, 7, 7, 8, 8 |
2712 | }; | 2872 | }; |
2713 | |||
2714 | const unsigned char uvQuanTable518[] = { | 2873 | const unsigned char uvQuanTable518[] = { |
2715 | 6, 6, 6, 7, 7, 7, 7, 7, | 2874 | 6, 6, 6, 7, 7, 7, 7, 7, |
2716 | 6, 6, 6, 7, 7, 7, 7, 7, | 2875 | 6, 6, 6, 7, 7, 7, 7, 7, |
@@ -2720,18 +2879,18 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2720 | 2879 | ||
2721 | const unsigned char *pYTable, *pUVTable; | 2880 | const unsigned char *pYTable, *pUVTable; |
2722 | unsigned char val0, val1; | 2881 | unsigned char val0, val1; |
2723 | int i, size, rc, reg = R51x_COMP_LUT_BEGIN; | 2882 | int i, size, reg = R51x_COMP_LUT_BEGIN; |
2724 | 2883 | ||
2725 | PDEBUG(D_PROBE, "Uploading quantization tables"); | 2884 | PDEBUG(D_PROBE, "Uploading quantization tables"); |
2726 | 2885 | ||
2727 | if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { | 2886 | if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { |
2728 | pYTable = yQuanTable511; | 2887 | pYTable = yQuanTable511; |
2729 | pUVTable = uvQuanTable511; | 2888 | pUVTable = uvQuanTable511; |
2730 | size = 32; | 2889 | size = 32; |
2731 | } else { | 2890 | } else { |
2732 | pYTable = yQuanTable518; | 2891 | pYTable = yQuanTable518; |
2733 | pUVTable = uvQuanTable518; | 2892 | pUVTable = uvQuanTable518; |
2734 | size = 16; | 2893 | size = 16; |
2735 | } | 2894 | } |
2736 | 2895 | ||
2737 | for (i = 0; i < size; i++) { | 2896 | for (i = 0; i < size; i++) { |
@@ -2740,30 +2899,23 @@ static int ov51x_upload_quan_tables(struct sd *sd) | |||
2740 | val0 &= 0x0f; | 2899 | val0 &= 0x0f; |
2741 | val1 &= 0x0f; | 2900 | val1 &= 0x0f; |
2742 | val0 |= val1 << 4; | 2901 | val0 |= val1 << 4; |
2743 | rc = reg_w(sd, reg, val0); | 2902 | reg_w(sd, reg, val0); |
2744 | if (rc < 0) | ||
2745 | return rc; | ||
2746 | 2903 | ||
2747 | val0 = *pUVTable++; | 2904 | val0 = *pUVTable++; |
2748 | val1 = *pUVTable++; | 2905 | val1 = *pUVTable++; |
2749 | val0 &= 0x0f; | 2906 | val0 &= 0x0f; |
2750 | val1 &= 0x0f; | 2907 | val1 &= 0x0f; |
2751 | val0 |= val1 << 4; | 2908 | val0 |= val1 << 4; |
2752 | rc = reg_w(sd, reg + size, val0); | 2909 | reg_w(sd, reg + size, val0); |
2753 | if (rc < 0) | ||
2754 | return rc; | ||
2755 | 2910 | ||
2756 | reg++; | 2911 | reg++; |
2757 | } | 2912 | } |
2758 | |||
2759 | return 0; | ||
2760 | } | 2913 | } |
2761 | 2914 | ||
2762 | /* This initializes the OV511/OV511+ and the sensor */ | 2915 | /* This initializes the OV511/OV511+ and the sensor */ |
2763 | static int ov511_configure(struct gspca_dev *gspca_dev) | 2916 | static void ov511_configure(struct gspca_dev *gspca_dev) |
2764 | { | 2917 | { |
2765 | struct sd *sd = (struct sd *) gspca_dev; | 2918 | struct sd *sd = (struct sd *) gspca_dev; |
2766 | int rc; | ||
2767 | 2919 | ||
2768 | /* For 511 and 511+ */ | 2920 | /* For 511 and 511+ */ |
2769 | const struct ov_regvals init_511[] = { | 2921 | const struct ov_regvals init_511[] = { |
@@ -2809,42 +2961,27 @@ static int ov511_configure(struct gspca_dev *gspca_dev) | |||
2809 | 2961 | ||
2810 | PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); | 2962 | PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); |
2811 | 2963 | ||
2812 | rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511)); | 2964 | write_regvals(sd, init_511, ARRAY_SIZE(init_511)); |
2813 | if (rc < 0) | ||
2814 | return rc; | ||
2815 | 2965 | ||
2816 | switch (sd->bridge) { | 2966 | switch (sd->bridge) { |
2817 | case BRIDGE_OV511: | 2967 | case BRIDGE_OV511: |
2818 | rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); | 2968 | write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); |
2819 | if (rc < 0) | ||
2820 | return rc; | ||
2821 | break; | 2969 | break; |
2822 | case BRIDGE_OV511PLUS: | 2970 | case BRIDGE_OV511PLUS: |
2823 | rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); | 2971 | write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); |
2824 | if (rc < 0) | ||
2825 | return rc; | ||
2826 | break; | 2972 | break; |
2827 | } | 2973 | } |
2828 | 2974 | ||
2829 | /* Init compression */ | 2975 | /* Init compression */ |
2830 | rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); | 2976 | write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); |
2831 | if (rc < 0) | ||
2832 | return rc; | ||
2833 | |||
2834 | rc = ov51x_upload_quan_tables(sd); | ||
2835 | if (rc < 0) { | ||
2836 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
2837 | return rc; | ||
2838 | } | ||
2839 | 2977 | ||
2840 | return 0; | 2978 | ov51x_upload_quan_tables(sd); |
2841 | } | 2979 | } |
2842 | 2980 | ||
2843 | /* This initializes the OV518/OV518+ and the sensor */ | 2981 | /* This initializes the OV518/OV518+ and the sensor */ |
2844 | static int ov518_configure(struct gspca_dev *gspca_dev) | 2982 | static void ov518_configure(struct gspca_dev *gspca_dev) |
2845 | { | 2983 | { |
2846 | struct sd *sd = (struct sd *) gspca_dev; | 2984 | struct sd *sd = (struct sd *) gspca_dev; |
2847 | int rc; | ||
2848 | 2985 | ||
2849 | /* For 518 and 518+ */ | 2986 | /* For 518 and 518+ */ |
2850 | const struct ov_regvals init_518[] = { | 2987 | const struct ov_regvals init_518[] = { |
@@ -2892,65 +3029,49 @@ static int ov518_configure(struct gspca_dev *gspca_dev) | |||
2892 | 3029 | ||
2893 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ | 3030 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ |
2894 | PDEBUG(D_PROBE, "Device revision %d", | 3031 | PDEBUG(D_PROBE, "Device revision %d", |
2895 | 0x1F & reg_r(sd, R51x_SYS_CUST_ID)); | 3032 | 0x1f & reg_r(sd, R51x_SYS_CUST_ID)); |
2896 | 3033 | ||
2897 | rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518)); | 3034 | write_regvals(sd, init_518, ARRAY_SIZE(init_518)); |
2898 | if (rc < 0) | ||
2899 | return rc; | ||
2900 | 3035 | ||
2901 | /* Set LED GPIO pin to output mode */ | 3036 | /* Set LED GPIO pin to output mode */ |
2902 | rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); | 3037 | reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); |
2903 | if (rc < 0) | ||
2904 | return rc; | ||
2905 | 3038 | ||
2906 | switch (sd->bridge) { | 3039 | switch (sd->bridge) { |
2907 | case BRIDGE_OV518: | 3040 | case BRIDGE_OV518: |
2908 | rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); | 3041 | write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); |
2909 | if (rc < 0) | ||
2910 | return rc; | ||
2911 | break; | 3042 | break; |
2912 | case BRIDGE_OV518PLUS: | 3043 | case BRIDGE_OV518PLUS: |
2913 | rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); | 3044 | write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); |
2914 | if (rc < 0) | ||
2915 | return rc; | ||
2916 | break; | 3045 | break; |
2917 | } | 3046 | } |
2918 | 3047 | ||
2919 | rc = ov51x_upload_quan_tables(sd); | 3048 | ov51x_upload_quan_tables(sd); |
2920 | if (rc < 0) { | ||
2921 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
2922 | return rc; | ||
2923 | } | ||
2924 | 3049 | ||
2925 | rc = reg_w(sd, 0x2f, 0x80); | 3050 | reg_w(sd, 0x2f, 0x80); |
2926 | if (rc < 0) | ||
2927 | return rc; | ||
2928 | |||
2929 | return 0; | ||
2930 | } | 3051 | } |
2931 | 3052 | ||
2932 | static int ov519_configure(struct sd *sd) | 3053 | static void ov519_configure(struct sd *sd) |
2933 | { | 3054 | { |
2934 | static const struct ov_regvals init_519[] = { | 3055 | static const struct ov_regvals init_519[] = { |
2935 | { 0x5a, 0x6d }, /* EnableSystem */ | 3056 | { 0x5a, 0x6d }, /* EnableSystem */ |
2936 | { 0x53, 0x9b }, | 3057 | { 0x53, 0x9b }, |
2937 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | 3058 | { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */ |
2938 | { 0x5d, 0x03 }, | 3059 | { 0x5d, 0x03 }, |
2939 | { 0x49, 0x01 }, | 3060 | { 0x49, 0x01 }, |
2940 | { 0x48, 0x00 }, | 3061 | { 0x48, 0x00 }, |
2941 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor | 3062 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor |
2942 | * detection will fail. This deserves further investigation. */ | 3063 | * detection will fail. This deserves further investigation. */ |
2943 | { OV519_GPIO_IO_CTRL0, 0xee }, | 3064 | { OV519_GPIO_IO_CTRL0, 0xee }, |
2944 | { 0x51, 0x0f }, /* SetUsbInit */ | 3065 | { OV519_R51_RESET1, 0x0f }, |
2945 | { 0x51, 0x00 }, | 3066 | { OV519_R51_RESET1, 0x00 }, |
2946 | { 0x22, 0x00 }, | 3067 | { 0x22, 0x00 }, |
2947 | /* windows reads 0x55 at this point*/ | 3068 | /* windows reads 0x55 at this point*/ |
2948 | }; | 3069 | }; |
2949 | 3070 | ||
2950 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); | 3071 | write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
2951 | } | 3072 | } |
2952 | 3073 | ||
2953 | static int ovfx2_configure(struct sd *sd) | 3074 | static void ovfx2_configure(struct sd *sd) |
2954 | { | 3075 | { |
2955 | static const struct ov_regvals init_fx2[] = { | 3076 | static const struct ov_regvals init_fx2[] = { |
2956 | { 0x00, 0x60 }, | 3077 | { 0x00, 0x60 }, |
@@ -2964,7 +3085,92 @@ static int ovfx2_configure(struct sd *sd) | |||
2964 | 3085 | ||
2965 | sd->stopped = 1; | 3086 | sd->stopped = 1; |
2966 | 3087 | ||
2967 | return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); | 3088 | write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); |
3089 | } | ||
3090 | |||
3091 | /* set the mode */ | ||
3092 | /* This function works for ov7660 only */ | ||
3093 | static void ov519_set_mode(struct sd *sd) | ||
3094 | { | ||
3095 | static const struct ov_regvals bridge_ov7660[2][10] = { | ||
3096 | {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00}, | ||
3097 | {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, | ||
3098 | {0x25, 0x01}, {0x26, 0x00}}, | ||
3099 | {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00}, | ||
3100 | {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c}, | ||
3101 | {0x25, 0x03}, {0x26, 0x00}} | ||
3102 | }; | ||
3103 | static const struct ov_i2c_regvals sensor_ov7660[2][3] = { | ||
3104 | {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}}, | ||
3105 | {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}} | ||
3106 | }; | ||
3107 | static const struct ov_i2c_regvals sensor_ov7660_2[] = { | ||
3108 | {OV7670_R17_HSTART, 0x13}, | ||
3109 | {OV7670_R18_HSTOP, 0x01}, | ||
3110 | {OV7670_R32_HREF, 0x92}, | ||
3111 | {OV7670_R19_VSTART, 0x02}, | ||
3112 | {OV7670_R1A_VSTOP, 0x7a}, | ||
3113 | {OV7670_R03_VREF, 0x00}, | ||
3114 | /* {0x33, 0x00}, */ | ||
3115 | /* {0x34, 0x07}, */ | ||
3116 | /* {0x36, 0x00}, */ | ||
3117 | /* {0x6b, 0x0a}, */ | ||
3118 | }; | ||
3119 | |||
3120 | write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode], | ||
3121 | ARRAY_SIZE(bridge_ov7660[0])); | ||
3122 | write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode], | ||
3123 | ARRAY_SIZE(sensor_ov7660[0])); | ||
3124 | write_i2c_regvals(sd, sensor_ov7660_2, | ||
3125 | ARRAY_SIZE(sensor_ov7660_2)); | ||
3126 | } | ||
3127 | |||
3128 | /* set the frame rate */ | ||
3129 | /* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */ | ||
3130 | static void ov519_set_fr(struct sd *sd) | ||
3131 | { | ||
3132 | int fr; | ||
3133 | u8 clock; | ||
3134 | /* frame rate table with indices: | ||
3135 | * - mode = 0: 320x240, 1: 640x480 | ||
3136 | * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5 | ||
3137 | * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock) | ||
3138 | */ | ||
3139 | static const u8 fr_tb[2][6][3] = { | ||
3140 | {{0x04, 0xff, 0x00}, | ||
3141 | {0x04, 0x1f, 0x00}, | ||
3142 | {0x04, 0x1b, 0x00}, | ||
3143 | {0x04, 0x15, 0x00}, | ||
3144 | {0x04, 0x09, 0x00}, | ||
3145 | {0x04, 0x01, 0x00}}, | ||
3146 | {{0x0c, 0xff, 0x00}, | ||
3147 | {0x0c, 0x1f, 0x00}, | ||
3148 | {0x0c, 0x1b, 0x00}, | ||
3149 | {0x04, 0xff, 0x01}, | ||
3150 | {0x04, 0x1f, 0x01}, | ||
3151 | {0x04, 0x1b, 0x01}}, | ||
3152 | }; | ||
3153 | |||
3154 | if (frame_rate > 0) | ||
3155 | sd->frame_rate = frame_rate; | ||
3156 | if (sd->frame_rate >= 30) | ||
3157 | fr = 0; | ||
3158 | else if (sd->frame_rate >= 25) | ||
3159 | fr = 1; | ||
3160 | else if (sd->frame_rate >= 20) | ||
3161 | fr = 2; | ||
3162 | else if (sd->frame_rate >= 15) | ||
3163 | fr = 3; | ||
3164 | else if (sd->frame_rate >= 10) | ||
3165 | fr = 4; | ||
3166 | else | ||
3167 | fr = 5; | ||
3168 | reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]); | ||
3169 | reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]); | ||
3170 | clock = fr_tb[sd->gspca_dev.curr_mode][fr][2]; | ||
3171 | if (sd->sensor == SEN_OV7660) | ||
3172 | clock |= 0x80; /* enable double clock */ | ||
3173 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); | ||
2968 | } | 3174 | } |
2969 | 3175 | ||
2970 | /* this function is called at probe time */ | 3176 | /* this function is called at probe time */ |
@@ -2973,99 +3179,119 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2973 | { | 3179 | { |
2974 | struct sd *sd = (struct sd *) gspca_dev; | 3180 | struct sd *sd = (struct sd *) gspca_dev; |
2975 | struct cam *cam = &gspca_dev->cam; | 3181 | struct cam *cam = &gspca_dev->cam; |
2976 | int ret = 0; | ||
2977 | 3182 | ||
2978 | sd->bridge = id->driver_info & BRIDGE_MASK; | 3183 | sd->bridge = id->driver_info & BRIDGE_MASK; |
2979 | sd->invert_led = id->driver_info & BRIDGE_INVERT_LED; | 3184 | sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0; |
2980 | 3185 | ||
2981 | switch (sd->bridge) { | 3186 | switch (sd->bridge) { |
2982 | case BRIDGE_OV511: | 3187 | case BRIDGE_OV511: |
2983 | case BRIDGE_OV511PLUS: | 3188 | case BRIDGE_OV511PLUS: |
2984 | ret = ov511_configure(gspca_dev); | 3189 | cam->cam_mode = ov511_vga_mode; |
3190 | cam->nmodes = ARRAY_SIZE(ov511_vga_mode); | ||
2985 | break; | 3191 | break; |
2986 | case BRIDGE_OV518: | 3192 | case BRIDGE_OV518: |
2987 | case BRIDGE_OV518PLUS: | 3193 | case BRIDGE_OV518PLUS: |
2988 | ret = ov518_configure(gspca_dev); | 3194 | cam->cam_mode = ov518_vga_mode; |
3195 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); | ||
2989 | break; | 3196 | break; |
2990 | case BRIDGE_OV519: | 3197 | case BRIDGE_OV519: |
2991 | ret = ov519_configure(sd); | 3198 | cam->cam_mode = ov519_vga_mode; |
3199 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3200 | sd->invert_led = !sd->invert_led; | ||
2992 | break; | 3201 | break; |
2993 | case BRIDGE_OVFX2: | 3202 | case BRIDGE_OVFX2: |
2994 | ret = ovfx2_configure(sd); | 3203 | cam->cam_mode = ov519_vga_mode; |
3204 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
2995 | cam->bulk_size = OVFX2_BULK_SIZE; | 3205 | cam->bulk_size = OVFX2_BULK_SIZE; |
2996 | cam->bulk_nurbs = MAX_NURBS; | 3206 | cam->bulk_nurbs = MAX_NURBS; |
2997 | cam->bulk = 1; | 3207 | cam->bulk = 1; |
2998 | break; | 3208 | break; |
2999 | case BRIDGE_W9968CF: | 3209 | case BRIDGE_W9968CF: |
3000 | ret = w9968cf_configure(sd); | 3210 | cam->cam_mode = w9968cf_vga_mode; |
3211 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | ||
3001 | cam->reverse_alts = 1; | 3212 | cam->reverse_alts = 1; |
3002 | break; | 3213 | break; |
3003 | } | 3214 | } |
3004 | 3215 | ||
3005 | if (ret) | 3216 | gspca_dev->cam.ctrls = sd->ctrls; |
3006 | goto error; | 3217 | sd->quality = QUALITY_DEF; |
3007 | 3218 | ||
3008 | ov51x_led_control(sd, 0); /* turn LED off */ | 3219 | return 0; |
3220 | } | ||
3221 | |||
3222 | /* this function is called at probe and resume time */ | ||
3223 | static int sd_init(struct gspca_dev *gspca_dev) | ||
3224 | { | ||
3225 | struct sd *sd = (struct sd *) gspca_dev; | ||
3226 | struct cam *cam = &gspca_dev->cam; | ||
3227 | |||
3228 | switch (sd->bridge) { | ||
3229 | case BRIDGE_OV511: | ||
3230 | case BRIDGE_OV511PLUS: | ||
3231 | ov511_configure(gspca_dev); | ||
3232 | break; | ||
3233 | case BRIDGE_OV518: | ||
3234 | case BRIDGE_OV518PLUS: | ||
3235 | ov518_configure(gspca_dev); | ||
3236 | break; | ||
3237 | case BRIDGE_OV519: | ||
3238 | ov519_configure(sd); | ||
3239 | break; | ||
3240 | case BRIDGE_OVFX2: | ||
3241 | ovfx2_configure(sd); | ||
3242 | break; | ||
3243 | case BRIDGE_W9968CF: | ||
3244 | w9968cf_configure(sd); | ||
3245 | break; | ||
3246 | } | ||
3009 | 3247 | ||
3010 | /* The OV519 must be more aggressive about sensor detection since | 3248 | /* The OV519 must be more aggressive about sensor detection since |
3011 | * I2C write will never fail if the sensor is not present. We have | 3249 | * I2C write will never fail if the sensor is not present. We have |
3012 | * to try to initialize the sensor to detect its presence */ | 3250 | * to try to initialize the sensor to detect its presence */ |
3251 | sd->sensor = -1; | ||
3013 | 3252 | ||
3014 | /* Test for 76xx */ | 3253 | /* Test for 76xx */ |
3015 | if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { | 3254 | if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { |
3016 | if (ov7xx0_configure(sd) < 0) { | 3255 | ov7xx0_configure(sd); |
3017 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); | 3256 | |
3018 | goto error; | ||
3019 | } | ||
3020 | /* Test for 6xx0 */ | 3257 | /* Test for 6xx0 */ |
3021 | } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { | 3258 | } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { |
3022 | if (ov6xx0_configure(sd) < 0) { | 3259 | ov6xx0_configure(sd); |
3023 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); | 3260 | |
3024 | goto error; | ||
3025 | } | ||
3026 | /* Test for 8xx0 */ | 3261 | /* Test for 8xx0 */ |
3027 | } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { | 3262 | } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { |
3028 | if (ov8xx0_configure(sd) < 0) { | 3263 | ov8xx0_configure(sd); |
3029 | PDEBUG(D_ERR, "Failed to configure OV8xx0"); | 3264 | |
3030 | goto error; | ||
3031 | } | ||
3032 | /* Test for 3xxx / 2xxx */ | 3265 | /* Test for 3xxx / 2xxx */ |
3033 | } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { | 3266 | } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { |
3034 | if (ov_hires_configure(sd) < 0) { | 3267 | ov_hires_configure(sd); |
3035 | PDEBUG(D_ERR, "Failed to configure high res OV"); | ||
3036 | goto error; | ||
3037 | } | ||
3038 | } else { | 3268 | } else { |
3039 | err("Can't determine sensor slave IDs"); | 3269 | err("Can't determine sensor slave IDs"); |
3040 | goto error; | 3270 | goto error; |
3041 | } | 3271 | } |
3042 | 3272 | ||
3273 | if (sd->sensor < 0) | ||
3274 | goto error; | ||
3275 | |||
3276 | ov51x_led_control(sd, 0); /* turn LED off */ | ||
3277 | |||
3043 | switch (sd->bridge) { | 3278 | switch (sd->bridge) { |
3044 | case BRIDGE_OV511: | 3279 | case BRIDGE_OV511: |
3045 | case BRIDGE_OV511PLUS: | 3280 | case BRIDGE_OV511PLUS: |
3046 | if (!sd->sif) { | 3281 | if (sd->sif) { |
3047 | cam->cam_mode = ov511_vga_mode; | ||
3048 | cam->nmodes = ARRAY_SIZE(ov511_vga_mode); | ||
3049 | } else { | ||
3050 | cam->cam_mode = ov511_sif_mode; | 3282 | cam->cam_mode = ov511_sif_mode; |
3051 | cam->nmodes = ARRAY_SIZE(ov511_sif_mode); | 3283 | cam->nmodes = ARRAY_SIZE(ov511_sif_mode); |
3052 | } | 3284 | } |
3053 | break; | 3285 | break; |
3054 | case BRIDGE_OV518: | 3286 | case BRIDGE_OV518: |
3055 | case BRIDGE_OV518PLUS: | 3287 | case BRIDGE_OV518PLUS: |
3056 | if (!sd->sif) { | 3288 | if (sd->sif) { |
3057 | cam->cam_mode = ov518_vga_mode; | ||
3058 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); | ||
3059 | } else { | ||
3060 | cam->cam_mode = ov518_sif_mode; | 3289 | cam->cam_mode = ov518_sif_mode; |
3061 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); | 3290 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); |
3062 | } | 3291 | } |
3063 | break; | 3292 | break; |
3064 | case BRIDGE_OV519: | 3293 | case BRIDGE_OV519: |
3065 | if (!sd->sif) { | 3294 | if (sd->sif) { |
3066 | cam->cam_mode = ov519_vga_mode; | ||
3067 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3068 | } else { | ||
3069 | cam->cam_mode = ov519_sif_mode; | 3295 | cam->cam_mode = ov519_sif_mode; |
3070 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3296 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); |
3071 | } | 3297 | } |
@@ -3077,118 +3303,107 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3077 | } else if (sd->sensor == SEN_OV3610) { | 3303 | } else if (sd->sensor == SEN_OV3610) { |
3078 | cam->cam_mode = ovfx2_ov3610_mode; | 3304 | cam->cam_mode = ovfx2_ov3610_mode; |
3079 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); | 3305 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); |
3080 | } else if (!sd->sif) { | 3306 | } else if (sd->sif) { |
3081 | cam->cam_mode = ov519_vga_mode; | ||
3082 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3083 | } else { | ||
3084 | cam->cam_mode = ov519_sif_mode; | 3307 | cam->cam_mode = ov519_sif_mode; |
3085 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3308 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); |
3086 | } | 3309 | } |
3087 | break; | 3310 | break; |
3088 | case BRIDGE_W9968CF: | 3311 | case BRIDGE_W9968CF: |
3089 | cam->cam_mode = w9968cf_vga_mode; | ||
3090 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | ||
3091 | if (sd->sif) | 3312 | if (sd->sif) |
3092 | cam->nmodes--; | 3313 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1; |
3093 | 3314 | ||
3094 | /* w9968cf needs initialisation once the sensor is known */ | 3315 | /* w9968cf needs initialisation once the sensor is known */ |
3095 | if (w9968cf_init(sd) < 0) | 3316 | w9968cf_init(sd); |
3096 | goto error; | ||
3097 | break; | 3317 | break; |
3098 | } | 3318 | } |
3099 | gspca_dev->cam.ctrls = sd->ctrls; | ||
3100 | if (sd->sensor == SEN_OV7670) | ||
3101 | gspca_dev->ctrl_dis = 1 << COLORS; | ||
3102 | else | ||
3103 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); | ||
3104 | sd->quality = QUALITY_DEF; | ||
3105 | if (sd->sensor == SEN_OV7640 || | ||
3106 | sd->sensor == SEN_OV7648) | ||
3107 | gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST); | ||
3108 | if (sd->sensor == SEN_OV7670) | ||
3109 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT; | ||
3110 | /* OV8610 Frequency filter control should work but needs testing */ | ||
3111 | if (sd->sensor == SEN_OV8610) | ||
3112 | gspca_dev->ctrl_dis |= 1 << FREQ; | ||
3113 | /* No controls for the OV2610/OV3610 */ | ||
3114 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
3115 | gspca_dev->ctrl_dis |= (1 << NCTRL) - 1; | ||
3116 | 3319 | ||
3117 | return 0; | 3320 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; |
3118 | error: | ||
3119 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
3120 | return -EBUSY; | ||
3121 | } | ||
3122 | |||
3123 | /* this function is called at probe and resume time */ | ||
3124 | static int sd_init(struct gspca_dev *gspca_dev) | ||
3125 | { | ||
3126 | struct sd *sd = (struct sd *) gspca_dev; | ||
3127 | 3321 | ||
3128 | /* initialize the sensor */ | 3322 | /* initialize the sensor */ |
3129 | switch (sd->sensor) { | 3323 | switch (sd->sensor) { |
3130 | case SEN_OV2610: | 3324 | case SEN_OV2610: |
3131 | if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610))) | 3325 | write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)); |
3132 | return -EIO; | 3326 | |
3133 | /* Enable autogain, autoexpo, awb, bandfilter */ | 3327 | /* Enable autogain, autoexpo, awb, bandfilter */ |
3134 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | 3328 | i2c_w_mask(sd, 0x13, 0x27, 0x27); |
3135 | return -EIO; | ||
3136 | break; | 3329 | break; |
3137 | case SEN_OV3610: | 3330 | case SEN_OV3610: |
3138 | if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b))) | 3331 | write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); |
3139 | return -EIO; | 3332 | |
3140 | /* Enable autogain, autoexpo, awb, bandfilter */ | 3333 | /* Enable autogain, autoexpo, awb, bandfilter */ |
3141 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | 3334 | i2c_w_mask(sd, 0x13, 0x27, 0x27); |
3142 | return -EIO; | ||
3143 | break; | 3335 | break; |
3144 | case SEN_OV6620: | 3336 | case SEN_OV6620: |
3145 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) | 3337 | write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)); |
3146 | return -EIO; | ||
3147 | break; | 3338 | break; |
3148 | case SEN_OV6630: | 3339 | case SEN_OV6630: |
3149 | case SEN_OV66308AF: | 3340 | case SEN_OV66308AF: |
3150 | sd->ctrls[CONTRAST].def = 200; | 3341 | sd->ctrls[CONTRAST].def = 200; |
3151 | /* The default is too low for the ov6630 */ | 3342 | /* The default is too low for the ov6630 */ |
3152 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) | 3343 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); |
3153 | return -EIO; | ||
3154 | break; | 3344 | break; |
3155 | default: | 3345 | default: |
3156 | /* case SEN_OV7610: */ | 3346 | /* case SEN_OV7610: */ |
3157 | /* case SEN_OV76BE: */ | 3347 | /* case SEN_OV76BE: */ |
3158 | if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) | 3348 | write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)); |
3159 | return -EIO; | 3349 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); |
3160 | if (i2c_w_mask(sd, 0x0e, 0x00, 0x40)) | ||
3161 | return -EIO; | ||
3162 | break; | 3350 | break; |
3163 | case SEN_OV7620: | 3351 | case SEN_OV7620: |
3164 | case SEN_OV7620AE: | 3352 | case SEN_OV7620AE: |
3165 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) | 3353 | write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)); |
3166 | return -EIO; | ||
3167 | break; | 3354 | break; |
3168 | case SEN_OV7640: | 3355 | case SEN_OV7640: |
3169 | case SEN_OV7648: | 3356 | case SEN_OV7648: |
3170 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) | 3357 | write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)); |
3171 | return -EIO; | 3358 | break; |
3359 | case SEN_OV7660: | ||
3360 | i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET); | ||
3361 | msleep(14); | ||
3362 | reg_w(sd, OV519_R57_SNAPSHOT, 0x23); | ||
3363 | write_regvals(sd, init_519_ov7660, | ||
3364 | ARRAY_SIZE(init_519_ov7660)); | ||
3365 | write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660)); | ||
3366 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ | ||
3367 | sd->frame_rate = 15; | ||
3368 | ov519_set_mode(sd); | ||
3369 | ov519_set_fr(sd); | ||
3370 | sd->ctrls[COLORS].max = 4; /* 0..4 */ | ||
3371 | sd->ctrls[COLORS].val = | ||
3372 | sd->ctrls[COLORS].def = 2; | ||
3373 | setcolors(gspca_dev); | ||
3374 | sd->ctrls[CONTRAST].max = 6; /* 0..6 */ | ||
3375 | sd->ctrls[CONTRAST].val = | ||
3376 | sd->ctrls[CONTRAST].def = 3; | ||
3377 | setcontrast(gspca_dev); | ||
3378 | sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */ | ||
3379 | sd->ctrls[BRIGHTNESS].val = | ||
3380 | sd->ctrls[BRIGHTNESS].def = 3; | ||
3381 | setbrightness(gspca_dev); | ||
3382 | sd_reset_snapshot(gspca_dev); | ||
3383 | ov51x_restart(sd); | ||
3384 | ov51x_stop(sd); /* not in win traces */ | ||
3385 | ov51x_led_control(sd, 0); | ||
3172 | break; | 3386 | break; |
3173 | case SEN_OV7670: | 3387 | case SEN_OV7670: |
3174 | sd->ctrls[FREQ].max = 3; /* auto */ | 3388 | sd->ctrls[FREQ].max = 3; /* auto */ |
3175 | sd->ctrls[FREQ].def = 3; | 3389 | sd->ctrls[FREQ].def = 3; |
3176 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) | 3390 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); |
3177 | return -EIO; | ||
3178 | break; | 3391 | break; |
3179 | case SEN_OV8610: | 3392 | case SEN_OV8610: |
3180 | if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) | 3393 | write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)); |
3181 | return -EIO; | ||
3182 | break; | 3394 | break; |
3183 | } | 3395 | } |
3184 | return 0; | 3396 | return gspca_dev->usb_err; |
3397 | error: | ||
3398 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
3399 | return -EINVAL; | ||
3185 | } | 3400 | } |
3186 | 3401 | ||
3187 | /* Set up the OV511/OV511+ with the given image parameters. | 3402 | /* Set up the OV511/OV511+ with the given image parameters. |
3188 | * | 3403 | * |
3189 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3404 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3190 | */ | 3405 | */ |
3191 | static int ov511_mode_init_regs(struct sd *sd) | 3406 | static void ov511_mode_init_regs(struct sd *sd) |
3192 | { | 3407 | { |
3193 | int hsegs, vsegs, packet_size, fps, needed; | 3408 | int hsegs, vsegs, packet_size, fps, needed; |
3194 | int interlaced = 0; | 3409 | int interlaced = 0; |
@@ -3199,7 +3414,8 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3199 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3414 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3200 | if (!alt) { | 3415 | if (!alt) { |
3201 | err("Couldn't get altsetting"); | 3416 | err("Couldn't get altsetting"); |
3202 | return -EIO; | 3417 | sd->gspca_dev.usb_err = -EIO; |
3418 | return; | ||
3203 | } | 3419 | } |
3204 | 3420 | ||
3205 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 3421 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
@@ -3302,8 +3518,6 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3302 | 3518 | ||
3303 | reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); | 3519 | reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); |
3304 | reg_w(sd, R51x_SYS_RESET, 0); | 3520 | reg_w(sd, R51x_SYS_RESET, 0); |
3305 | |||
3306 | return 0; | ||
3307 | } | 3521 | } |
3308 | 3522 | ||
3309 | /* Sets up the OV518/OV518+ with the given image parameters | 3523 | /* Sets up the OV518/OV518+ with the given image parameters |
@@ -3313,7 +3527,7 @@ static int ov511_mode_init_regs(struct sd *sd) | |||
3313 | * | 3527 | * |
3314 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3528 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3315 | */ | 3529 | */ |
3316 | static int ov518_mode_init_regs(struct sd *sd) | 3530 | static void ov518_mode_init_regs(struct sd *sd) |
3317 | { | 3531 | { |
3318 | int hsegs, vsegs, packet_size; | 3532 | int hsegs, vsegs, packet_size; |
3319 | struct usb_host_interface *alt; | 3533 | struct usb_host_interface *alt; |
@@ -3323,14 +3537,14 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3323 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | 3537 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); |
3324 | if (!alt) { | 3538 | if (!alt) { |
3325 | err("Couldn't get altsetting"); | 3539 | err("Couldn't get altsetting"); |
3326 | return -EIO; | 3540 | sd->gspca_dev.usb_err = -EIO; |
3541 | return; | ||
3327 | } | 3542 | } |
3328 | 3543 | ||
3329 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | 3544 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
3330 | ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); | 3545 | ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); |
3331 | 3546 | ||
3332 | /******** Set the mode ********/ | 3547 | /******** Set the mode ********/ |
3333 | |||
3334 | reg_w(sd, 0x2b, 0); | 3548 | reg_w(sd, 0x2b, 0); |
3335 | reg_w(sd, 0x2c, 0); | 3549 | reg_w(sd, 0x2c, 0); |
3336 | reg_w(sd, 0x2d, 0); | 3550 | reg_w(sd, 0x2d, 0); |
@@ -3364,7 +3578,7 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3364 | /* Windows driver does this here; who knows why */ | 3578 | /* Windows driver does this here; who knows why */ |
3365 | reg_w(sd, 0x2f, 0x80); | 3579 | reg_w(sd, 0x2f, 0x80); |
3366 | 3580 | ||
3367 | /******** Set the framerate ********/ | 3581 | /******** Set the framerate ********/ |
3368 | sd->clockdiv = 1; | 3582 | sd->clockdiv = 1; |
3369 | 3583 | ||
3370 | /* Mode independent, but framerate dependent, regs */ | 3584 | /* Mode independent, but framerate dependent, regs */ |
@@ -3427,11 +3641,8 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3427 | } | 3641 | } |
3428 | 3642 | ||
3429 | reg_w(sd, 0x2f, 0x80); | 3643 | reg_w(sd, 0x2f, 0x80); |
3430 | |||
3431 | return 0; | ||
3432 | } | 3644 | } |
3433 | 3645 | ||
3434 | |||
3435 | /* Sets up the OV519 with the given image parameters | 3646 | /* Sets up the OV519 with the given image parameters |
3436 | * | 3647 | * |
3437 | * OV519 needs a completely different approach, until we can figure out what | 3648 | * OV519 needs a completely different approach, until we can figure out what |
@@ -3439,12 +3650,12 @@ static int ov518_mode_init_regs(struct sd *sd) | |||
3439 | * | 3650 | * |
3440 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 3651 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
3441 | */ | 3652 | */ |
3442 | static int ov519_mode_init_regs(struct sd *sd) | 3653 | static void ov519_mode_init_regs(struct sd *sd) |
3443 | { | 3654 | { |
3444 | static const struct ov_regvals mode_init_519_ov7670[] = { | 3655 | static const struct ov_regvals mode_init_519_ov7670[] = { |
3445 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 3656 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
3446 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | 3657 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ |
3447 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | 3658 | { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ |
3448 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | 3659 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ |
3449 | { 0xa3, 0x18 }, | 3660 | { 0xa3, 0x18 }, |
3450 | { 0xa4, 0x04 }, | 3661 | { 0xa4, 0x04 }, |
@@ -3467,7 +3678,7 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3467 | static const struct ov_regvals mode_init_519[] = { | 3678 | static const struct ov_regvals mode_init_519[] = { |
3468 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 3679 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
3469 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | 3680 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ |
3470 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | 3681 | { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */ |
3471 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | 3682 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ |
3472 | { 0xa3, 0x18 }, | 3683 | { 0xa3, 0x18 }, |
3473 | { 0xa4, 0x04 }, | 3684 | { 0xa4, 0x04 }, |
@@ -3486,19 +3697,21 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3486 | }; | 3697 | }; |
3487 | 3698 | ||
3488 | /******** Set the mode ********/ | 3699 | /******** Set the mode ********/ |
3489 | if (sd->sensor != SEN_OV7670) { | 3700 | switch (sd->sensor) { |
3490 | if (write_regvals(sd, mode_init_519, | 3701 | default: |
3491 | ARRAY_SIZE(mode_init_519))) | 3702 | write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519)); |
3492 | return -EIO; | ||
3493 | if (sd->sensor == SEN_OV7640 || | 3703 | if (sd->sensor == SEN_OV7640 || |
3494 | sd->sensor == SEN_OV7648) { | 3704 | sd->sensor == SEN_OV7648) { |
3495 | /* Select 8-bit input mode */ | 3705 | /* Select 8-bit input mode */ |
3496 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); | 3706 | reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); |
3497 | } | 3707 | } |
3498 | } else { | 3708 | break; |
3499 | if (write_regvals(sd, mode_init_519_ov7670, | 3709 | case SEN_OV7660: |
3500 | ARRAY_SIZE(mode_init_519_ov7670))) | 3710 | return; /* done by ov519_set_mode/fr() */ |
3501 | return -EIO; | 3711 | case SEN_OV7670: |
3712 | write_regvals(sd, mode_init_519_ov7670, | ||
3713 | ARRAY_SIZE(mode_init_519_ov7670)); | ||
3714 | break; | ||
3502 | } | 3715 | } |
3503 | 3716 | ||
3504 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); | 3717 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); |
@@ -3594,17 +3807,16 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
3594 | } | 3807 | } |
3595 | break; | 3808 | break; |
3596 | } | 3809 | } |
3597 | return 0; | ||
3598 | } | 3810 | } |
3599 | 3811 | ||
3600 | static int mode_init_ov_sensor_regs(struct sd *sd) | 3812 | static void mode_init_ov_sensor_regs(struct sd *sd) |
3601 | { | 3813 | { |
3602 | struct gspca_dev *gspca_dev; | 3814 | struct gspca_dev *gspca_dev; |
3603 | int qvga, xstart, xend, ystart, yend; | 3815 | int qvga, xstart, xend, ystart, yend; |
3604 | __u8 v; | 3816 | u8 v; |
3605 | 3817 | ||
3606 | gspca_dev = &sd->gspca_dev; | 3818 | gspca_dev = &sd->gspca_dev; |
3607 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3819 | qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; |
3608 | 3820 | ||
3609 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 3821 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
3610 | switch (sd->sensor) { | 3822 | switch (sd->sensor) { |
@@ -3616,7 +3828,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3616 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | 3828 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); |
3617 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | 3829 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); |
3618 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | 3830 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); |
3619 | return 0; | 3831 | return; |
3620 | case SEN_OV3610: | 3832 | case SEN_OV3610: |
3621 | if (qvga) { | 3833 | if (qvga) { |
3622 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); | 3834 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); |
@@ -3640,7 +3852,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3640 | i2c_w(sd, 0x18, xend >> 4); | 3852 | i2c_w(sd, 0x18, xend >> 4); |
3641 | i2c_w(sd, 0x19, ystart >> 3); | 3853 | i2c_w(sd, 0x19, ystart >> 3); |
3642 | i2c_w(sd, 0x1a, yend >> 3); | 3854 | i2c_w(sd, 0x1a, yend >> 3); |
3643 | return 0; | 3855 | return; |
3644 | case SEN_OV8610: | 3856 | case SEN_OV8610: |
3645 | /* For OV8610 qvga means qsvga */ | 3857 | /* For OV8610 qvga means qsvga */ |
3646 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); | 3858 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); |
@@ -3687,11 +3899,11 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3687 | /* set COM7_FMT_VGA or COM7_FMT_QVGA | 3899 | /* set COM7_FMT_VGA or COM7_FMT_QVGA |
3688 | * do we need to set anything else? | 3900 | * do we need to set anything else? |
3689 | * HSTART etc are set in set_ov_sensor_window itself */ | 3901 | * HSTART etc are set in set_ov_sensor_window itself */ |
3690 | i2c_w_mask(sd, OV7670_REG_COM7, | 3902 | i2c_w_mask(sd, OV7670_R12_COM7, |
3691 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, | 3903 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, |
3692 | OV7670_COM7_FMT_MASK); | 3904 | OV7670_COM7_FMT_MASK); |
3693 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | 3905 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ |
3694 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | 3906 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB, |
3695 | OV7670_COM8_AWB); | 3907 | OV7670_COM8_AWB); |
3696 | if (qvga) { /* QVGA from ov7670.c by | 3908 | if (qvga) { /* QVGA from ov7670.c by |
3697 | * Jonathan Corbet */ | 3909 | * Jonathan Corbet */ |
@@ -3707,21 +3919,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3707 | } | 3919 | } |
3708 | /* OV7670 hardware window registers are split across | 3920 | /* OV7670 hardware window registers are split across |
3709 | * multiple locations */ | 3921 | * multiple locations */ |
3710 | i2c_w(sd, OV7670_REG_HSTART, xstart >> 3); | 3922 | i2c_w(sd, OV7670_R17_HSTART, xstart >> 3); |
3711 | i2c_w(sd, OV7670_REG_HSTOP, xend >> 3); | 3923 | i2c_w(sd, OV7670_R18_HSTOP, xend >> 3); |
3712 | v = i2c_r(sd, OV7670_REG_HREF); | 3924 | v = i2c_r(sd, OV7670_R32_HREF); |
3713 | v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); | 3925 | v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); |
3714 | msleep(10); /* need to sleep between read and write to | 3926 | msleep(10); /* need to sleep between read and write to |
3715 | * same reg! */ | 3927 | * same reg! */ |
3716 | i2c_w(sd, OV7670_REG_HREF, v); | 3928 | i2c_w(sd, OV7670_R32_HREF, v); |
3717 | 3929 | ||
3718 | i2c_w(sd, OV7670_REG_VSTART, ystart >> 2); | 3930 | i2c_w(sd, OV7670_R19_VSTART, ystart >> 2); |
3719 | i2c_w(sd, OV7670_REG_VSTOP, yend >> 2); | 3931 | i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2); |
3720 | v = i2c_r(sd, OV7670_REG_VREF); | 3932 | v = i2c_r(sd, OV7670_R03_VREF); |
3721 | v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); | 3933 | v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); |
3722 | msleep(10); /* need to sleep between read and write to | 3934 | msleep(10); /* need to sleep between read and write to |
3723 | * same reg! */ | 3935 | * same reg! */ |
3724 | i2c_w(sd, OV7670_REG_VREF, v); | 3936 | i2c_w(sd, OV7670_R03_VREF, v); |
3725 | break; | 3937 | break; |
3726 | case SEN_OV6620: | 3938 | case SEN_OV6620: |
3727 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3939 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
@@ -3734,46 +3946,50 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
3734 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | 3946 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ |
3735 | break; | 3947 | break; |
3736 | default: | 3948 | default: |
3737 | return -EINVAL; | 3949 | return; |
3738 | } | 3950 | } |
3739 | 3951 | ||
3740 | /******** Clock programming ********/ | 3952 | /******** Clock programming ********/ |
3741 | i2c_w(sd, 0x11, sd->clockdiv); | 3953 | i2c_w(sd, 0x11, sd->clockdiv); |
3742 | |||
3743 | return 0; | ||
3744 | } | 3954 | } |
3745 | 3955 | ||
3956 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ | ||
3746 | static void sethvflip(struct gspca_dev *gspca_dev) | 3957 | static void sethvflip(struct gspca_dev *gspca_dev) |
3747 | { | 3958 | { |
3748 | struct sd *sd = (struct sd *) gspca_dev; | 3959 | struct sd *sd = (struct sd *) gspca_dev; |
3749 | 3960 | ||
3750 | if (sd->sensor != SEN_OV7670) | ||
3751 | return; | ||
3752 | if (sd->gspca_dev.streaming) | 3961 | if (sd->gspca_dev.streaming) |
3753 | ov51x_stop(sd); | 3962 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ |
3754 | i2c_w_mask(sd, OV7670_REG_MVFP, | 3963 | i2c_w_mask(sd, OV7670_R1E_MVFP, |
3755 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val | 3964 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val |
3756 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, | 3965 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, |
3757 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | 3966 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); |
3758 | if (sd->gspca_dev.streaming) | 3967 | if (sd->gspca_dev.streaming) |
3759 | ov51x_restart(sd); | 3968 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ |
3760 | } | 3969 | } |
3761 | 3970 | ||
3762 | static int set_ov_sensor_window(struct sd *sd) | 3971 | static void set_ov_sensor_window(struct sd *sd) |
3763 | { | 3972 | { |
3764 | struct gspca_dev *gspca_dev; | 3973 | struct gspca_dev *gspca_dev; |
3765 | int qvga, crop; | 3974 | int qvga, crop; |
3766 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 3975 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
3767 | int ret; | ||
3768 | 3976 | ||
3769 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ | 3977 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ |
3770 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 || | 3978 | switch (sd->sensor) { |
3771 | sd->sensor == SEN_OV7670) | 3979 | case SEN_OV2610: |
3772 | return mode_init_ov_sensor_regs(sd); | 3980 | case SEN_OV3610: |
3981 | case SEN_OV7670: | ||
3982 | mode_init_ov_sensor_regs(sd); | ||
3983 | return; | ||
3984 | case SEN_OV7660: | ||
3985 | ov519_set_mode(sd); | ||
3986 | ov519_set_fr(sd); | ||
3987 | return; | ||
3988 | } | ||
3773 | 3989 | ||
3774 | gspca_dev = &sd->gspca_dev; | 3990 | gspca_dev = &sd->gspca_dev; |
3775 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3991 | qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; |
3776 | crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2; | 3992 | crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2; |
3777 | 3993 | ||
3778 | /* The different sensor ICs handle setting up of window differently. | 3994 | /* The different sensor ICs handle setting up of window differently. |
3779 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | 3995 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ |
@@ -3820,7 +4036,7 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3820 | vwsbase = vwebase = 0x03; | 4036 | vwsbase = vwebase = 0x03; |
3821 | break; | 4037 | break; |
3822 | default: | 4038 | default: |
3823 | return -EINVAL; | 4039 | return; |
3824 | } | 4040 | } |
3825 | 4041 | ||
3826 | switch (sd->sensor) { | 4042 | switch (sd->sensor) { |
@@ -3855,23 +4071,18 @@ static int set_ov_sensor_window(struct sd *sd) | |||
3855 | } | 4071 | } |
3856 | } | 4072 | } |
3857 | 4073 | ||
3858 | ret = mode_init_ov_sensor_regs(sd); | 4074 | mode_init_ov_sensor_regs(sd); |
3859 | if (ret < 0) | ||
3860 | return ret; | ||
3861 | 4075 | ||
3862 | i2c_w(sd, 0x17, hwsbase); | 4076 | i2c_w(sd, 0x17, hwsbase); |
3863 | i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); | 4077 | i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); |
3864 | i2c_w(sd, 0x19, vwsbase); | 4078 | i2c_w(sd, 0x19, vwsbase); |
3865 | i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); | 4079 | i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); |
3866 | |||
3867 | return 0; | ||
3868 | } | 4080 | } |
3869 | 4081 | ||
3870 | /* -- start the camera -- */ | 4082 | /* -- start the camera -- */ |
3871 | static int sd_start(struct gspca_dev *gspca_dev) | 4083 | static int sd_start(struct gspca_dev *gspca_dev) |
3872 | { | 4084 | { |
3873 | struct sd *sd = (struct sd *) gspca_dev; | 4085 | struct sd *sd = (struct sd *) gspca_dev; |
3874 | int ret = 0; | ||
3875 | 4086 | ||
3876 | /* Default for most bridges, allow bridge_mode_init_regs to override */ | 4087 | /* Default for most bridges, allow bridge_mode_init_regs to override */ |
3877 | sd->sensor_width = sd->gspca_dev.width; | 4088 | sd->sensor_width = sd->gspca_dev.width; |
@@ -3880,50 +4091,46 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
3880 | switch (sd->bridge) { | 4091 | switch (sd->bridge) { |
3881 | case BRIDGE_OV511: | 4092 | case BRIDGE_OV511: |
3882 | case BRIDGE_OV511PLUS: | 4093 | case BRIDGE_OV511PLUS: |
3883 | ret = ov511_mode_init_regs(sd); | 4094 | ov511_mode_init_regs(sd); |
3884 | break; | 4095 | break; |
3885 | case BRIDGE_OV518: | 4096 | case BRIDGE_OV518: |
3886 | case BRIDGE_OV518PLUS: | 4097 | case BRIDGE_OV518PLUS: |
3887 | ret = ov518_mode_init_regs(sd); | 4098 | ov518_mode_init_regs(sd); |
3888 | break; | 4099 | break; |
3889 | case BRIDGE_OV519: | 4100 | case BRIDGE_OV519: |
3890 | ret = ov519_mode_init_regs(sd); | 4101 | ov519_mode_init_regs(sd); |
3891 | break; | 4102 | break; |
3892 | /* case BRIDGE_OVFX2: nothing to do */ | 4103 | /* case BRIDGE_OVFX2: nothing to do */ |
3893 | case BRIDGE_W9968CF: | 4104 | case BRIDGE_W9968CF: |
3894 | ret = w9968cf_mode_init_regs(sd); | 4105 | w9968cf_mode_init_regs(sd); |
3895 | break; | 4106 | break; |
3896 | } | 4107 | } |
3897 | if (ret < 0) | 4108 | |
3898 | goto out; | 4109 | set_ov_sensor_window(sd); |
3899 | 4110 | ||
3900 | ret = set_ov_sensor_window(sd); | 4111 | if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST))) |
3901 | if (ret < 0) | 4112 | setcontrast(gspca_dev); |
3902 | goto out; | 4113 | if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) |
3903 | 4114 | setbrightness(gspca_dev); | |
3904 | setcontrast(gspca_dev); | 4115 | if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) |
3905 | setbrightness(gspca_dev); | 4116 | setcolors(gspca_dev); |
3906 | setcolors(gspca_dev); | 4117 | if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) |
3907 | sethvflip(gspca_dev); | 4118 | sethvflip(gspca_dev); |
3908 | setautobright(gspca_dev); | 4119 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) |
3909 | setfreq_i(sd); | 4120 | setautobright(gspca_dev); |
4121 | if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) | ||
4122 | setfreq_i(sd); | ||
3910 | 4123 | ||
3911 | /* Force clear snapshot state in case the snapshot button was | 4124 | /* Force clear snapshot state in case the snapshot button was |
3912 | pressed while we weren't streaming */ | 4125 | pressed while we weren't streaming */ |
3913 | sd->snapshot_needs_reset = 1; | 4126 | sd->snapshot_needs_reset = 1; |
3914 | sd_reset_snapshot(gspca_dev); | 4127 | sd_reset_snapshot(gspca_dev); |
3915 | sd->snapshot_pressed = 0; | ||
3916 | 4128 | ||
3917 | sd->first_frame = 3; | 4129 | sd->first_frame = 3; |
3918 | 4130 | ||
3919 | ret = ov51x_restart(sd); | 4131 | ov51x_restart(sd); |
3920 | if (ret < 0) | ||
3921 | goto out; | ||
3922 | ov51x_led_control(sd, 1); | 4132 | ov51x_led_control(sd, 1); |
3923 | return 0; | 4133 | return gspca_dev->usb_err; |
3924 | out: | ||
3925 | PDEBUG(D_ERR, "camera start error:%d", ret); | ||
3926 | return ret; | ||
3927 | } | 4134 | } |
3928 | 4135 | ||
3929 | static void sd_stopN(struct gspca_dev *gspca_dev) | 4136 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -3938,8 +4145,21 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
3938 | { | 4145 | { |
3939 | struct sd *sd = (struct sd *) gspca_dev; | 4146 | struct sd *sd = (struct sd *) gspca_dev; |
3940 | 4147 | ||
4148 | if (!sd->gspca_dev.present) | ||
4149 | return; | ||
3941 | if (sd->bridge == BRIDGE_W9968CF) | 4150 | if (sd->bridge == BRIDGE_W9968CF) |
3942 | w9968cf_stop0(sd); | 4151 | w9968cf_stop0(sd); |
4152 | |||
4153 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
4154 | /* If the last button state is pressed, release it now! */ | ||
4155 | if (sd->snapshot_pressed) { | ||
4156 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | ||
4157 | input_sync(gspca_dev->input_dev); | ||
4158 | sd->snapshot_pressed = 0; | ||
4159 | } | ||
4160 | #endif | ||
4161 | if (sd->bridge == BRIDGE_OV519) | ||
4162 | reg_w(sd, OV519_R57_SNAPSHOT, 0x23); | ||
3943 | } | 4163 | } |
3944 | 4164 | ||
3945 | static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) | 4165 | static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state) |
@@ -4160,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4160 | { | 4380 | { |
4161 | struct sd *sd = (struct sd *) gspca_dev; | 4381 | struct sd *sd = (struct sd *) gspca_dev; |
4162 | int val; | 4382 | int val; |
4383 | static const struct ov_i2c_regvals brit_7660[][7] = { | ||
4384 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, | ||
4385 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, | ||
4386 | {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1}, | ||
4387 | {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}}, | ||
4388 | {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2}, | ||
4389 | {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}}, | ||
4390 | {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3}, | ||
4391 | {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}}, | ||
4392 | {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3}, | ||
4393 | {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}}, | ||
4394 | {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3}, | ||
4395 | {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}}, | ||
4396 | {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4}, | ||
4397 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} | ||
4398 | }; | ||
4163 | 4399 | ||
4164 | val = sd->ctrls[BRIGHTNESS].val; | 4400 | val = sd->ctrls[BRIGHTNESS].val; |
4165 | switch (sd->sensor) { | 4401 | switch (sd->sensor) { |
@@ -4179,10 +4415,14 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4179 | if (!sd->ctrls[AUTOBRIGHT].val) | 4415 | if (!sd->ctrls[AUTOBRIGHT].val) |
4180 | i2c_w(sd, OV7610_REG_BRT, val); | 4416 | i2c_w(sd, OV7610_REG_BRT, val); |
4181 | break; | 4417 | break; |
4418 | case SEN_OV7660: | ||
4419 | write_i2c_regvals(sd, brit_7660[val], | ||
4420 | ARRAY_SIZE(brit_7660[0])); | ||
4421 | break; | ||
4182 | case SEN_OV7670: | 4422 | case SEN_OV7670: |
4183 | /*win trace | 4423 | /*win trace |
4184 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | 4424 | * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */ |
4185 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | 4425 | i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val)); |
4186 | break; | 4426 | break; |
4187 | } | 4427 | } |
4188 | } | 4428 | } |
@@ -4191,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4191 | { | 4431 | { |
4192 | struct sd *sd = (struct sd *) gspca_dev; | 4432 | struct sd *sd = (struct sd *) gspca_dev; |
4193 | int val; | 4433 | int val; |
4434 | static const struct ov_i2c_regvals contrast_7660[][31] = { | ||
4435 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, | ||
4436 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, | ||
4437 | {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24}, | ||
4438 | {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34}, | ||
4439 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65}, | ||
4440 | {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83}, | ||
4441 | {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f}, | ||
4442 | {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}}, | ||
4443 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94}, | ||
4444 | {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30}, | ||
4445 | {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24}, | ||
4446 | {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31}, | ||
4447 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62}, | ||
4448 | {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81}, | ||
4449 | {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1}, | ||
4450 | {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}}, | ||
4451 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84}, | ||
4452 | {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40}, | ||
4453 | {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24}, | ||
4454 | {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34}, | ||
4455 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d}, | ||
4456 | {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81}, | ||
4457 | {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e}, | ||
4458 | {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}}, | ||
4459 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70}, | ||
4460 | {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48}, | ||
4461 | {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34}, | ||
4462 | {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22}, | ||
4463 | {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58}, | ||
4464 | {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80}, | ||
4465 | {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9}, | ||
4466 | {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}}, | ||
4467 | {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80}, | ||
4468 | {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60}, | ||
4469 | {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38}, | ||
4470 | {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e}, | ||
4471 | {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46}, | ||
4472 | {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c}, | ||
4473 | {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4}, | ||
4474 | {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}}, | ||
4475 | {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80}, | ||
4476 | {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30}, | ||
4477 | {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50}, | ||
4478 | {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08}, | ||
4479 | {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a}, | ||
4480 | {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b}, | ||
4481 | {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3}, | ||
4482 | {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}}, | ||
4483 | {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60}, | ||
4484 | {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8}, | ||
4485 | {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c}, | ||
4486 | {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04}, | ||
4487 | {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22}, | ||
4488 | {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b}, | ||
4489 | {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde}, | ||
4490 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, | ||
4491 | }; | ||
4194 | 4492 | ||
4195 | val = sd->ctrls[CONTRAST].val; | 4493 | val = sd->ctrls[CONTRAST].val; |
4196 | switch (sd->sensor) { | 4494 | switch (sd->sensor) { |
@@ -4203,7 +4501,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4203 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | 4501 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); |
4204 | break; | 4502 | break; |
4205 | case SEN_OV8610: { | 4503 | case SEN_OV8610: { |
4206 | static const __u8 ctab[] = { | 4504 | static const u8 ctab[] = { |
4207 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | 4505 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f |
4208 | }; | 4506 | }; |
4209 | 4507 | ||
@@ -4213,7 +4511,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4213 | } | 4511 | } |
4214 | case SEN_OV7620: | 4512 | case SEN_OV7620: |
4215 | case SEN_OV7620AE: { | 4513 | case SEN_OV7620AE: { |
4216 | static const __u8 ctab[] = { | 4514 | static const u8 ctab[] = { |
4217 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, | 4515 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, |
4218 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff | 4516 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff |
4219 | }; | 4517 | }; |
@@ -4222,9 +4520,13 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4222 | i2c_w(sd, 0x64, ctab[val >> 4]); | 4520 | i2c_w(sd, 0x64, ctab[val >> 4]); |
4223 | break; | 4521 | break; |
4224 | } | 4522 | } |
4523 | case SEN_OV7660: | ||
4524 | write_i2c_regvals(sd, contrast_7660[val], | ||
4525 | ARRAY_SIZE(contrast_7660[0])); | ||
4526 | break; | ||
4225 | case SEN_OV7670: | 4527 | case SEN_OV7670: |
4226 | /* check that this isn't just the same as ov7610 */ | 4528 | /* check that this isn't just the same as ov7610 */ |
4227 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 4529 | i2c_w(sd, OV7670_R56_CONTRAS, val >> 1); |
4228 | break; | 4530 | break; |
4229 | } | 4531 | } |
4230 | } | 4532 | } |
@@ -4233,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4233 | { | 4535 | { |
4234 | struct sd *sd = (struct sd *) gspca_dev; | 4536 | struct sd *sd = (struct sd *) gspca_dev; |
4235 | int val; | 4537 | int val; |
4538 | static const struct ov_i2c_regvals colors_7660[][6] = { | ||
4539 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, | ||
4540 | {0x53, 0x19}, {0x54, 0x23}}, | ||
4541 | {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11}, | ||
4542 | {0x53, 0x2c}, {0x54, 0x3e}}, | ||
4543 | {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19}, | ||
4544 | {0x53, 0x40}, {0x54, 0x59}}, | ||
4545 | {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20}, | ||
4546 | {0x53, 0x53}, {0x54, 0x73}}, | ||
4547 | {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28}, | ||
4548 | {0x53, 0x66}, {0x54, 0x8e}}, | ||
4549 | }; | ||
4236 | 4550 | ||
4237 | val = sd->ctrls[COLORS].val; | 4551 | val = sd->ctrls[COLORS].val; |
4238 | switch (sd->sensor) { | 4552 | switch (sd->sensor) { |
@@ -4256,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4256 | case SEN_OV7648: | 4570 | case SEN_OV7648: |
4257 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | 4571 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); |
4258 | break; | 4572 | break; |
4573 | case SEN_OV7660: | ||
4574 | write_i2c_regvals(sd, colors_7660[val], | ||
4575 | ARRAY_SIZE(colors_7660[0])); | ||
4576 | break; | ||
4259 | case SEN_OV7670: | 4577 | case SEN_OV7670: |
4260 | /* supported later once I work out how to do it | 4578 | /* supported later once I work out how to do it |
4261 | * transparently fail now! */ | 4579 | * transparently fail now! */ |
@@ -4268,38 +4586,31 @@ static void setautobright(struct gspca_dev *gspca_dev) | |||
4268 | { | 4586 | { |
4269 | struct sd *sd = (struct sd *) gspca_dev; | 4587 | struct sd *sd = (struct sd *) gspca_dev; |
4270 | 4588 | ||
4271 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 || | ||
4272 | sd->sensor == SEN_OV7670 || | ||
4273 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
4274 | return; | ||
4275 | |||
4276 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); | 4589 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); |
4277 | } | 4590 | } |
4278 | 4591 | ||
4279 | static void setfreq_i(struct sd *sd) | 4592 | static void setfreq_i(struct sd *sd) |
4280 | { | 4593 | { |
4281 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | 4594 | if (sd->sensor == SEN_OV7660 |
4282 | return; | 4595 | || sd->sensor == SEN_OV7670) { |
4283 | |||
4284 | if (sd->sensor == SEN_OV7670) { | ||
4285 | switch (sd->ctrls[FREQ].val) { | 4596 | switch (sd->ctrls[FREQ].val) { |
4286 | case 0: /* Banding filter disabled */ | 4597 | case 0: /* Banding filter disabled */ |
4287 | i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT); | 4598 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); |
4288 | break; | 4599 | break; |
4289 | case 1: /* 50 hz */ | 4600 | case 1: /* 50 hz */ |
4290 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4601 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4291 | OV7670_COM8_BFILT); | 4602 | OV7670_COM8_BFILT); |
4292 | i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18); | 4603 | i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18); |
4293 | break; | 4604 | break; |
4294 | case 2: /* 60 hz */ | 4605 | case 2: /* 60 hz */ |
4295 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4606 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4296 | OV7670_COM8_BFILT); | 4607 | OV7670_COM8_BFILT); |
4297 | i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18); | 4608 | i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18); |
4298 | break; | 4609 | break; |
4299 | case 3: /* Auto hz */ | 4610 | case 3: /* Auto hz - ov7670 only */ |
4300 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, | 4611 | i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT, |
4301 | OV7670_COM8_BFILT); | 4612 | OV7670_COM8_BFILT); |
4302 | i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO, | 4613 | i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO, |
4303 | 0x18); | 4614 | 0x18); |
4304 | break; | 4615 | break; |
4305 | } | 4616 | } |
@@ -4443,14 +4754,14 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
4443 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, | 4754 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
4444 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, | 4755 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
4445 | {USB_DEVICE(0x041e, 0x4064), | 4756 | {USB_DEVICE(0x041e, 0x4064), |
4446 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4757 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4447 | {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, | 4758 | {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, |
4448 | {USB_DEVICE(0x041e, 0x4068), | 4759 | {USB_DEVICE(0x041e, 0x4068), |
4449 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4760 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4450 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, | 4761 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
4451 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, | 4762 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
4452 | {USB_DEVICE(0x054c, 0x0155), | 4763 | {USB_DEVICE(0x054c, 0x0155), |
4453 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4764 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4454 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, | 4765 | {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, |
4455 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, | 4766 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
4456 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, | 4767 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
@@ -4464,7 +4775,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
4464 | {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, | 4775 | {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, |
4465 | {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, | 4776 | {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, |
4466 | {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, | 4777 | {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, |
4467 | {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, | 4778 | {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 }, |
4468 | {} | 4779 | {} |
4469 | }; | 4780 | }; |
4470 | 4781 | ||