aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixj.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r--drivers/media/video/gspca/sonixj.c548
1 files changed, 370 insertions, 178 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 245a30ec5fb1..572b0f363b64 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -54,8 +54,10 @@ struct sd {
54#define SENSOR_HV7131R 0 54#define SENSOR_HV7131R 0
55#define SENSOR_MI0360 1 55#define SENSOR_MI0360 1
56#define SENSOR_MO4000 2 56#define SENSOR_MO4000 2
57#define SENSOR_OV7648 3 57#define SENSOR_OM6802 3
58#define SENSOR_OV7660 4 58#define SENSOR_OV7630 4
59#define SENSOR_OV7648 5
60#define SENSOR_OV7660 6
59 unsigned char i2c_base; 61 unsigned char i2c_base;
60}; 62};
61 63
@@ -76,7 +78,8 @@ static struct ctrl sd_ctrls[] = {
76 .type = V4L2_CTRL_TYPE_INTEGER, 78 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness", 79 .name = "Brightness",
78 .minimum = 0, 80 .minimum = 0,
79 .maximum = 0xffff, 81#define BRIGHTNESS_MAX 0xffff
82 .maximum = BRIGHTNESS_MAX,
80 .step = 1, 83 .step = 1,
81#define BRIGHTNESS_DEF 0x7fff 84#define BRIGHTNESS_DEF 0x7fff
82 .default_value = BRIGHTNESS_DEF, 85 .default_value = BRIGHTNESS_DEF,
@@ -90,7 +93,8 @@ static struct ctrl sd_ctrls[] = {
90 .type = V4L2_CTRL_TYPE_INTEGER, 93 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Contrast", 94 .name = "Contrast",
92 .minimum = 0, 95 .minimum = 0,
93 .maximum = 127, 96#define CONTRAST_MAX 127
97 .maximum = CONTRAST_MAX,
94 .step = 1, 98 .step = 1,
95#define CONTRAST_DEF 63 99#define CONTRAST_DEF 63
96 .default_value = CONTRAST_DEF, 100 .default_value = CONTRAST_DEF,
@@ -104,14 +108,15 @@ static struct ctrl sd_ctrls[] = {
104 .type = V4L2_CTRL_TYPE_INTEGER, 108 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Color", 109 .name = "Color",
106 .minimum = 0, 110 .minimum = 0,
107 .maximum = 255, 111 .maximum = 64,
108 .step = 1, 112 .step = 1,
109#define COLOR_DEF 127 113#define COLOR_DEF 32
110 .default_value = COLOR_DEF, 114 .default_value = COLOR_DEF,
111 }, 115 },
112 .set = sd_setcolors, 116 .set = sd_setcolors,
113 .get = sd_getcolors, 117 .get = sd_getcolors,
114 }, 118 },
119#define AUTOGAIN_IDX 3
115 { 120 {
116 { 121 {
117 .id = V4L2_CID_AUTOGAIN, 122 .id = V4L2_CID_AUTOGAIN,
@@ -131,7 +136,7 @@ static struct ctrl sd_ctrls[] = {
131static struct v4l2_pix_format vga_mode[] = { 136static struct v4l2_pix_format vga_mode[] = {
132 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 137 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .bytesperline = 160, 138 .bytesperline = 160,
134 .sizeimage = 160 * 120 * 3 / 8 + 590, 139 .sizeimage = 160 * 120 * 4 / 8 + 590,
135 .colorspace = V4L2_COLORSPACE_JPEG, 140 .colorspace = V4L2_COLORSPACE_JPEG,
136 .priv = 2}, 141 .priv = 2},
137 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -180,6 +185,31 @@ static const __u8 sn_mo4000[] = {
180 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 185 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181}; 186};
182 187
188static const __u8 sn_om6802[] = {
189/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
190 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
191/* reg8 reg9 rega regb regc regd rege regf */
192 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
194 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
195/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
196 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
198 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
199 0xf7
200};
201
202static const __u8 sn_ov7630[] = {
203/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
204 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
205/* reg8 reg9 rega regb regc regd rege regf */
206 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
207/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
208 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
209/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
210 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
211};
212
183static const __u8 sn_ov7648[] = { 213static const __u8 sn_ov7648[] = {
184/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 214/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
185 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 215 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -207,31 +237,22 @@ static const __u8 *sn_tb[] = {
207 sn_hv7131, 237 sn_hv7131,
208 sn_mi0360, 238 sn_mi0360,
209 sn_mo4000, 239 sn_mo4000,
240 sn_om6802,
241 sn_ov7630,
210 sn_ov7648, 242 sn_ov7648,
211 sn_ov7660 243 sn_ov7660
212}; 244};
213 245
214static const __u8 regsn20[] = { 246static const __u8 gamma_def[] = {
215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 247 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
217}; 249};
218static const __u8 regsn20_sn9c325[] = {
219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
221};
222 250
223static const __u8 reg84[] = { 251static const __u8 reg84[] = {
224 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
225 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, 253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
226/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 254 0xf7, 0x0f, 0x00, 0x00, 0x00
227 0xf7, 0x0f, 0x0a, 0x00, 0x00
228};
229static const __u8 reg84_sn9c325[] = {
230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
232 0xf8, 0x0f, 0x00, 0x00, 0x00
233}; 255};
234
235static const __u8 hv7131r_sensor_init[][8] = { 256static const __u8 hv7131r_sensor_init[][8] = {
236 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 257 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
237 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, 258 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
@@ -340,6 +361,92 @@ static const __u8 mo4000_sensor_init[][8] = {
340 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, 361 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
341 {} 362 {}
342}; 363};
364static __u8 om6802_sensor_init[][8] = {
365 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
366 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
367 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
368 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
369/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
370 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
371 /* white balance & auto-exposure */
372/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
373 * set color mode */
374/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
375 * max AGC value in AE */
376/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
377 * preset AGC */
378/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
379 * preset brightness */
380/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
381 * preset contrast */
382/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
383 * preset gamma */
384 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
385 /* luminance mode (0x4f = AE) */
386 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
387 /* preset shutter */
388/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
389 * auto frame rate */
390/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
391
392/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
393/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
394/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
395/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
396 {}
397};
398static const __u8 ov7630_sensor_init[][8] = {
399 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
401/* win: delay 20ms */
402 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
403 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
404/* win: delay 20ms */
405 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
406/* win: i2c_r from 00 to 80 */
407 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
408 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
409 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
410 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
411 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
412 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
413 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
414 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
415 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
416 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
417 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
418 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
422 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
424 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
425 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
426 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
427 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
428 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
429 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
430 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
431 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
432 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
433/* */
434 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
436/*fixme: + 0x12, 0x04*/
437 {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
441/* */
442 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
445/* */
446 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
447/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
448 {}
449};
343static const __u8 ov7660_sensor_init[][8] = { 450static const __u8 ov7660_sensor_init[][8] = {
344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 451 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
345/* (delay 20ms) */ 452/* (delay 20ms) */
@@ -506,10 +613,16 @@ static const __u8 qtable4[] = {
506 0x29, 0x29, 0x29, 0x29 613 0x29, 0x29, 0x29, 0x29
507}; 614};
508 615
509/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */ 616/* read <len> bytes to gspca_dev->usb_buf */
510static void reg_r(struct gspca_dev *gspca_dev, 617static void reg_r(struct gspca_dev *gspca_dev,
511 __u16 value, int len) 618 __u16 value, int len)
512{ 619{
620#ifdef GSPCA_DEBUG
621 if (len > USB_BUF_SZ) {
622 err("reg_r: buffer overflow");
623 return;
624 }
625#endif
513 usb_control_msg(gspca_dev->dev, 626 usb_control_msg(gspca_dev->dev,
514 usb_rcvctrlpipe(gspca_dev->dev, 0), 627 usb_rcvctrlpipe(gspca_dev->dev, 0),
515 0, 628 0,
@@ -542,29 +655,20 @@ static void reg_w(struct gspca_dev *gspca_dev,
542{ 655{
543 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", 656 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
544 value, buffer[0], buffer[1]); 657 value, buffer[0], buffer[1]);
545 if (len <= sizeof gspca_dev->usb_buf) { 658#ifdef GSPCA_DEBUG
546 memcpy(gspca_dev->usb_buf, buffer, len); 659 if (len > USB_BUF_SZ) {
547 usb_control_msg(gspca_dev->dev, 660 err("reg_w: buffer overflow");
548 usb_sndctrlpipe(gspca_dev->dev, 0), 661 return;
549 0x08,
550 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
551 value, 0,
552 gspca_dev->usb_buf, len,
553 500);
554 } else {
555 __u8 *tmpbuf;
556
557 tmpbuf = kmalloc(len, GFP_KERNEL);
558 memcpy(tmpbuf, buffer, len);
559 usb_control_msg(gspca_dev->dev,
560 usb_sndctrlpipe(gspca_dev->dev, 0),
561 0x08,
562 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
563 value, 0,
564 tmpbuf, len,
565 500);
566 kfree(tmpbuf);
567 } 662 }
663#endif
664 memcpy(gspca_dev->usb_buf, buffer, len);
665 usb_control_msg(gspca_dev->dev,
666 usb_sndctrlpipe(gspca_dev->dev, 0),
667 0x08,
668 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
669 value, 0,
670 gspca_dev->usb_buf, len,
671 500);
568} 672}
569 673
570/* I2C write 1 byte */ 674/* I2C write 1 byte */
@@ -603,6 +707,7 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
603 0x08, 0, /* value, index */ 707 0x08, 0, /* value, index */
604 gspca_dev->usb_buf, 8, 708 gspca_dev->usb_buf, 8,
605 500); 709 500);
710 msleep(2);
606} 711}
607 712
608/* read 5 bytes in gspca_dev->usb_buf */ 713/* read 5 bytes in gspca_dev->usb_buf */
@@ -665,7 +770,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
665 static const __u8 regd4[] = {0x60, 0x00, 0x00}; 770 static const __u8 regd4[] = {0x60, 0x00, 0x00};
666 771
667 reg_w1(gspca_dev, 0xf1, 0x00); 772 reg_w1(gspca_dev, 0xf1, 0x00);
668 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ 773 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
669 774
670 /* configure gpio */ 775 /* configure gpio */
671 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 776 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -685,21 +790,41 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
685 790
686 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 791 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
687 792
688 switch (sd->bridge) { 793 switch (sd->sensor) {
689 case BRIDGE_SN9C325: 794 case SENSOR_OM6802:
795 reg_w1(gspca_dev, 0x02, 0x71);
796 reg_w1(gspca_dev, 0x01, 0x42);
797 reg_w1(gspca_dev, 0x17, 0x64);
798 reg_w1(gspca_dev, 0x01, 0x42);
799 break;
800/*jfm: from win trace */
801 case SENSOR_OV7630:
802 reg_w1(gspca_dev, 0x01, 0x61);
803 reg_w1(gspca_dev, 0x17, 0xe2);
804 reg_w1(gspca_dev, 0x01, 0x60);
805 reg_w1(gspca_dev, 0x01, 0x40);
806 break;
807 case SENSOR_OV7648:
690 reg_w1(gspca_dev, 0x01, 0x43); 808 reg_w1(gspca_dev, 0x01, 0x43);
691 reg_w1(gspca_dev, 0x17, 0xae); 809 reg_w1(gspca_dev, 0x17, 0xae);
692 reg_w1(gspca_dev, 0x01, 0x42); 810 reg_w1(gspca_dev, 0x01, 0x42);
693 break; 811 break;
812/*jfm: from win trace */
813 case SENSOR_OV7660:
814 reg_w1(gspca_dev, 0x01, 0x61);
815 reg_w1(gspca_dev, 0x17, 0x20);
816 reg_w1(gspca_dev, 0x01, 0x60);
817 reg_w1(gspca_dev, 0x01, 0x40);
818 break;
694 default: 819 default:
695 reg_w1(gspca_dev, 0x01, 0x43); 820 reg_w1(gspca_dev, 0x01, 0x43);
696 reg_w1(gspca_dev, 0x17, 0x61); 821 reg_w1(gspca_dev, 0x17, 0x61);
697 reg_w1(gspca_dev, 0x01, 0x42); 822 reg_w1(gspca_dev, 0x01, 0x42);
698 } 823 if (sd->sensor == SENSOR_HV7131R) {
699 824 if (probesensor(gspca_dev) < 0)
700 if (sd->sensor == SENSOR_HV7131R) { 825 return -ENODEV;
701 if (probesensor(gspca_dev) < 0) 826 }
702 return -ENODEV; 827 break;
703 } 828 }
704 return 0; 829 return 0;
705} 830}
@@ -737,6 +862,40 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
737 } 862 }
738} 863}
739 864
865static void om6802_InitSensor(struct gspca_dev *gspca_dev)
866{
867 int i = 0;
868
869 while (om6802_sensor_init[i][0]) {
870 i2c_w8(gspca_dev, om6802_sensor_init[i]);
871 i++;
872 }
873}
874
875static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
876{
877 int i = 0;
878
879 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
880 i++;
881 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
882 i++;
883 msleep(20);
884 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
885 i++;
886 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
887 i++;
888 msleep(20);
889 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
890 i++;
891/*jfm:win i2c_r from 00 to 80*/
892
893 while (ov7630_sensor_init[i][0]) {
894 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
895 i++;
896 }
897}
898
740static void ov7648_InitSensor(struct gspca_dev *gspca_dev) 899static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
741{ 900{
742 int i = 0; 901 int i = 0;
@@ -783,11 +942,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
783 sd->autogain = AUTOGAIN_DEF; 942 sd->autogain = AUTOGAIN_DEF;
784 sd->ag_cnt = -1; 943 sd->ag_cnt = -1;
785 944
945 switch (sd->sensor) {
946 case SENSOR_OV7630:
947 case SENSOR_OV7648:
948 case SENSOR_OV7660:
949 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
950 break;
951 }
952
786 return 0; 953 return 0;
787} 954}
788 955
789/* this function is called at open time */ 956/* this function is called at probe and resume time */
790static int sd_open(struct gspca_dev *gspca_dev) 957static int sd_init(struct gspca_dev *gspca_dev)
791{ 958{
792 struct sd *sd = (struct sd *) gspca_dev; 959 struct sd *sd = (struct sd *) gspca_dev;
793/* const __u8 *sn9c1xx; */ 960/* const __u8 *sn9c1xx; */
@@ -810,13 +977,13 @@ static int sd_open(struct gspca_dev *gspca_dev)
810 case BRIDGE_SN9C105: 977 case BRIDGE_SN9C105:
811 if (regF1 != 0x11) 978 if (regF1 != 0x11)
812 return -ENODEV; 979 return -ENODEV;
813 reg_w(gspca_dev, 0x02, regGpio, 2); 980 reg_w(gspca_dev, 0x01, regGpio, 2);
814 break; 981 break;
815 case BRIDGE_SN9C120: 982 case BRIDGE_SN9C120:
816 if (regF1 != 0x12) 983 if (regF1 != 0x12)
817 return -ENODEV; 984 return -ENODEV;
818 regGpio[1] = 0x70; 985 regGpio[1] = 0x70;
819 reg_w(gspca_dev, 0x02, regGpio, 2); 986 reg_w(gspca_dev, 0x01, regGpio, 2);
820 break; 987 break;
821 default: 988 default:
822/* case BRIDGE_SN9C110: */ 989/* case BRIDGE_SN9C110: */
@@ -891,16 +1058,53 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
891 | ((expoMo10[3] & 0x30) >> 4)); 1058 | ((expoMo10[3] & 0x30) >> 4));
892 break; 1059 break;
893 } 1060 }
1061 case SENSOR_OM6802: {
1062 __u8 gainOm[] =
1063 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1064
1065 if (expo > 0x03ff)
1066 expo = 0x03ff;
1067 if (expo < 0x0001)
1068 expo = 0x0001;
1069 gainOm[3] = expo >> 2;
1070 i2c_w8(gspca_dev, gainOm);
1071 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1072 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1073 break;
1074 }
894 } 1075 }
895 return expo; 1076 return expo;
896} 1077}
897 1078
1079/* this function is used for sensors o76xx only */
1080static void setbrightcont(struct gspca_dev *gspca_dev)
1081{
1082 struct sd *sd = (struct sd *) gspca_dev;
1083 unsigned val;
1084 __u8 reg84_full[0x15];
1085
1086 memset(reg84_full, 0, sizeof reg84_full);
1087 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1088 reg84_full[2] = val;
1089 reg84_full[0] = (val + 1) / 2;
1090 reg84_full[4] = (val + 1) / 5;
1091 if (val > BRIGHTNESS_DEF)
1092 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1093 / BRIGHTNESS_MAX;
1094 else
1095 val = 0;
1096 reg84_full[0x12] = val; /* 00..1f */
1097 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1098}
1099
1100/* sensor != ov76xx */
898static void setbrightness(struct gspca_dev *gspca_dev) 1101static void setbrightness(struct gspca_dev *gspca_dev)
899{ 1102{
900 struct sd *sd = (struct sd *) gspca_dev; 1103 struct sd *sd = (struct sd *) gspca_dev;
901 unsigned int expo; 1104 unsigned int expo;
902 __u8 k2; 1105 __u8 k2;
903 1106
1107 k2 = sd->brightness >> 10;
904 switch (sd->sensor) { 1108 switch (sd->sensor) {
905 case SENSOR_HV7131R: 1109 case SENSOR_HV7131R:
906 expo = sd->brightness << 4; 1110 expo = sd->brightness << 4;
@@ -915,12 +1119,17 @@ static void setbrightness(struct gspca_dev *gspca_dev)
915 expo = sd->brightness >> 4; 1119 expo = sd->brightness >> 4;
916 sd->exposure = setexposure(gspca_dev, expo); 1120 sd->exposure = setexposure(gspca_dev, expo);
917 break; 1121 break;
1122 case SENSOR_OM6802:
1123 expo = sd->brightness >> 6;
1124 sd->exposure = setexposure(gspca_dev, expo);
1125 k2 = sd->brightness >> 11;
1126 break;
918 } 1127 }
919 1128
920 k2 = sd->brightness >> 10;
921 reg_w1(gspca_dev, 0x96, k2); 1129 reg_w1(gspca_dev, 0x96, k2);
922} 1130}
923 1131
1132/* sensor != ov76xx */
924static void setcontrast(struct gspca_dev *gspca_dev) 1133static void setcontrast(struct gspca_dev *gspca_dev)
925{ 1134{
926 struct sd *sd = (struct sd *) gspca_dev; 1135 struct sd *sd = (struct sd *) gspca_dev;
@@ -937,31 +1146,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
937static void setcolors(struct gspca_dev *gspca_dev) 1146static void setcolors(struct gspca_dev *gspca_dev)
938{ 1147{
939 struct sd *sd = (struct sd *) gspca_dev; 1148 struct sd *sd = (struct sd *) gspca_dev;
940 __u8 data; 1149 __u8 blue, red;
941 int colour;
942 1150
943 colour = sd->colors - 128; 1151 if (sd->colors >= 32) {
944 if (colour > 0) 1152 red = 32 + (sd->colors - 32) / 2;
945 data = (colour + 32) & 0x7f; /* blue */ 1153 blue = 64 - sd->colors;
946 else 1154 } else {
947 data = (-colour + 32) & 0x7f; /* red */ 1155 red = sd->colors;
948 reg_w1(gspca_dev, 0x05, data); 1156 blue = 32 + (32 - sd->colors) / 2;
1157 }
1158 reg_w1(gspca_dev, 0x05, red);
1159/* reg_w1(gspca_dev, 0x07, 32); */
1160 reg_w1(gspca_dev, 0x06, blue);
949} 1161}
950 1162
951static void setautogain(struct gspca_dev *gspca_dev) 1163static void setautogain(struct gspca_dev *gspca_dev)
952{ 1164{
953 struct sd *sd = (struct sd *) gspca_dev; 1165 struct sd *sd = (struct sd *) gspca_dev;
954 1166
955 switch (sd->sensor) { 1167 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
956 case SENSOR_HV7131R: 1168 return;
957 case SENSOR_MO4000: 1169 if (sd->autogain)
958 case SENSOR_MI0360: 1170 sd->ag_cnt = AG_CNT_START;
959 if (sd->autogain) 1171 else
960 sd->ag_cnt = AG_CNT_START; 1172 sd->ag_cnt = -1;
961 else
962 sd->ag_cnt = -1;
963 break;
964 }
965} 1173}
966 1174
967/* -- start the camera -- */ 1175/* -- start the camera -- */
@@ -975,13 +1183,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
975 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1183 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
976 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1184 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
977 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 1185 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
978 static const __u8 CE_sn9c325[] = 1186 static const __u8 CE_ov76xx[] =
979 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ 1187 { 0x32, 0xdd, 0x32, 0xdd };
980 1188
981 sn9c1xx = sn_tb[(int) sd->sensor]; 1189 sn9c1xx = sn_tb[(int) sd->sensor];
982 configure_gpio(gspca_dev, sn9c1xx); 1190 configure_gpio(gspca_dev, sn9c1xx);
983 1191
984/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
985 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 1192 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
986 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 1193 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
987 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 1194 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -994,10 +1201,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
994 reg_w1(gspca_dev, 0xc8, 0x50); 1201 reg_w1(gspca_dev, 0xc8, 0x50);
995 reg_w1(gspca_dev, 0xc9, 0x3c); 1202 reg_w1(gspca_dev, 0xc9, 0x3c);
996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1203 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
997 switch (sd->bridge) { 1204 switch (sd->sensor) {
998 case BRIDGE_SN9C325: 1205 case SENSOR_OV7630:
1206 reg17 = 0xe2;
1207 break;
1208 case SENSOR_OV7648:
999 reg17 = 0xae; 1209 reg17 = 0xae;
1000 break; 1210 break;
1211/*jfm: from win trace */
1212 case SENSOR_OV7660:
1213 reg17 = 0xa0;
1214 break;
1001 default: 1215 default:
1002 reg17 = 0x60; 1216 reg17 = 0x60;
1003 break; 1217 break;
@@ -1007,20 +1221,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
1007 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1221 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1008 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1222 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1009 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1223 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1010 switch (sd->bridge) { 1224 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1011 case BRIDGE_SN9C325: 1225 for (i = 0; i < 8; i++)
1012 reg_w(gspca_dev, 0x20, regsn20_sn9c325, 1226 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1013 sizeof regsn20_sn9c325); 1227 switch (sd->sensor) {
1014 for (i = 0; i < 8; i++) 1228 case SENSOR_OV7660:
1015 reg_w(gspca_dev, 0x84, reg84_sn9c325, 1229 reg_w1(gspca_dev, 0x9a, 0x05);
1016 sizeof reg84_sn9c325);
1017 reg_w1(gspca_dev, 0x9a, 0x0a);
1018 reg_w1(gspca_dev, 0x99, 0x60);
1019 break; 1230 break;
1020 default: 1231 default:
1021 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1022 for (i = 0; i < 8; i++)
1023 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1024 reg_w1(gspca_dev, 0x9a, 0x08); 1232 reg_w1(gspca_dev, 0x9a, 0x08);
1025 reg_w1(gspca_dev, 0x99, 0x59); 1233 reg_w1(gspca_dev, 0x99, 0x59);
1026 break; 1234 break;
@@ -1049,6 +1257,15 @@ static void sd_start(struct gspca_dev *gspca_dev)
1049/* reg1 = 0x06; * 640 clk 24Mz (done) */ 1257/* reg1 = 0x06; * 640 clk 24Mz (done) */
1050 } 1258 }
1051 break; 1259 break;
1260 case SENSOR_OM6802:
1261 om6802_InitSensor(gspca_dev);
1262 reg17 = 0x64; /* 640 MCKSIZE */
1263 break;
1264 case SENSOR_OV7630:
1265 ov7630_InitSensor(gspca_dev);
1266 reg17 = 0xe2;
1267 reg1 = 0x44;
1268 break;
1052 case SENSOR_OV7648: 1269 case SENSOR_OV7648:
1053 ov7648_InitSensor(gspca_dev); 1270 ov7648_InitSensor(gspca_dev);
1054 reg17 = 0xa2; 1271 reg17 = 0xa2;
@@ -1066,16 +1283,18 @@ static void sd_start(struct gspca_dev *gspca_dev)
1066/* reg1 = 0x44; */ 1283/* reg1 = 0x44; */
1067/* reg1 = 0x46; (done) */ 1284/* reg1 = 0x46; (done) */
1068 } else { 1285 } else {
1069 reg17 = 0x22; /* 640 MCKSIZE */ 1286 reg17 = 0xa2; /* 640 */
1070 reg1 = 0x06; 1287 reg1 = 0x44;
1071 } 1288 }
1072 break; 1289 break;
1073 } 1290 }
1074 reg_w(gspca_dev, 0xc0, C0, 6); 1291 reg_w(gspca_dev, 0xc0, C0, 6);
1075 reg_w(gspca_dev, 0xca, CA, 4); 1292 reg_w(gspca_dev, 0xca, CA, 4);
1076 switch (sd->bridge) { 1293 switch (sd->sensor) {
1077 case BRIDGE_SN9C325: 1294 case SENSOR_OV7630:
1078 reg_w(gspca_dev, 0xce, CE_sn9c325, 4); 1295 case SENSOR_OV7648:
1296 case SENSOR_OV7660:
1297 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1079 break; 1298 break;
1080 default: 1299 default:
1081 reg_w(gspca_dev, 0xce, CE, 4); 1300 reg_w(gspca_dev, 0xce, CE, 4);
@@ -1093,10 +1312,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
1093 reg_w1(gspca_dev, 0x18, reg18); 1312 reg_w1(gspca_dev, 0x18, reg18);
1094 1313
1095 reg_w1(gspca_dev, 0x17, reg17); 1314 reg_w1(gspca_dev, 0x17, reg17);
1096 reg_w1(gspca_dev, 0x01, reg1); 1315 switch (sd->sensor) {
1097 setbrightness(gspca_dev); 1316 case SENSOR_HV7131R:
1098 setcontrast(gspca_dev); 1317 case SENSOR_MI0360:
1318 case SENSOR_MO4000:
1319 case SENSOR_OM6802:
1320 setbrightness(gspca_dev);
1321 setcontrast(gspca_dev);
1322 break;
1323 default: /* OV76xx */
1324 setbrightcont(gspca_dev);
1325 break;
1326 }
1099 setautogain(gspca_dev); 1327 setautogain(gspca_dev);
1328 reg_w1(gspca_dev, 0x01, reg1);
1100} 1329}
1101 1330
1102static void sd_stopN(struct gspca_dev *gspca_dev) 1331static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1119,6 +1348,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1119 i2c_w8(gspca_dev, stopmi0360); 1348 i2c_w8(gspca_dev, stopmi0360);
1120 data = 0x29; 1349 data = 0x29;
1121 break; 1350 break;
1351 case SENSOR_OV7630:
1122 case SENSOR_OV7648: 1352 case SENSOR_OV7648:
1123 data = 0x29; 1353 data = 0x29;
1124 break; 1354 break;
@@ -1132,15 +1362,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1132 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 1362 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1133 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1363 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1134 reg_w1(gspca_dev, 0x01, data); 1364 reg_w1(gspca_dev, 0x01, data);
1135 reg_w1(gspca_dev, 0xf1, 0x01); 1365 reg_w1(gspca_dev, 0xf1, 0x00);
1136}
1137
1138static void sd_stop0(struct gspca_dev *gspca_dev)
1139{
1140}
1141
1142static void sd_close(struct gspca_dev *gspca_dev)
1143{
1144} 1366}
1145 1367
1146static void do_autogain(struct gspca_dev *gspca_dev) 1368static void do_autogain(struct gspca_dev *gspca_dev)
@@ -1174,6 +1396,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1174 default: 1396 default:
1175/* case SENSOR_MO4000: */ 1397/* case SENSOR_MO4000: */
1176/* case SENSOR_MI0360: */ 1398/* case SENSOR_MI0360: */
1399/* case SENSOR_OM6802: */
1177 expotimes = sd->exposure; 1400 expotimes = sd->exposure;
1178 expotimes += (luma_mean - delta) >> 6; 1401 expotimes += (luma_mean - delta) >> 6;
1179 if (expotimes < 0) 1402 if (expotimes < 0)
@@ -1229,69 +1452,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1229 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1452 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1230} 1453}
1231 1454
1232static unsigned int getexposure(struct gspca_dev *gspca_dev)
1233{
1234 struct sd *sd = (struct sd *) gspca_dev;
1235 __u8 hexpo, mexpo, lexpo;
1236
1237 switch (sd->sensor) {
1238 case SENSOR_HV7131R:
1239 /* read sensor exposure */
1240 i2c_r5(gspca_dev, 0x25);
1241 return (gspca_dev->usb_buf[0] << 16)
1242 | (gspca_dev->usb_buf[1] << 8)
1243 | gspca_dev->usb_buf[2];
1244 case SENSOR_MI0360:
1245 /* read sensor exposure */
1246 i2c_r5(gspca_dev, 0x09);
1247 return (gspca_dev->usb_buf[0] << 8)
1248 | gspca_dev->usb_buf[1];
1249 case SENSOR_MO4000:
1250 i2c_r5(gspca_dev, 0x0e);
1251 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1252 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1253 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1254 PDEBUG(D_CONF, "exposure %d",
1255 (hexpo << 10) | (mexpo << 2) | lexpo);
1256 return (hexpo << 10) | (mexpo << 2) | lexpo;
1257 default:
1258/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1259/* case SENSOR_OV7660: */
1260 /* read sensor exposure */
1261 i2c_r5(gspca_dev, 0x04);
1262 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1263 lexpo = gspca_dev->usb_buf[0] & 0x02;
1264 i2c_r5(gspca_dev, 0x08);
1265 mexpo = gspca_dev->usb_buf[2];
1266 return (hexpo << 10) | (mexpo << 2) | lexpo;
1267 }
1268}
1269
1270static void getbrightness(struct gspca_dev *gspca_dev)
1271{
1272 struct sd *sd = (struct sd *) gspca_dev;
1273
1274 /* hardcoded registers seem not readable */
1275 switch (sd->sensor) {
1276 case SENSOR_HV7131R:
1277 sd->brightness = getexposure(gspca_dev) >> 4;
1278 break;
1279 case SENSOR_MI0360:
1280 sd->brightness = getexposure(gspca_dev) << 4;
1281 break;
1282 case SENSOR_MO4000:
1283 sd->brightness = getexposure(gspca_dev) << 4;
1284 break;
1285 }
1286}
1287
1288static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1455static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1289{ 1456{
1290 struct sd *sd = (struct sd *) gspca_dev; 1457 struct sd *sd = (struct sd *) gspca_dev;
1291 1458
1292 sd->brightness = val; 1459 sd->brightness = val;
1293 if (gspca_dev->streaming) 1460 if (gspca_dev->streaming) {
1294 setbrightness(gspca_dev); 1461 switch (sd->sensor) {
1462 case SENSOR_HV7131R:
1463 case SENSOR_MI0360:
1464 case SENSOR_MO4000:
1465 case SENSOR_OM6802:
1466 setbrightness(gspca_dev);
1467 break;
1468 default: /* OV76xx */
1469 setbrightcont(gspca_dev);
1470 break;
1471 }
1472 }
1295 return 0; 1473 return 0;
1296} 1474}
1297 1475
@@ -1299,7 +1477,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1299{ 1477{
1300 struct sd *sd = (struct sd *) gspca_dev; 1478 struct sd *sd = (struct sd *) gspca_dev;
1301 1479
1302 getbrightness(gspca_dev);
1303 *val = sd->brightness; 1480 *val = sd->brightness;
1304 return 0; 1481 return 0;
1305} 1482}
@@ -1309,8 +1486,19 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1309 struct sd *sd = (struct sd *) gspca_dev; 1486 struct sd *sd = (struct sd *) gspca_dev;
1310 1487
1311 sd->contrast = val; 1488 sd->contrast = val;
1312 if (gspca_dev->streaming) 1489 if (gspca_dev->streaming) {
1313 setcontrast(gspca_dev); 1490 switch (sd->sensor) {
1491 case SENSOR_HV7131R:
1492 case SENSOR_MI0360:
1493 case SENSOR_MO4000:
1494 case SENSOR_OM6802:
1495 setcontrast(gspca_dev);
1496 break;
1497 default: /* OV76xx */
1498 setbrightcont(gspca_dev);
1499 break;
1500 }
1501 }
1314 return 0; 1502 return 0;
1315} 1503}
1316 1504
@@ -1364,11 +1552,9 @@ static const struct sd_desc sd_desc = {
1364 .ctrls = sd_ctrls, 1552 .ctrls = sd_ctrls,
1365 .nctrls = ARRAY_SIZE(sd_ctrls), 1553 .nctrls = ARRAY_SIZE(sd_ctrls),
1366 .config = sd_config, 1554 .config = sd_config,
1367 .open = sd_open, 1555 .init = sd_init,
1368 .start = sd_start, 1556 .start = sd_start,
1369 .stopN = sd_stopN, 1557 .stopN = sd_stopN,
1370 .stop0 = sd_stop0,
1371 .close = sd_close,
1372 .pkt_scan = sd_pkt_scan, 1558 .pkt_scan = sd_pkt_scan,
1373 .dq_callback = do_autogain, 1559 .dq_callback = do_autogain,
1374}; 1560};
@@ -1379,7 +1565,7 @@ static const struct sd_desc sd_desc = {
1379 | (SENSOR_ ## sensor << 8) \ 1565 | (SENSOR_ ## sensor << 8) \
1380 | (i2c_addr) 1566 | (i2c_addr)
1381static const __devinitdata struct usb_device_id device_table[] = { 1567static const __devinitdata struct usb_device_id device_table[] = {
1382#ifndef CONFIG_USB_SN9C102 1568#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1383 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1569 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1384 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1570 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1385 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1571 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
@@ -1406,15 +1592,17 @@ static const __devinitdata struct usb_device_id device_table[] = {
1406/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 1592/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1407/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 1593/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1408/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1594/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1409 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, 1595 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1410/* bw600.inf: 1596/*bw600.inf:*/
1411 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ 1597 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1412 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1598 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1413/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ 1599 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1414/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1600/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1415#ifndef CONFIG_USB_SN9C102 1601#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1416 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1602 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1603#endif
1417 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1604 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1605#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1418/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */ 1606/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1419 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1607 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1420 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1608 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
@@ -1438,6 +1626,10 @@ static struct usb_driver sd_driver = {
1438 .id_table = device_table, 1626 .id_table = device_table,
1439 .probe = sd_probe, 1627 .probe = sd_probe,
1440 .disconnect = gspca_disconnect, 1628 .disconnect = gspca_disconnect,
1629#ifdef CONFIG_PM
1630 .suspend = gspca_suspend,
1631 .resume = gspca_resume,
1632#endif
1441}; 1633};
1442 1634
1443/* -- module insert / remove -- */ 1635/* -- module insert / remove -- */