diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixb.c')
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 270 |
1 files changed, 157 insertions, 113 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 73504a3f87b7..c6cd68d66b53 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -23,8 +23,15 @@ | |||
23 | /* Some documentation on known sonixb registers: | 23 | /* Some documentation on known sonixb registers: |
24 | 24 | ||
25 | Reg Use | 25 | Reg Use |
26 | sn9c101 / sn9c102: | ||
26 | 0x10 high nibble red gain low nibble blue gain | 27 | 0x10 high nibble red gain low nibble blue gain |
27 | 0x11 low nibble green gain | 28 | 0x11 low nibble green gain |
29 | sn9c103: | ||
30 | 0x05 red gain 0-127 | ||
31 | 0x06 blue gain 0-127 | ||
32 | 0x07 green gain 0-127 | ||
33 | all: | ||
34 | 0x08-0x0f i2c / 3wire registers | ||
28 | 0x12 hstart | 35 | 0x12 hstart |
29 | 0x13 vstart | 36 | 0x13 vstart |
30 | 0x15 hsize (hsize = register-value * 16) | 37 | 0x15 hsize (hsize = register-value * 16) |
@@ -88,12 +95,9 @@ struct sd { | |||
88 | typedef const __u8 sensor_init_t[8]; | 95 | typedef const __u8 sensor_init_t[8]; |
89 | 96 | ||
90 | struct sensor_data { | 97 | struct sensor_data { |
91 | const __u8 *bridge_init[2]; | 98 | const __u8 *bridge_init; |
92 | int bridge_init_size[2]; | ||
93 | sensor_init_t *sensor_init; | 99 | sensor_init_t *sensor_init; |
94 | int sensor_init_size; | 100 | int sensor_init_size; |
95 | sensor_init_t *sensor_bridge_init[2]; | ||
96 | int sensor_bridge_init_size[2]; | ||
97 | int flags; | 101 | int flags; |
98 | unsigned ctrl_dis; | 102 | unsigned ctrl_dis; |
99 | __u8 sensor_addr; | 103 | __u8 sensor_addr; |
@@ -114,7 +118,6 @@ struct sensor_data { | |||
114 | #define NO_FREQ (1 << FREQ_IDX) | 118 | #define NO_FREQ (1 << FREQ_IDX) |
115 | #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) | 119 | #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) |
116 | 120 | ||
117 | #define COMP2 0x8f | ||
118 | #define COMP 0xc7 /* 0x87 //0x07 */ | 121 | #define COMP 0xc7 /* 0x87 //0x07 */ |
119 | #define COMP1 0xc9 /* 0x89 //0x09 */ | 122 | #define COMP1 0xc9 /* 0x89 //0x09 */ |
120 | 123 | ||
@@ -123,15 +126,11 @@ struct sensor_data { | |||
123 | 126 | ||
124 | #define SYS_CLK 0x04 | 127 | #define SYS_CLK 0x04 |
125 | 128 | ||
126 | #define SENS(bridge_1, bridge_3, sensor, sensor_1, \ | 129 | #define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \ |
127 | sensor_3, _flags, _ctrl_dis, _sensor_addr) \ | ||
128 | { \ | 130 | { \ |
129 | .bridge_init = { bridge_1, bridge_3 }, \ | 131 | .bridge_init = bridge, \ |
130 | .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \ | ||
131 | .sensor_init = sensor, \ | 132 | .sensor_init = sensor, \ |
132 | .sensor_init_size = sizeof(sensor), \ | 133 | .sensor_init_size = sizeof(sensor), \ |
133 | .sensor_bridge_init = { sensor_1, sensor_3,}, \ | ||
134 | .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \ | ||
135 | .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ | 134 | .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ |
136 | } | 135 | } |
137 | 136 | ||
@@ -311,7 +310,6 @@ static const __u8 initHv7131d[] = { | |||
311 | 0x00, 0x00, | 310 | 0x00, 0x00, |
312 | 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, | 311 | 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, |
313 | 0x28, 0x1e, 0x60, 0x8e, 0x42, | 312 | 0x28, 0x1e, 0x60, 0x8e, 0x42, |
314 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | ||
315 | }; | 313 | }; |
316 | static const __u8 hv7131d_sensor_init[][8] = { | 314 | static const __u8 hv7131d_sensor_init[][8] = { |
317 | {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, | 315 | {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, |
@@ -326,7 +324,6 @@ static const __u8 initHv7131r[] = { | |||
326 | 0x00, 0x00, | 324 | 0x00, 0x00, |
327 | 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, | 325 | 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, |
328 | 0x28, 0x1e, 0x60, 0x8a, 0x20, | 326 | 0x28, 0x1e, 0x60, 0x8a, 0x20, |
329 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | ||
330 | }; | 327 | }; |
331 | static const __u8 hv7131r_sensor_init[][8] = { | 328 | static const __u8 hv7131r_sensor_init[][8] = { |
332 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, | 329 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, |
@@ -339,7 +336,7 @@ static const __u8 initOv6650[] = { | |||
339 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | 336 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, |
340 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 337 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
341 | 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, | 338 | 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, |
342 | 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 | 339 | 0x10, |
343 | }; | 340 | }; |
344 | static const __u8 ov6650_sensor_init[][8] = { | 341 | static const __u8 ov6650_sensor_init[][8] = { |
345 | /* Bright, contrast, etc are set through SCBB interface. | 342 | /* Bright, contrast, etc are set through SCBB interface. |
@@ -378,24 +375,13 @@ static const __u8 initOv7630[] = { | |||
378 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | 375 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ |
379 | 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ | 376 | 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ |
380 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | 377 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ |
381 | 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ | ||
382 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | ||
383 | }; | ||
384 | static const __u8 initOv7630_3[] = { | ||
385 | 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ | ||
386 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | ||
387 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | ||
388 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | ||
389 | 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ | 378 | 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ |
390 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ | ||
391 | 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ | ||
392 | 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ | ||
393 | }; | 379 | }; |
394 | static const __u8 ov7630_sensor_init[][8] = { | 380 | static const __u8 ov7630_sensor_init[][8] = { |
395 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | 381 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, |
396 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, | 382 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, |
397 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ | 383 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ |
398 | {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ | 384 | {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ |
399 | {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, | 385 | {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, |
400 | {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, | 386 | {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, |
401 | {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, | 387 | {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, |
@@ -413,16 +399,11 @@ static const __u8 ov7630_sensor_init[][8] = { | |||
413 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, | 399 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, |
414 | }; | 400 | }; |
415 | 401 | ||
416 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
417 | {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
418 | }; | ||
419 | |||
420 | static const __u8 initPas106[] = { | 402 | static const __u8 initPas106[] = { |
421 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | 403 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, |
422 | 0x00, 0x00, | 404 | 0x00, 0x00, |
423 | 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, | 405 | 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, |
424 | 0x16, 0x12, 0x24, COMP1, MCK_INIT1, | 406 | 0x16, 0x12, 0x24, COMP1, MCK_INIT1, |
425 | 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 | ||
426 | }; | 407 | }; |
427 | /* compression 0x86 mckinit1 0x2b */ | 408 | /* compression 0x86 mckinit1 0x2b */ |
428 | 409 | ||
@@ -496,7 +477,6 @@ static const __u8 initPas202[] = { | |||
496 | 0x00, 0x00, | 477 | 0x00, 0x00, |
497 | 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, | 478 | 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, |
498 | 0x28, 0x1e, 0x20, 0x89, 0x20, | 479 | 0x28, 0x1e, 0x20, 0x89, 0x20, |
499 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c | ||
500 | }; | 480 | }; |
501 | 481 | ||
502 | /* "Known" PAS202BCB registers: | 482 | /* "Known" PAS202BCB registers: |
@@ -537,7 +517,6 @@ static const __u8 initTas5110c[] = { | |||
537 | 0x00, 0x00, | 517 | 0x00, 0x00, |
538 | 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a, | 518 | 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a, |
539 | 0x16, 0x12, 0x60, 0x86, 0x2b, | 519 | 0x16, 0x12, 0x60, 0x86, 0x2b, |
540 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 | ||
541 | }; | 520 | }; |
542 | /* Same as above, except a different hstart */ | 521 | /* Same as above, except a different hstart */ |
543 | static const __u8 initTas5110d[] = { | 522 | static const __u8 initTas5110d[] = { |
@@ -545,12 +524,19 @@ static const __u8 initTas5110d[] = { | |||
545 | 0x00, 0x00, | 524 | 0x00, 0x00, |
546 | 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a, | 525 | 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a, |
547 | 0x16, 0x12, 0x60, 0x86, 0x2b, | 526 | 0x16, 0x12, 0x60, 0x86, 0x2b, |
548 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 | ||
549 | }; | 527 | }; |
550 | static const __u8 tas5110_sensor_init[][8] = { | 528 | /* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */ |
529 | static const __u8 tas5110c_sensor_init[][8] = { | ||
551 | {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, | 530 | {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, |
552 | {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, | 531 | {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, |
553 | {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, | 532 | }; |
533 | /* Known TAS5110D registers | ||
534 | * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain | ||
535 | * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted) | ||
536 | * Note: writing reg03 seems to only work when written together with 02 | ||
537 | */ | ||
538 | static const __u8 tas5110d_sensor_init[][8] = { | ||
539 | {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */ | ||
554 | }; | 540 | }; |
555 | 541 | ||
556 | static const __u8 initTas5130[] = { | 542 | static const __u8 initTas5130[] = { |
@@ -558,7 +544,6 @@ static const __u8 initTas5130[] = { | |||
558 | 0x00, 0x00, | 544 | 0x00, 0x00, |
559 | 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a, | 545 | 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a, |
560 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, | 546 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, |
561 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | ||
562 | }; | 547 | }; |
563 | static const __u8 tas5130_sensor_init[][8] = { | 548 | static const __u8 tas5130_sensor_init[][8] = { |
564 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, | 549 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, |
@@ -569,21 +554,18 @@ static const __u8 tas5130_sensor_init[][8] = { | |||
569 | }; | 554 | }; |
570 | 555 | ||
571 | static struct sensor_data sensor_data[] = { | 556 | static struct sensor_data sensor_data[] = { |
572 | SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), | 557 | SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), |
573 | SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), | 558 | SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), |
574 | SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), | 559 | SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), |
575 | SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, | 560 | SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21), |
576 | F_GAIN, 0, 0x21), | 561 | SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0), |
577 | SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ, | 562 | SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0), |
578 | 0), | 563 | SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, |
579 | SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN, | 564 | NO_BRIGHTNESS|NO_FREQ, 0), |
580 | NO_FREQ, 0), | 565 | SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, |
581 | SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL, | 566 | NO_BRIGHTNESS|NO_FREQ, 0), |
582 | F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0), | 567 | SENS(initTas5130, tas5130_sensor_init, F_GAIN, |
583 | SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL, | 568 | NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), |
584 | F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0), | ||
585 | SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, | ||
586 | 0), | ||
587 | }; | 569 | }; |
588 | 570 | ||
589 | /* get one byte in gspca_dev->usb_buf */ | 571 | /* get one byte in gspca_dev->usb_buf */ |
@@ -655,7 +637,6 @@ static void i2c_w_vector(struct gspca_dev *gspca_dev, | |||
655 | static void setbrightness(struct gspca_dev *gspca_dev) | 637 | static void setbrightness(struct gspca_dev *gspca_dev) |
656 | { | 638 | { |
657 | struct sd *sd = (struct sd *) gspca_dev; | 639 | struct sd *sd = (struct sd *) gspca_dev; |
658 | __u8 value; | ||
659 | 640 | ||
660 | switch (sd->sensor) { | 641 | switch (sd->sensor) { |
661 | case SENSOR_OV6650: | 642 | case SENSOR_OV6650: |
@@ -697,17 +678,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
697 | goto err; | 678 | goto err; |
698 | break; | 679 | break; |
699 | } | 680 | } |
700 | case SENSOR_TAS5130CXX: { | ||
701 | __u8 i2c[] = | ||
702 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | ||
703 | |||
704 | value = 0xff - sd->brightness; | ||
705 | i2c[4] = value; | ||
706 | PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); | ||
707 | if (i2c_w(gspca_dev, i2c) < 0) | ||
708 | goto err; | ||
709 | break; | ||
710 | } | ||
711 | } | 681 | } |
712 | return; | 682 | return; |
713 | err: | 683 | err: |
@@ -733,7 +703,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
733 | break; | 703 | break; |
734 | } | 704 | } |
735 | case SENSOR_TAS5110C: | 705 | case SENSOR_TAS5110C: |
736 | case SENSOR_TAS5110D: { | 706 | case SENSOR_TAS5130CXX: { |
737 | __u8 i2c[] = | 707 | __u8 i2c[] = |
738 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | 708 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; |
739 | 709 | ||
@@ -742,6 +712,23 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
742 | goto err; | 712 | goto err; |
743 | break; | 713 | break; |
744 | } | 714 | } |
715 | case SENSOR_TAS5110D: { | ||
716 | __u8 i2c[] = { | ||
717 | 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 }; | ||
718 | gain = 255 - gain; | ||
719 | /* The bits in the register are the wrong way around!! */ | ||
720 | i2c[3] |= (gain & 0x80) >> 7; | ||
721 | i2c[3] |= (gain & 0x40) >> 5; | ||
722 | i2c[3] |= (gain & 0x20) >> 3; | ||
723 | i2c[3] |= (gain & 0x10) >> 1; | ||
724 | i2c[3] |= (gain & 0x08) << 1; | ||
725 | i2c[3] |= (gain & 0x04) << 3; | ||
726 | i2c[3] |= (gain & 0x02) << 5; | ||
727 | i2c[3] |= (gain & 0x01) << 7; | ||
728 | if (i2c_w(gspca_dev, i2c) < 0) | ||
729 | goto err; | ||
730 | break; | ||
731 | } | ||
745 | 732 | ||
746 | case SENSOR_OV6650: | 733 | case SENSOR_OV6650: |
747 | gain >>= 1; | 734 | gain >>= 1; |
@@ -796,7 +783,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
796 | { | 783 | { |
797 | struct sd *sd = (struct sd *) gspca_dev; | 784 | struct sd *sd = (struct sd *) gspca_dev; |
798 | __u8 gain; | 785 | __u8 gain; |
799 | __u8 buf[2] = { 0, 0 }; | 786 | __u8 buf[3] = { 0, 0, 0 }; |
800 | 787 | ||
801 | if (sensor_data[sd->sensor].flags & F_GAIN) { | 788 | if (sensor_data[sd->sensor].flags & F_GAIN) { |
802 | /* Use the sensor gain to do the actual gain */ | 789 | /* Use the sensor gain to do the actual gain */ |
@@ -804,13 +791,18 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
804 | return; | 791 | return; |
805 | } | 792 | } |
806 | 793 | ||
807 | gain = sd->gain >> 4; | 794 | if (sd->bridge == BRIDGE_103) { |
808 | 795 | gain = sd->gain >> 1; | |
809 | /* red and blue gain */ | 796 | buf[0] = gain; /* Red */ |
810 | buf[0] = gain << 4 | gain; | 797 | buf[1] = gain; /* Green */ |
811 | /* green gain */ | 798 | buf[2] = gain; /* Blue */ |
812 | buf[1] = gain; | 799 | reg_w(gspca_dev, 0x05, buf, 3); |
813 | reg_w(gspca_dev, 0x10, buf, 2); | 800 | } else { |
801 | gain = sd->gain >> 4; | ||
802 | buf[0] = gain << 4 | gain; /* Red and blue */ | ||
803 | buf[1] = gain; /* Green */ | ||
804 | reg_w(gspca_dev, 0x10, buf, 2); | ||
805 | } | ||
814 | } | 806 | } |
815 | 807 | ||
816 | static void setexposure(struct gspca_dev *gspca_dev) | 808 | static void setexposure(struct gspca_dev *gspca_dev) |
@@ -1049,7 +1041,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1049 | desired_avg_lum = 5000; | 1041 | desired_avg_lum = 5000; |
1050 | } else { | 1042 | } else { |
1051 | deadzone = 1500; | 1043 | deadzone = 1500; |
1052 | desired_avg_lum = 18000; | 1044 | desired_avg_lum = 13000; |
1053 | } | 1045 | } |
1054 | 1046 | ||
1055 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) | 1047 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) |
@@ -1127,53 +1119,91 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1127 | { | 1119 | { |
1128 | struct sd *sd = (struct sd *) gspca_dev; | 1120 | struct sd *sd = (struct sd *) gspca_dev; |
1129 | struct cam *cam = &gspca_dev->cam; | 1121 | struct cam *cam = &gspca_dev->cam; |
1130 | int mode, l; | 1122 | int i, mode; |
1131 | const __u8 *sn9c10x; | 1123 | __u8 regs[0x31]; |
1132 | __u8 reg12_19[8]; | ||
1133 | 1124 | ||
1134 | mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; | 1125 | mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; |
1135 | sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; | 1126 | /* Copy registers 0x01 - 0x19 from the template */ |
1136 | l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; | 1127 | memcpy(®s[0x01], sensor_data[sd->sensor].bridge_init, 0x19); |
1137 | memcpy(reg12_19, &sn9c10x[0x12 - 1], 8); | 1128 | /* Set the mode */ |
1138 | reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); | 1129 | regs[0x18] |= mode << 4; |
1139 | /* Special cases where reg 17 and or 19 value depends on mode */ | 1130 | |
1131 | /* Set bridge gain to 1.0 */ | ||
1132 | if (sd->bridge == BRIDGE_103) { | ||
1133 | regs[0x05] = 0x20; /* Red */ | ||
1134 | regs[0x06] = 0x20; /* Green */ | ||
1135 | regs[0x07] = 0x20; /* Blue */ | ||
1136 | } else { | ||
1137 | regs[0x10] = 0x00; /* Red and blue */ | ||
1138 | regs[0x11] = 0x00; /* Green */ | ||
1139 | } | ||
1140 | |||
1141 | /* Setup pixel numbers and auto exposure window */ | ||
1142 | if (sensor_data[sd->sensor].flags & F_SIF) { | ||
1143 | regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */ | ||
1144 | regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */ | ||
1145 | regs[0x1c] = 0x02; /* AE H-start 64 */ | ||
1146 | regs[0x1d] = 0x02; /* AE V-start 64 */ | ||
1147 | regs[0x1e] = 0x09; /* AE H-end 288 */ | ||
1148 | regs[0x1f] = 0x07; /* AE V-end 224 */ | ||
1149 | } else { | ||
1150 | regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */ | ||
1151 | regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */ | ||
1152 | regs[0x1c] = 0x05; /* AE H-start 160 */ | ||
1153 | regs[0x1d] = 0x03; /* AE V-start 96 */ | ||
1154 | regs[0x1e] = 0x0f; /* AE H-end 480 */ | ||
1155 | regs[0x1f] = 0x0c; /* AE V-end 384 */ | ||
1156 | } | ||
1157 | |||
1158 | /* Setup the gamma table (only used with the sn9c103 bridge) */ | ||
1159 | for (i = 0; i < 16; i++) | ||
1160 | regs[0x20 + i] = i * 16; | ||
1161 | regs[0x20 + i] = 255; | ||
1162 | |||
1163 | /* Special cases where some regs depend on mode or bridge */ | ||
1140 | switch (sd->sensor) { | 1164 | switch (sd->sensor) { |
1141 | case SENSOR_TAS5130CXX: | 1165 | case SENSOR_TAS5130CXX: |
1142 | /* probably not mode specific at all most likely the upper | 1166 | /* FIXME / TESTME |
1167 | probably not mode specific at all most likely the upper | ||
1143 | nibble of 0x19 is exposure (clock divider) just as with | 1168 | nibble of 0x19 is exposure (clock divider) just as with |
1144 | the tas5110, we need someone to test this. */ | 1169 | the tas5110, we need someone to test this. */ |
1145 | reg12_19[7] = mode ? 0x23 : 0x43; | 1170 | regs[0x19] = mode ? 0x23 : 0x43; |
1146 | break; | 1171 | break; |
1172 | case SENSOR_OV7630: | ||
1173 | /* FIXME / TESTME for some reason with the 101/102 bridge the | ||
1174 | clock is set to 12 Mhz (reg1 == 0x04), rather then 24. | ||
1175 | Also the hstart needs to go from 1 to 2 when using a 103, | ||
1176 | which is likely related. This does not seem right. */ | ||
1177 | if (sd->bridge == BRIDGE_103) { | ||
1178 | regs[0x01] = 0x44; /* Select 24 Mhz clock */ | ||
1179 | regs[0x12] = 0x02; /* Set hstart to 2 */ | ||
1180 | } | ||
1147 | } | 1181 | } |
1148 | /* Disable compression when the raw bayer format has been selected */ | 1182 | /* Disable compression when the raw bayer format has been selected */ |
1149 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) | 1183 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) |
1150 | reg12_19[6] &= ~0x80; | 1184 | regs[0x18] &= ~0x80; |
1151 | 1185 | ||
1152 | /* Vga mode emulation on SIF sensor? */ | 1186 | /* Vga mode emulation on SIF sensor? */ |
1153 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { | 1187 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { |
1154 | reg12_19[0] += 16; /* 0x12: hstart adjust */ | 1188 | regs[0x12] += 16; /* hstart adjust */ |
1155 | reg12_19[1] += 24; /* 0x13: vstart adjust */ | 1189 | regs[0x13] += 24; /* vstart adjust */ |
1156 | reg12_19[3] = 320 / 16; /* 0x15: hsize */ | 1190 | regs[0x15] = 320 / 16; /* hsize */ |
1157 | reg12_19[4] = 240 / 16; /* 0x16: vsize */ | 1191 | regs[0x16] = 240 / 16; /* vsize */ |
1158 | } | 1192 | } |
1159 | 1193 | ||
1160 | /* reg 0x01 bit 2 video transfert on */ | 1194 | /* reg 0x01 bit 2 video transfert on */ |
1161 | reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); | 1195 | reg_w(gspca_dev, 0x01, ®s[0x01], 1); |
1162 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ | 1196 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ |
1163 | reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); | 1197 | reg_w(gspca_dev, 0x17, ®s[0x17], 1); |
1164 | /* Set the registers from the template */ | 1198 | /* Set the registers from the template */ |
1165 | reg_w(gspca_dev, 0x01, sn9c10x, l); | 1199 | reg_w(gspca_dev, 0x01, ®s[0x01], |
1200 | (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f); | ||
1166 | 1201 | ||
1167 | /* Init the sensor */ | 1202 | /* Init the sensor */ |
1168 | i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, | 1203 | i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, |
1169 | sensor_data[sd->sensor].sensor_init_size); | 1204 | sensor_data[sd->sensor].sensor_init_size); |
1170 | if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge]) | ||
1171 | i2c_w_vector(gspca_dev, | ||
1172 | sensor_data[sd->sensor].sensor_bridge_init[sd->bridge], | ||
1173 | sensor_data[sd->sensor].sensor_bridge_init_size[ | ||
1174 | sd->bridge]); | ||
1175 | 1205 | ||
1176 | /* Mode specific sensor setup */ | 1206 | /* Mode / bridge specific sensor setup */ |
1177 | switch (sd->sensor) { | 1207 | switch (sd->sensor) { |
1178 | case SENSOR_PAS202: { | 1208 | case SENSOR_PAS202: { |
1179 | const __u8 i2cpclockdiv[] = | 1209 | const __u8 i2cpclockdiv[] = |
@@ -1181,27 +1211,37 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1181 | /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */ | 1211 | /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */ |
1182 | if (mode) | 1212 | if (mode) |
1183 | i2c_w(gspca_dev, i2cpclockdiv); | 1213 | i2c_w(gspca_dev, i2cpclockdiv); |
1214 | break; | ||
1184 | } | 1215 | } |
1216 | case SENSOR_OV7630: | ||
1217 | /* FIXME / TESTME We should be able to handle this identical | ||
1218 | for the 101/102 and the 103 case */ | ||
1219 | if (sd->bridge == BRIDGE_103) { | ||
1220 | const __u8 i2c[] = { 0xa0, 0x21, 0x13, | ||
1221 | 0x80, 0x00, 0x00, 0x00, 0x10 }; | ||
1222 | i2c_w(gspca_dev, i2c); | ||
1223 | } | ||
1224 | break; | ||
1185 | } | 1225 | } |
1186 | /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ | 1226 | /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ |
1187 | reg_w(gspca_dev, 0x15, ®12_19[3], 2); | 1227 | reg_w(gspca_dev, 0x15, ®s[0x15], 2); |
1188 | /* compression register */ | 1228 | /* compression register */ |
1189 | reg_w(gspca_dev, 0x18, ®12_19[6], 1); | 1229 | reg_w(gspca_dev, 0x18, ®s[0x18], 1); |
1190 | /* H_start */ | 1230 | /* H_start */ |
1191 | reg_w(gspca_dev, 0x12, ®12_19[0], 1); | 1231 | reg_w(gspca_dev, 0x12, ®s[0x12], 1); |
1192 | /* V_START */ | 1232 | /* V_START */ |
1193 | reg_w(gspca_dev, 0x13, ®12_19[1], 1); | 1233 | reg_w(gspca_dev, 0x13, ®s[0x13], 1); |
1194 | /* reset 0x17 SensorClk enable inv Clk 0x60 */ | 1234 | /* reset 0x17 SensorClk enable inv Clk 0x60 */ |
1195 | /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ | 1235 | /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ |
1196 | reg_w(gspca_dev, 0x17, ®12_19[5], 1); | 1236 | reg_w(gspca_dev, 0x17, ®s[0x17], 1); |
1197 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ | 1237 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ |
1198 | reg_w(gspca_dev, 0x19, ®12_19[7], 1); | 1238 | reg_w(gspca_dev, 0x19, ®s[0x19], 1); |
1199 | /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ | 1239 | /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ |
1200 | reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); | 1240 | reg_w(gspca_dev, 0x1c, ®s[0x1c], 4); |
1201 | /* Enable video transfert */ | 1241 | /* Enable video transfert */ |
1202 | reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); | 1242 | reg_w(gspca_dev, 0x01, ®s[0x01], 1); |
1203 | /* Compression */ | 1243 | /* Compression */ |
1204 | reg_w(gspca_dev, 0x18, ®12_19[6], 2); | 1244 | reg_w(gspca_dev, 0x18, ®s[0x18], 2); |
1205 | msleep(20); | 1245 | msleep(20); |
1206 | 1246 | ||
1207 | sd->reg11 = -1; | 1247 | sd->reg11 = -1; |
@@ -1525,15 +1565,15 @@ static const struct sd_desc sd_desc = { | |||
1525 | .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge | 1565 | .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge |
1526 | 1566 | ||
1527 | 1567 | ||
1528 | static const struct usb_device_id device_table[] __devinitconst = { | 1568 | static const struct usb_device_id device_table[] = { |
1529 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ | 1569 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ |
1530 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ | 1570 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ |
1531 | {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ | 1571 | {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ |
1532 | {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, | 1572 | {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, |
1533 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, | 1573 | {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, |
1534 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, | 1574 | {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, |
1535 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | ||
1536 | {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, | 1575 | {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, |
1576 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | ||
1537 | {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, | 1577 | {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, |
1538 | {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, | 1578 | {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, |
1539 | #endif | 1579 | #endif |
@@ -1544,18 +1584,22 @@ static const struct usb_device_id device_table[] __devinitconst = { | |||
1544 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, | 1584 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, |
1545 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, | 1585 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, |
1546 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, | 1586 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, |
1547 | /* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ | 1587 | /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ |
1588 | /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */ | ||
1589 | {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)}, | ||
1590 | {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)}, | ||
1591 | /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */ | ||
1548 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, | 1592 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, |
1549 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1593 | {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)}, |
1594 | {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)}, | ||
1550 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, | 1595 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, |
1551 | #endif | ||
1552 | {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, | 1596 | {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, |
1553 | {} | 1597 | {} |
1554 | }; | 1598 | }; |
1555 | MODULE_DEVICE_TABLE(usb, device_table); | 1599 | MODULE_DEVICE_TABLE(usb, device_table); |
1556 | 1600 | ||
1557 | /* -- device connect -- */ | 1601 | /* -- device connect -- */ |
1558 | static int __devinit sd_probe(struct usb_interface *intf, | 1602 | static int sd_probe(struct usb_interface *intf, |
1559 | const struct usb_device_id *id) | 1603 | const struct usb_device_id *id) |
1560 | { | 1604 | { |
1561 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 1605 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |