aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sonixb.c')
-rw-r--r--drivers/media/video/gspca/sonixb.c451
1 files changed, 330 insertions, 121 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index ddff2b5ee5c2..785eeb4c2014 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -42,6 +42,7 @@ Reg Use
42 42
43#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
44 44
45#include <linux/input.h>
45#include "gspca.h" 46#include "gspca.h"
46 47
47MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 48MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -53,9 +54,11 @@ struct sd {
53 struct gspca_dev gspca_dev; /* !! must be the first item */ 54 struct gspca_dev gspca_dev; /* !! must be the first item */
54 atomic_t avg_lum; 55 atomic_t avg_lum;
55 int prev_avg_lum; 56 int prev_avg_lum;
57 int exp_too_low_cnt;
58 int exp_too_high_cnt;
56 59
60 unsigned short exposure;
57 unsigned char gain; 61 unsigned char gain;
58 unsigned char exposure;
59 unsigned char brightness; 62 unsigned char brightness;
60 unsigned char autogain; 63 unsigned char autogain;
61 unsigned char autogain_ignore_frames; 64 unsigned char autogain_ignore_frames;
@@ -73,8 +76,9 @@ struct sd {
73#define SENSOR_OV7630 2 76#define SENSOR_OV7630 2
74#define SENSOR_PAS106 3 77#define SENSOR_PAS106 3
75#define SENSOR_PAS202 4 78#define SENSOR_PAS202 4
76#define SENSOR_TAS5110 5 79#define SENSOR_TAS5110C 5
77#define SENSOR_TAS5130CXX 6 80#define SENSOR_TAS5110D 6
81#define SENSOR_TAS5130CXX 7
78 __u8 reg11; 82 __u8 reg11;
79}; 83};
80 84
@@ -95,13 +99,15 @@ struct sensor_data {
95/* sensor_data flags */ 99/* sensor_data flags */
96#define F_GAIN 0x01 /* has gain */ 100#define F_GAIN 0x01 /* has gain */
97#define F_SIF 0x02 /* sif or vga */ 101#define F_SIF 0x02 /* sif or vga */
102#define F_COARSE_EXPO 0x04 /* exposure control is coarse */
98 103
99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ 104/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100#define MODE_RAW 0x10 /* raw bayer mode */ 105#define MODE_RAW 0x10 /* raw bayer mode */
101#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 106#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
102 107
103/* ctrl_dis helper macros */ 108/* ctrl_dis helper macros */
104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) 109#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
110 (1 << AUTOGAIN_IDX))
105#define NO_FREQ (1 << FREQ_IDX) 111#define NO_FREQ (1 << FREQ_IDX)
106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) 112#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
107 113
@@ -127,11 +133,10 @@ struct sensor_data {
127} 133}
128 134
129/* We calculate the autogain at the end of the transfer of a frame, at this 135/* We calculate the autogain at the end of the transfer of a frame, at this
130 moment a frame with the old settings is being transmitted, and a frame is 136 moment a frame with the old settings is being captured and transmitted. So
131 being captured with the old settings. So if we adjust the autogain we must 137 if we adjust the gain or exposure we must ignore atleast the next frame for
132 ignore atleast the 2 next frames for the new settings to come into effect 138 the new settings to come into effect before doing any other adjustments. */
133 before doing any other adjustments */ 139#define AUTOGAIN_IGNORE_FRAMES 1
134#define AUTOGAIN_IGNORE_FRAMES 3
135 140
136/* V4L2 controls supported by the driver */ 141/* V4L2 controls supported by the driver */
137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 142static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -145,7 +150,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
145static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 150static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
146static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 151static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
147 152
148static struct ctrl sd_ctrls[] = { 153static const struct ctrl sd_ctrls[] = {
149#define BRIGHTNESS_IDX 0 154#define BRIGHTNESS_IDX 0
150 { 155 {
151 { 156 {
@@ -171,7 +176,7 @@ static struct ctrl sd_ctrls[] = {
171 .maximum = 255, 176 .maximum = 255,
172 .step = 1, 177 .step = 1,
173#define GAIN_DEF 127 178#define GAIN_DEF 127
174#define GAIN_KNEE 200 179#define GAIN_KNEE 230
175 .default_value = GAIN_DEF, 180 .default_value = GAIN_DEF,
176 }, 181 },
177 .set = sd_setgain, 182 .set = sd_setgain,
@@ -183,10 +188,10 @@ static struct ctrl sd_ctrls[] = {
183 .id = V4L2_CID_EXPOSURE, 188 .id = V4L2_CID_EXPOSURE,
184 .type = V4L2_CTRL_TYPE_INTEGER, 189 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "Exposure", 190 .name = "Exposure",
186#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 191#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
187#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 192#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
188 .minimum = 0, 193 .minimum = 0,
189 .maximum = 255, 194 .maximum = 1023,
190 .step = 1, 195 .step = 1,
191 .default_value = EXPOSURE_DEF, 196 .default_value = EXPOSURE_DEF,
192 .flags = 0, 197 .flags = 0,
@@ -194,7 +199,23 @@ static struct ctrl sd_ctrls[] = {
194 .set = sd_setexposure, 199 .set = sd_setexposure,
195 .get = sd_getexposure, 200 .get = sd_getexposure,
196 }, 201 },
197#define AUTOGAIN_IDX 3 202#define COARSE_EXPOSURE_IDX 3
203 {
204 {
205 .id = V4L2_CID_EXPOSURE,
206 .type = V4L2_CTRL_TYPE_INTEGER,
207 .name = "Exposure",
208#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
209 .minimum = 2,
210 .maximum = 15,
211 .step = 1,
212 .default_value = COARSE_EXPOSURE_DEF,
213 .flags = 0,
214 },
215 .set = sd_setexposure,
216 .get = sd_getexposure,
217 },
218#define AUTOGAIN_IDX 4
198 { 219 {
199 { 220 {
200 .id = V4L2_CID_AUTOGAIN, 221 .id = V4L2_CID_AUTOGAIN,
@@ -210,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
210 .set = sd_setautogain, 231 .set = sd_setautogain,
211 .get = sd_getautogain, 232 .get = sd_getautogain,
212 }, 233 },
213#define FREQ_IDX 4 234#define FREQ_IDX 5
214 { 235 {
215 { 236 {
216 .id = V4L2_CID_POWER_LINE_FREQUENCY, 237 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -219,7 +240,7 @@ static struct ctrl sd_ctrls[] = {
219 .minimum = 0, 240 .minimum = 0,
220 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 241 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
221 .step = 1, 242 .step = 1,
222#define FREQ_DEF 1 243#define FREQ_DEF 0
223 .default_value = FREQ_DEF, 244 .default_value = FREQ_DEF,
224 }, 245 },
225 .set = sd_setfreq, 246 .set = sd_setfreq,
@@ -345,7 +366,7 @@ static const __u8 initOv7630[] = {
345}; 366};
346static const __u8 initOv7630_3[] = { 367static const __u8 initOv7630_3[] = {
347 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 368 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
348 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 369 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
349 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 370 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
350 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 371 0x28, 0x1e, /* H & V sizes r15 .. r16 */
351 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 372 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
@@ -387,6 +408,30 @@ static const __u8 initPas106[] = {
387 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 408 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
388}; 409};
389/* compression 0x86 mckinit1 0x2b */ 410/* compression 0x86 mckinit1 0x2b */
411
412/* "Known" PAS106B registers:
413 0x02 clock divider
414 0x03 Variable framerate bits 4-11
415 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
416 The variable framerate control must never be set lower then 300,
417 which sets the framerate at 90 / reg02, otherwise vsync is lost.
418 0x05 Shutter Time Line Offset, this can be used as an exposure control:
419 0 = use full frame time, 255 = no exposure at all
420 Note this may never be larger then "var-framerate control" / 2 - 2.
421 When var-framerate control is < 514, no exposure is reached at the max
422 allowed value for the framerate control value, rather then at 255.
423 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
424 only a very little bit, leave at 0xcd
425 0x07 offset sign bit (bit0 1 > negative offset)
426 0x08 offset
427 0x09 Blue Gain
428 0x0a Green1 Gain
429 0x0b Green2 Gain
430 0x0c Red Gain
431 0x0e Global gain
432 0x13 Write 1 to commit settings to sensor
433*/
434
390static const __u8 pas106_sensor_init[][8] = { 435static const __u8 pas106_sensor_init[][8] = {
391 /* Pixel Clock Divider 6 */ 436 /* Pixel Clock Divider 6 */
392 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, 437 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
@@ -433,37 +478,55 @@ static const __u8 initPas202[] = {
433 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 478 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
434 0x00, 0x00, 479 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 480 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
436 0x28, 0x1e, 0x28, 0x89, 0x20, 481 0x28, 0x1e, 0x20, 0x89, 0x20,
437 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c 482 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
438}; 483};
484
485/* "Known" PAS202BCB registers:
486 0x02 clock divider
487 0x04 Variable framerate bits 6-11 (*)
488 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
489 0x07 Blue Gain
490 0x08 Green Gain
491 0x09 Red Gain
492 0x0b offset sign bit (bit0 1 > negative offset)
493 0x0c offset
494 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
495 leave at 1 otherwise we get a jump in our exposure control
496 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
497 0x10 Master gain 0 - 31
498 0x11 write 1 to apply changes
499 (*) The variable framerate control must never be set lower then 500
500 which sets the framerate at 30 / reg02, otherwise vsync is lost.
501*/
439static const __u8 pas202_sensor_init[][8] = { 502static const __u8 pas202_sensor_init[][8] = {
440 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, 503 /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
504 to set it lower, but for some reason the bridge starts missing
505 vsync's then */
506 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
441 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, 507 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
442 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, 508 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
443 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, 509 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
444 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, 510 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
445 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, 511 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
446 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, 512 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
447 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 513 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
448 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, 514 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
449 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 515 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
450 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
451 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
452
453 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
454 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
455 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
456 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
457 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
458 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
459 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
460 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
461}; 516};
462 517
463static const __u8 initTas5110[] = { 518static const __u8 initTas5110c[] = {
464 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 519 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
465 0x00, 0x00, 520 0x00, 0x00,
466 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a, 521 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
522 0x16, 0x12, 0x60, 0x86, 0x2b,
523 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
524};
525/* Same as above, except a different hstart */
526static const __u8 initTas5110d[] = {
527 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
528 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
467 0x16, 0x12, 0x60, 0x86, 0x2b, 530 0x16, 0x12, 0x60, 0x86, 0x2b,
468 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 531 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
469}; 532};
@@ -476,7 +539,7 @@ static const __u8 tas5110_sensor_init[][8] = {
476static const __u8 initTas5130[] = { 539static const __u8 initTas5130[] = {
477 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 540 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
478 0x00, 0x00, 541 0x00, 0x00,
479 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a, 542 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
480 0x28, 0x1e, 0x60, COMP, MCK_INIT, 543 0x28, 0x1e, 0x60, COMP, MCK_INIT,
481 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 544 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
482}; 545};
@@ -493,12 +556,14 @@ SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
493SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), 556SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
494SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 557SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
495 F_GAIN, 0, 0x21), 558 F_GAIN, 0, 0x21),
496SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 559SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
497 0), 560 0),
498SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, 561SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
499 NO_EXPO|NO_FREQ, 0), 562 NO_FREQ, 0),
500SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, 563SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
501 NO_BRIGHTNESS|NO_FREQ, 0), 564 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
565SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
566 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
502SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 567SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
503 0), 568 0),
504}; 569};
@@ -587,42 +652,28 @@ static void setbrightness(struct gspca_dev *gspca_dev)
587 goto err; 652 goto err;
588 break; 653 break;
589 } 654 }
590 case SENSOR_PAS106: { 655 case SENSOR_PAS106:
591 __u8 i2c1[] =
592 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
593
594 i2c1[3] = sd->brightness >> 3;
595 i2c1[2] = 0x0e;
596 if (i2c_w(gspca_dev, i2c1) < 0)
597 goto err;
598 i2c1[3] = 0x01;
599 i2c1[2] = 0x13;
600 if (i2c_w(gspca_dev, i2c1) < 0)
601 goto err;
602 break;
603 }
604 case SENSOR_PAS202: { 656 case SENSOR_PAS202: {
605 /* __u8 i2cpexpo1[] = 657 __u8 i2cpbright[] =
606 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ 658 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
607 __u8 i2cpexpo[] = 659 __u8 i2cpdoit[] =
608 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; 660 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
609 __u8 i2cp202[] = 661
610 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; 662 /* PAS106 uses reg 7 and 8 instead of b and c */
611 static __u8 i2cpdoit[] = 663 if (sd->sensor == SENSOR_PAS106) {
612 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; 664 i2cpbright[2] = 7;
613 665 i2cpdoit[2] = 0x13;
614 /* change reg 0x10 */ 666 }
615 i2cpexpo[4] = 0xff - sd->brightness; 667
616/* if(i2c_w(gspca_dev,i2cpexpo1) < 0) 668 if (sd->brightness < 127) {
617 goto err; */ 669 /* change reg 0x0b, signreg */
618/* if(i2c_w(gspca_dev,i2cpdoit) < 0) 670 i2cpbright[3] = 0x01;
619 goto err; */ 671 /* set reg 0x0c, offset */
620 if (i2c_w(gspca_dev, i2cpexpo) < 0) 672 i2cpbright[4] = 127 - sd->brightness;
621 goto err; 673 } else
622 if (i2c_w(gspca_dev, i2cpdoit) < 0) 674 i2cpbright[4] = sd->brightness - 127;
623 goto err; 675
624 i2cp202[3] = sd->brightness >> 3; 676 if (i2c_w(gspca_dev, i2cpbright) < 0)
625 if (i2c_w(gspca_dev, i2cp202) < 0)
626 goto err; 677 goto err;
627 if (i2c_w(gspca_dev, i2cpdoit) < 0) 678 if (i2c_w(gspca_dev, i2cpdoit) < 0)
628 goto err; 679 goto err;
@@ -652,7 +703,8 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
652 703
653 switch (sd->sensor) { 704 switch (sd->sensor) {
654 705
655 case SENSOR_TAS5110: { 706 case SENSOR_TAS5110C:
707 case SENSOR_TAS5110D: {
656 __u8 i2c[] = 708 __u8 i2c[] =
657 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; 709 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
658 710
@@ -674,6 +726,37 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
674 goto err; 726 goto err;
675 break; 727 break;
676 } 728 }
729 case SENSOR_PAS106:
730 case SENSOR_PAS202: {
731 __u8 i2cpgain[] =
732 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
733 __u8 i2cpcolorgain[] =
734 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
735 __u8 i2cpdoit[] =
736 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
737
738 /* PAS106 uses different regs (and has split green gains) */
739 if (sd->sensor == SENSOR_PAS106) {
740 i2cpgain[2] = 0x0e;
741 i2cpcolorgain[0] = 0xd0;
742 i2cpcolorgain[2] = 0x09;
743 i2cpdoit[2] = 0x13;
744 }
745
746 i2cpgain[3] = sd->gain >> 3;
747 i2cpcolorgain[3] = sd->gain >> 4;
748 i2cpcolorgain[4] = sd->gain >> 4;
749 i2cpcolorgain[5] = sd->gain >> 4;
750 i2cpcolorgain[6] = sd->gain >> 4;
751
752 if (i2c_w(gspca_dev, i2cpgain) < 0)
753 goto err;
754 if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
755 goto err;
756 if (i2c_w(gspca_dev, i2cpdoit) < 0)
757 goto err;
758 break;
759 }
677 } 760 }
678 return; 761 return;
679err: 762err:
@@ -684,19 +767,21 @@ static void setgain(struct gspca_dev *gspca_dev)
684{ 767{
685 struct sd *sd = (struct sd *) gspca_dev; 768 struct sd *sd = (struct sd *) gspca_dev;
686 __u8 gain; 769 __u8 gain;
687 __u8 rgb_value; 770 __u8 buf[2] = { 0, 0 };
771
772 if (sensor_data[sd->sensor].flags & F_GAIN) {
773 /* Use the sensor gain to do the actual gain */
774 setsensorgain(gspca_dev);
775 return;
776 }
688 777
689 gain = sd->gain >> 4; 778 gain = sd->gain >> 4;
690 779
691 /* red and blue gain */ 780 /* red and blue gain */
692 rgb_value = gain << 4 | gain; 781 buf[0] = gain << 4 | gain;
693 reg_w(gspca_dev, 0x10, &rgb_value, 1);
694 /* green gain */ 782 /* green gain */
695 rgb_value = gain; 783 buf[1] = gain;
696 reg_w(gspca_dev, 0x11, &rgb_value, 1); 784 reg_w(gspca_dev, 0x10, buf, 2);
697
698 if (sensor_data[sd->sensor].flags & F_GAIN)
699 setsensorgain(gspca_dev);
700} 785}
701 786
702static void setexposure(struct gspca_dev *gspca_dev) 787static void setexposure(struct gspca_dev *gspca_dev)
@@ -704,17 +789,12 @@ static void setexposure(struct gspca_dev *gspca_dev)
704 struct sd *sd = (struct sd *) gspca_dev; 789 struct sd *sd = (struct sd *) gspca_dev;
705 790
706 switch (sd->sensor) { 791 switch (sd->sensor) {
707 case SENSOR_TAS5110: { 792 case SENSOR_TAS5110C:
708 __u8 reg; 793 case SENSOR_TAS5110D: {
709
710 /* register 19's high nibble contains the sn9c10x clock divider 794 /* register 19's high nibble contains the sn9c10x clock divider
711 The high nibble configures the no fps according to the 795 The high nibble configures the no fps according to the
712 formula: 60 / high_nibble. With a maximum of 30 fps */ 796 formula: 60 / high_nibble. With a maximum of 30 fps */
713 reg = 120 * sd->exposure / 1000; 797 __u8 reg = sd->exposure;
714 if (reg < 2)
715 reg = 2;
716 else if (reg > 15)
717 reg = 15;
718 reg = (reg << 4) | 0x0b; 798 reg = (reg << 4) | 0x0b;
719 reg_w(gspca_dev, 0x19, &reg, 1); 799 reg_w(gspca_dev, 0x19, &reg, 1);
720 break; 800 break;
@@ -750,20 +830,21 @@ static void setexposure(struct gspca_dev *gspca_dev)
750 } else 830 } else
751 reg10_max = 0x41; 831 reg10_max = 0x41;
752 832
753 reg11 = (60 * sd->exposure + 999) / 1000; 833 reg11 = (15 * sd->exposure + 999) / 1000;
754 if (reg11 < 1) 834 if (reg11 < 1)
755 reg11 = 1; 835 reg11 = 1;
756 else if (reg11 > 16) 836 else if (reg11 > 16)
757 reg11 = 16; 837 reg11 = 16;
758 838
759 /* In 640x480, if the reg11 has less than 3, the image is 839 /* In 640x480, if the reg11 has less than 4, the image is
760 unstable (not enough bandwidth). */ 840 unstable (the bridge goes into a higher compression mode
761 if (gspca_dev->width == 640 && reg11 < 3) 841 which we have not reverse engineered yet). */
762 reg11 = 3; 842 if (gspca_dev->width == 640 && reg11 < 4)
843 reg11 = 4;
763 844
764 /* frame exposure time in ms = 1000 * reg11 / 30 -> 845 /* frame exposure time in ms = 1000 * reg11 / 30 ->
765 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ 846 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
766 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); 847 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
767 848
768 /* Don't allow this to get below 10 when using autogain, the 849 /* Don't allow this to get below 10 when using autogain, the
769 steps become very large (relatively) when below 10 causing 850 steps become very large (relatively) when below 10 causing
@@ -786,10 +867,85 @@ static void setexposure(struct gspca_dev *gspca_dev)
786 if (i2c_w(gspca_dev, i2c) == 0) 867 if (i2c_w(gspca_dev, i2c) == 0)
787 sd->reg11 = reg11; 868 sd->reg11 = reg11;
788 else 869 else
789 PDEBUG(D_ERR, "i2c error exposure"); 870 goto err;
871 break;
872 }
873 case SENSOR_PAS202: {
874 __u8 i2cpframerate[] =
875 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
876 __u8 i2cpexpo[] =
877 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
878 const __u8 i2cpdoit[] =
879 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
880 int framerate_ctrl;
881
882 /* The exposure knee for the autogain algorithm is 200
883 (100 ms / 10 fps on other sensors), for values below this
884 use the control for setting the partial frame expose time,
885 above that use variable framerate. This way we run at max
886 framerate (640x480@7.5 fps, 320x240@10fps) until the knee
887 is reached. Using the variable framerate control above 200
888 is better then playing around with both clockdiv + partial
889 frame exposure times (like we are doing with the ov chips),
890 as that sometimes leads to jumps in the exposure control,
891 which are bad for auto exposure. */
892 if (sd->exposure < 200) {
893 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
894 framerate_ctrl = 500;
895 } else {
896 /* The PAS202's exposure control goes from 0 - 4095,
897 but anything below 500 causes vsync issues, so scale
898 our 200-1023 to 500-4095 */
899 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
900 500;
901 }
902
903 i2cpframerate[3] = framerate_ctrl >> 6;
904 i2cpframerate[4] = framerate_ctrl & 0x3f;
905 if (i2c_w(gspca_dev, i2cpframerate) < 0)
906 goto err;
907 if (i2c_w(gspca_dev, i2cpexpo) < 0)
908 goto err;
909 if (i2c_w(gspca_dev, i2cpdoit) < 0)
910 goto err;
911 break;
912 }
913 case SENSOR_PAS106: {
914 __u8 i2cpframerate[] =
915 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
916 __u8 i2cpexpo[] =
917 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
918 const __u8 i2cpdoit[] =
919 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
920 int framerate_ctrl;
921
922 /* For values below 150 use partial frame exposure, above
923 that use framerate ctrl */
924 if (sd->exposure < 150) {
925 i2cpexpo[3] = 150 - sd->exposure;
926 framerate_ctrl = 300;
927 } else {
928 /* The PAS106's exposure control goes from 0 - 4095,
929 but anything below 300 causes vsync issues, so scale
930 our 150-1023 to 300-4095 */
931 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
932 300;
933 }
934
935 i2cpframerate[3] = framerate_ctrl >> 4;
936 i2cpframerate[4] = framerate_ctrl & 0x0f;
937 if (i2c_w(gspca_dev, i2cpframerate) < 0)
938 goto err;
939 if (i2c_w(gspca_dev, i2cpexpo) < 0)
940 goto err;
941 if (i2c_w(gspca_dev, i2cpdoit) < 0)
942 goto err;
790 break; 943 break;
791 } 944 }
792 } 945 }
946 return;
947err:
948 PDEBUG(D_ERR, "i2c error exposure");
793} 949}
794 950
795static void setfreq(struct gspca_dev *gspca_dev) 951static void setfreq(struct gspca_dev *gspca_dev)
@@ -823,30 +979,43 @@ static void setfreq(struct gspca_dev *gspca_dev)
823 } 979 }
824} 980}
825 981
982#include "coarse_expo_autogain.h"
983
826static void do_autogain(struct gspca_dev *gspca_dev) 984static void do_autogain(struct gspca_dev *gspca_dev)
827{ 985{
828 int deadzone, desired_avg_lum; 986 int deadzone, desired_avg_lum, result;
829 struct sd *sd = (struct sd *) gspca_dev; 987 struct sd *sd = (struct sd *) gspca_dev;
830 int avg_lum = atomic_read(&sd->avg_lum); 988 int avg_lum = atomic_read(&sd->avg_lum);
831 989
832 if (avg_lum == -1) 990 if (avg_lum == -1 || !sd->autogain)
833 return; 991 return;
834 992
993 if (sd->autogain_ignore_frames > 0) {
994 sd->autogain_ignore_frames--;
995 return;
996 }
997
835 /* SIF / VGA sensors have a different autoexposure area and thus 998 /* SIF / VGA sensors have a different autoexposure area and thus
836 different avg_lum values for the same picture brightness */ 999 different avg_lum values for the same picture brightness */
837 if (sensor_data[sd->sensor].flags & F_SIF) { 1000 if (sensor_data[sd->sensor].flags & F_SIF) {
838 deadzone = 1000; 1001 deadzone = 500;
839 desired_avg_lum = 7000; 1002 /* SIF sensors tend to overexpose, so keep this small */
1003 desired_avg_lum = 5000;
840 } else { 1004 } else {
841 deadzone = 3000; 1005 deadzone = 1500;
842 desired_avg_lum = 23000; 1006 desired_avg_lum = 18000;
843 } 1007 }
844 1008
845 if (sd->autogain_ignore_frames > 0) 1009 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
846 sd->autogain_ignore_frames--; 1010 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
847 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1011 sd->brightness * desired_avg_lum / 127,
848 sd->brightness * desired_avg_lum / 127, 1012 deadzone);
849 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) { 1013 else
1014 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
1015 sd->brightness * desired_avg_lum / 127,
1016 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1017
1018 if (result) {
850 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1019 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
851 (int)sd->gain, (int)sd->exposure); 1020 (int)sd->gain, (int)sd->exposure);
852 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1021 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
@@ -881,7 +1050,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
881 1050
882 sd->brightness = BRIGHTNESS_DEF; 1051 sd->brightness = BRIGHTNESS_DEF;
883 sd->gain = GAIN_DEF; 1052 sd->gain = GAIN_DEF;
884 sd->exposure = EXPOSURE_DEF; 1053 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1054 sd->exposure = COARSE_EXPOSURE_DEF;
1055 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
1056 } else {
1057 sd->exposure = EXPOSURE_DEF;
1058 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1059 }
885 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) 1060 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
886 sd->autogain = 0; /* Disable do_autogain callback */ 1061 sd->autogain = 0; /* Disable do_autogain callback */
887 else 1062 else
@@ -917,9 +1092,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
917 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); 1092 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
918 /* Special cases where reg 17 and or 19 value depends on mode */ 1093 /* Special cases where reg 17 and or 19 value depends on mode */
919 switch (sd->sensor) { 1094 switch (sd->sensor) {
920 case SENSOR_PAS202:
921 reg12_19[5] = mode ? 0x24 : 0x20;
922 break;
923 case SENSOR_TAS5130CXX: 1095 case SENSOR_TAS5130CXX:
924 /* probably not mode specific at all most likely the upper 1096 /* probably not mode specific at all most likely the upper
925 nibble of 0x19 is exposure (clock divider) just as with 1097 nibble of 0x19 is exposure (clock divider) just as with
@@ -955,6 +1127,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
955 sensor_data[sd->sensor].sensor_bridge_init_size[ 1127 sensor_data[sd->sensor].sensor_bridge_init_size[
956 sd->bridge]); 1128 sd->bridge]);
957 1129
1130 /* Mode specific sensor setup */
1131 switch (sd->sensor) {
1132 case SENSOR_PAS202: {
1133 const __u8 i2cpclockdiv[] =
1134 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1135 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1136 if (mode)
1137 i2c_w(gspca_dev, i2cpclockdiv);
1138 }
1139 }
958 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 1140 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
959 reg_w(gspca_dev, 0x15, &reg12_19[3], 2); 1141 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
960 /* compression register */ 1142 /* compression register */
@@ -985,6 +1167,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
985 1167
986 sd->frames_to_drop = 0; 1168 sd->frames_to_drop = 0;
987 sd->autogain_ignore_frames = 0; 1169 sd->autogain_ignore_frames = 0;
1170 sd->exp_too_high_cnt = 0;
1171 sd->exp_too_low_cnt = 0;
988 atomic_set(&sd->avg_lum, -1); 1172 atomic_set(&sd->avg_lum, -1);
989 return 0; 1173 return 0;
990} 1174}
@@ -1143,11 +1327,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1143 struct sd *sd = (struct sd *) gspca_dev; 1327 struct sd *sd = (struct sd *) gspca_dev;
1144 1328
1145 sd->autogain = val; 1329 sd->autogain = val;
1330 sd->exp_too_high_cnt = 0;
1331 sd->exp_too_low_cnt = 0;
1332
1146 /* when switching to autogain set defaults to make sure 1333 /* when switching to autogain set defaults to make sure
1147 we are on a valid point of the autogain gain / 1334 we are on a valid point of the autogain gain /
1148 exposure knee graph, and give this change time to 1335 exposure knee graph, and give this change time to
1149 take effect before doing autogain. */ 1336 take effect before doing autogain. */
1150 if (sd->autogain) { 1337 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1151 sd->exposure = EXPOSURE_DEF; 1338 sd->exposure = EXPOSURE_DEF;
1152 sd->gain = GAIN_DEF; 1339 sd->gain = GAIN_DEF;
1153 if (gspca_dev->streaming) { 1340 if (gspca_dev->streaming) {
@@ -1207,6 +1394,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
1207 return -EINVAL; 1394 return -EINVAL;
1208} 1395}
1209 1396
1397#ifdef CONFIG_INPUT
1398static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1399 u8 *data, /* interrupt packet data */
1400 int len) /* interrupt packet length */
1401{
1402 int ret = -EINVAL;
1403
1404 if (len == 1 && data[0] == 1) {
1405 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1406 input_sync(gspca_dev->input_dev);
1407 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1408 input_sync(gspca_dev->input_dev);
1409 ret = 0;
1410 }
1411
1412 return ret;
1413}
1414#endif
1415
1210/* sub-driver description */ 1416/* sub-driver description */
1211static const struct sd_desc sd_desc = { 1417static const struct sd_desc sd_desc = {
1212 .name = MODULE_NAME, 1418 .name = MODULE_NAME,
@@ -1219,6 +1425,9 @@ static const struct sd_desc sd_desc = {
1219 .pkt_scan = sd_pkt_scan, 1425 .pkt_scan = sd_pkt_scan,
1220 .querymenu = sd_querymenu, 1426 .querymenu = sd_querymenu,
1221 .dq_callback = do_autogain, 1427 .dq_callback = do_autogain,
1428#ifdef CONFIG_INPUT
1429 .int_pkt_scan = sd_int_pkt_scan,
1430#endif
1222}; 1431};
1223 1432
1224/* -- module initialisation -- */ 1433/* -- module initialisation -- */
@@ -1227,21 +1436,21 @@ static const struct sd_desc sd_desc = {
1227 1436
1228 1437
1229static const struct usb_device_id device_table[] __devinitconst = { 1438static const struct usb_device_id device_table[] __devinitconst = {
1230 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ 1439 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1231 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ 1440 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1232#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1441#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */ 1442 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1443#endif
1234 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, 1444 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1235 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, 1445 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1236#endif
1237 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, 1446 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1238#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1447#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1239 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, 1448 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1240 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, 1449 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1241 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, 1450 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1451#endif
1242 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, 1452 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1243 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1453 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1244#endif
1245 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, 1454 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1246 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1455 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1247#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1456#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE