aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-06-24 04:02:57 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 13:52:02 -0400
commita68f723cef2c97c30e84c39a847c0c5feff5f0d5 (patch)
tree3faf3d01c45f94e848de58b7bea79282a248e5b2 /drivers
parent7d716a36c349bad75e13352d11211c3ae556e92f (diff)
V4L/DVB: gspca - sq930x: New sensor mt9v111
Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/sq930x.c392
1 files changed, 323 insertions, 69 deletions
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
index dd24127d5168..01954701d813 100644
--- a/drivers/media/video/gspca/sq930x.c
+++ b/drivers/media/video/gspca/sq930x.c
@@ -51,8 +51,11 @@ struct sd {
51 u8 sensor; 51 u8 sensor;
52enum { 52enum {
53 SENSOR_ICX098BQ, 53 SENSOR_ICX098BQ,
54 SENSOR_MI0360,
55 SENSOR_LZ24BP, 54 SENSOR_LZ24BP,
55 SENSOR_MI0360,
56 SENSOR_MT9V111,
57 SENSOR_OV7660,
58 SENSOR_OV9630,
56} sensors; 59} sensors;
57 u8 type; 60 u8 type;
58#define Generic 0 61#define Generic 0
@@ -295,10 +298,55 @@ static const struct i2c_write_cmd mi0360_start_4[] = {
295 {0x05, 0x03f5}, /* horiz blanking */ 298 {0x05, 0x03f5}, /* horiz blanking */
296}; 299};
297 300
301static const struct i2c_write_cmd mt9v111_init_0[] = {
302 {0x01, 0x0001},
303 {0x06, 0x300c},
304 {0x08, 0xcc00},
305 {0x01, 0x0004},
306};
307static const struct i2c_write_cmd mt9v111_init_1[] = {
308 {0x03, 0x01e5},
309 {0x04, 0x0285},
310};
311static const struct i2c_write_cmd mt9v111_init_2[] = {
312 {0x30, 0x7800},
313 {0x31, 0x0000},
314 {0x07, 0x3002},
315 {0x35, 0x0020},
316 {0x2b, 0x0020},
317 {0x2c, 0x0020},
318 {0x2d, 0x0020},
319 {0x2e, 0x0020},
320};
321static const struct ucbus_write_cmd mt9v111_start_1[] = {
322 {0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
323 {0xf5f4, 0xaa},
324 {0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
325 {0xf5f4, 0xaa},
326 {0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a},
327 {0xf5f9, 0x0a}
328};
329static const struct i2c_write_cmd mt9v111_init_3[] = {
330 {0x62, 0x0405},
331};
332static const struct i2c_write_cmd mt9v111_init_4[] = {
333 {0x05, 0x00ce},
334};
335
336static const struct ucbus_write_cmd ov7660_start_0[] = {
337 {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0},
338 {0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03}
339};
340
341static const struct ucbus_write_cmd ov9630_start_0[] = {
342 {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00},
343 {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
344};
345
298static const struct cap_s { 346static const struct cap_s {
299 u8 cc_sizeid; 347 u8 cc_sizeid;
300 u8 cc_bytes[32]; 348 u8 cc_bytes[32];
301} capconfig[3][3] = { 349} capconfig[4][3] = {
302 [SENSOR_ICX098BQ] = { 350 [SENSOR_ICX098BQ] = {
303 {0, /* JPEG, 160x120 */ 351 {0, /* JPEG, 160x120 */
304 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee, 352 {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
@@ -351,6 +399,101 @@ static const struct cap_s {
351 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f, 399 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
352 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} }, 400 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
353 }, 401 },
402 [SENSOR_MT9V111] = {
403 {0, /* JPEG, 160x120 */
404 {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b,
405 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
406 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f,
407 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} },
408 {2, /* JPEG, 320x240 */
409 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
410 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
411 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
412 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
413 {4, /* JPEG, 640x480 */
414 {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
415 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
416 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
417 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
418 },
419};
420
421struct sensor_s {
422 const char *name;
423 u8 i2c_addr;
424 u8 i2c_dum;
425 u8 gpio[5];
426 u8 cmd_len;
427 const struct ucbus_write_cmd *cmd;
428};
429
430static const struct sensor_s sensor_tb[] = {
431 [SENSOR_ICX098BQ] = {
432 "icx098bp",
433 0x00, 0x00,
434 {0,
435 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
436 SQ930_GPIO_DFL_I2C_SDA,
437 0,
438 SQ930_GPIO_RSTBAR
439 },
440 8, icx098bq_start_0
441 },
442 [SENSOR_LZ24BP] = {
443 "lz24bp",
444 0x00, 0x00,
445 {0,
446 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
447 SQ930_GPIO_DFL_I2C_SDA,
448 0,
449 SQ930_GPIO_RSTBAR
450 },
451 8, lz24bp_start_0
452 },
453 [SENSOR_MI0360] = {
454 "mi0360",
455 0x5d, 0x80,
456 {SQ930_GPIO_RSTBAR,
457 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
458 SQ930_GPIO_DFL_I2C_SDA,
459 0,
460 0
461 },
462 7, mi0360_start_0
463 },
464 [SENSOR_MT9V111] = {
465 "mt9v111",
466 0x5c, 0x7f,
467 {SQ930_GPIO_RSTBAR,
468 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
469 SQ930_GPIO_DFL_I2C_SDA,
470 0,
471 0
472 },
473 7, mi0360_start_0
474 },
475 [SENSOR_OV7660] = {
476 "ov7660",
477 0x21, 0x00,
478 {0,
479 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
480 SQ930_GPIO_DFL_I2C_SDA,
481 0,
482 SQ930_GPIO_RSTBAR
483 },
484 7, ov7660_start_0
485 },
486 [SENSOR_OV9630] = {
487 "ov9630",
488 0x30, 0x00,
489 {0,
490 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
491 SQ930_GPIO_DFL_I2C_SDA,
492 0,
493 SQ930_GPIO_RSTBAR
494 },
495 7, ov9630_start_0
496 },
354}; 497};
355 498
356static void reg_r(struct gspca_dev *gspca_dev, 499static void reg_r(struct gspca_dev *gspca_dev,
@@ -415,10 +558,12 @@ static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
415 } 558 }
416} 559}
417 560
418static void i2c_write(struct gspca_dev *gspca_dev, 561static void i2c_write(struct sd *sd,
419 const struct i2c_write_cmd *cmd, 562 const struct i2c_write_cmd *cmd,
420 int ncmds) 563 int ncmds)
421{ 564{
565 struct gspca_dev *gspca_dev = &sd->gspca_dev;
566 const struct sensor_s *sensor;
422 u16 val, idx; 567 u16 val, idx;
423 u8 *buf; 568 u8 *buf;
424 int ret; 569 int ret;
@@ -426,18 +571,20 @@ static void i2c_write(struct gspca_dev *gspca_dev,
426 if (gspca_dev->usb_err < 0) 571 if (gspca_dev->usb_err < 0)
427 return; 572 return;
428 573
429 val = (0x5d << 8) | SQ930_CTRL_I2C_IO; /* 0x5d = mi0360 i2c addr */ 574 sensor = &sensor_tb[sd->sensor];
575
576 val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO;
430 idx = (cmd->val & 0xff00) | cmd->reg; 577 idx = (cmd->val & 0xff00) | cmd->reg;
431 578
432 buf = gspca_dev->usb_buf; 579 buf = gspca_dev->usb_buf;
433 *buf++ = 0x80; 580 *buf++ = sensor->i2c_dum;
434 *buf++ = cmd->val; 581 *buf++ = cmd->val;
435 582
436 while (--ncmds > 0) { 583 while (--ncmds > 0) {
437 cmd++; 584 cmd++;
438 *buf++ = cmd->reg; 585 *buf++ = cmd->reg;
439 *buf++ = cmd->val >> 8; 586 *buf++ = cmd->val >> 8;
440 *buf++ = 0x80; 587 *buf++ = sensor->i2c_dum;
441 *buf++ = cmd->val; 588 *buf++ = cmd->val;
442 } 589 }
443 590
@@ -538,7 +685,17 @@ static void gpio_set(struct sd *sd, u16 val, u16 mask)
538 } 685 }
539} 686}
540 687
541static void global_init(struct sd *sd, int first_time) 688static void gpio_init(struct sd *sd,
689 const u8 *gpio)
690{
691 gpio_set(sd, *gpio++, 0x000f);
692 gpio_set(sd, *gpio++, 0x000f);
693 gpio_set(sd, *gpio++, 0x000f);
694 gpio_set(sd, *gpio++, 0x000f);
695 gpio_set(sd, *gpio, 0x000f);
696}
697
698static void bridge_init(struct sd *sd)
542{ 699{
543 static const struct ucbus_write_cmd clkfreq_cmd = { 700 static const struct ucbus_write_cmd clkfreq_cmd = {
544 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */ 701 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */
@@ -547,19 +704,81 @@ static void global_init(struct sd *sd, int first_time)
547 ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1); 704 ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
548 705
549 gpio_set(sd, SQ930_GPIO_POWER, 0xff00); 706 gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
707}
708
709static void cmos_probe(struct gspca_dev *gspca_dev)
710{
711 struct sd *sd = (struct sd *) gspca_dev;
712 int i;
713 const struct sensor_s *sensor;
714 static const u8 probe_order[] = {
715/* SENSOR_LZ24BP, (tested as ccd) */
716 SENSOR_OV9630,
717 SENSOR_MI0360,
718 SENSOR_OV7660,
719 SENSOR_MT9V111,
720 };
721
722 for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
723 sensor = &sensor_tb[probe_order[i]];
724 ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8);
725 gpio_init(sd, sensor->gpio);
726 msleep(100);
727 reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1);
728 msleep(100);
729 if (gspca_dev->usb_buf[0] != 0)
730 break;
731 }
732 if (i >= ARRAY_SIZE(probe_order))
733 PDEBUG(D_PROBE, "Unknown sensor");
734 else
735 sd->sensor = probe_order[i];
736}
737
738static void mt9v111_init(struct gspca_dev *gspca_dev)
739{
740 int i, nwait;
741 static const u8 cmd_001b[] = {
742 0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00,
743 0x00, 0x00, 0x00
744 };
745 static const u8 cmd_011b[][7] = {
746 {0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00},
747 {0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00},
748 {0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00},
749 {0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00},
750 };
751
752 reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b);
753 for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) {
754 reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i],
755 ARRAY_SIZE(cmd_011b[0]));
756 msleep(400);
757 nwait = 20;
758 for (;;) {
759 reg_r(gspca_dev, 0x031b, 1);
760 if (gspca_dev->usb_buf[0] == 0
761 || gspca_dev->usb_err != 0)
762 break;
763 if (--nwait < 0) {
764 PDEBUG(D_PROBE, "mt9v111_init timeout");
765 gspca_dev->usb_err = -ETIME;
766 return;
767 }
768 msleep(50);
769 }
770 }
771}
772
773static void global_init(struct sd *sd, int first_time)
774{
550 switch (sd->sensor) { 775 switch (sd->sensor) {
551 case SENSOR_ICX098BQ: 776 case SENSOR_ICX098BQ:
552 if (first_time) 777 if (first_time)
553 ucbus_write(&sd->gspca_dev, 778 ucbus_write(&sd->gspca_dev,
554 icx098bq_start_0, 779 icx098bq_start_0,
555 8, 8); 780 8, 8);
556 gpio_set(sd, 0, 0x00ff); 781 gpio_init(sd, sensor_tb[sd->sensor].gpio);
557 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
558 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
559 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
560 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
561 gpio_set(sd, SQ930_GPIO_RSTBAR,
562 SQ930_GPIO_RSTBAR);
563 break; 782 break;
564 case SENSOR_LZ24BP: 783 case SENSOR_LZ24BP:
565 if (sd->type != Creative_live_motion) 784 if (sd->type != Creative_live_motion)
@@ -571,34 +790,24 @@ static void global_init(struct sd *sd, int first_time)
571 ucbus_write(&sd->gspca_dev, 790 ucbus_write(&sd->gspca_dev,
572 lz24bp_start_0, 791 lz24bp_start_0,
573 8, 8); 792 8, 8);
574 gpio_set(sd, 0, 0x0001); /* no change */ 793 gpio_init(sd, sensor_tb[sd->sensor].gpio);
575 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
576 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
577 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
578 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
579 gpio_set(sd, SQ930_GPIO_RSTBAR,
580 SQ930_GPIO_RSTBAR);
581 break; 794 break;
582 default: 795 case SENSOR_MI0360:
583/* case SENSOR_MI0360: */ 796 if (first_time)
584 if (first_time) {
585 ucbus_write(&sd->gspca_dev, 797 ucbus_write(&sd->gspca_dev,
586 mi0360_start_0, 798 mi0360_start_0,
587 ARRAY_SIZE(mi0360_start_0), 799 ARRAY_SIZE(mi0360_start_0),
588 8); 800 8);
589 gpio_set(sd, SQ930_GPIO_RSTBAR, 0x00ff); 801 gpio_init(sd, sensor_tb[sd->sensor].gpio);
590 } else {
591 gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR,
592 0x00ff);
593 }
594 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
595 SQ930_GPIO_RSTBAR |
596 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
597 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
598 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
599 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
600 gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2); 802 gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
601 break; 803 break;
804 default:
805/* case SENSOR_MT9V111: */
806 if (first_time)
807 mt9v111_init(&sd->gspca_dev);
808 else
809 gpio_init(sd, sensor_tb[sd->sensor].gpio);
810 break;
602 } 811 }
603} 812}
604 813
@@ -616,30 +825,17 @@ static void setexposure(struct gspca_dev *gspca_dev)
616{ 825{
617 struct sd *sd = (struct sd *) gspca_dev; 826 struct sd *sd = (struct sd *) gspca_dev;
618 int i, integclks, intstartclk, frameclks, min_frclk; 827 int i, integclks, intstartclk, frameclks, min_frclk;
828 const struct sensor_s *sensor;
619 u16 cmd; 829 u16 cmd;
620 u8 buf[15]; 830 u8 buf[15];
621 831
622 integclks = sd->expo; 832 integclks = sd->expo;
623 i = 0; 833 i = 0;
624 cmd = SQ930_CTRL_SET_EXPOSURE; 834 cmd = SQ930_CTRL_SET_EXPOSURE;
625 if (sd->sensor == SENSOR_MI0360) { 835
626 cmd |= 0x0100; 836 switch (sd->sensor) {
627 buf[i++] = 0x5d; /* i2c_slave_addr */ 837 case SENSOR_ICX098BQ: /* ccd */
628 buf[i++] = 0x08; /* 2 * ni2c */ 838 case SENSOR_LZ24BP:
629 buf[i++] = 0x09; /* reg = shutter width */
630 buf[i++] = integclks >> 8; /* val H */
631 buf[i++] = 0x80;
632 buf[i++] = integclks; /* val L */
633 buf[i++] = 0x35; /* reg = global gain */
634 buf[i++] = 0x00; /* val H */
635 buf[i++] = 0x80;
636 buf[i++] = sd->gain; /* val L */
637 buf[i++] = 0x00;
638 buf[i++] = 0x00;
639 buf[i++] = 0x00;
640 buf[i++] = 0x00;
641 buf[i++] = 0x83;
642 } else {
643 min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f; 839 min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
644 if (integclks >= min_frclk) { 840 if (integclks >= min_frclk) {
645 intstartclk = 0; 841 intstartclk = 0;
@@ -653,6 +849,28 @@ static void setexposure(struct gspca_dev *gspca_dev)
653 buf[i++] = frameclks >> 8; 849 buf[i++] = frameclks >> 8;
654 buf[i++] = frameclks; 850 buf[i++] = frameclks;
655 buf[i++] = sd->gain; 851 buf[i++] = sd->gain;
852 break;
853 default: /* cmos */
854/* case SENSOR_MI0360: */
855/* case SENSOR_MT9V111: */
856 cmd |= 0x0100;
857 sensor = &sensor_tb[sd->sensor];
858 buf[i++] = sensor->i2c_addr; /* i2c_slave_addr */
859 buf[i++] = 0x08; /* 2 * ni2c */
860 buf[i++] = 0x09; /* reg = shutter width */
861 buf[i++] = integclks >> 8; /* val H */
862 buf[i++] = sensor->i2c_dum;
863 buf[i++] = integclks; /* val L */
864 buf[i++] = 0x35; /* reg = global gain */
865 buf[i++] = 0x00; /* val H */
866 buf[i++] = sensor->i2c_dum;
867 buf[i++] = sd->gain; /* val L */
868 buf[i++] = 0x00;
869 buf[i++] = 0x00;
870 buf[i++] = 0x00;
871 buf[i++] = 0x00;
872 buf[i++] = 0x83;
873 break;
656 } 874 }
657 reg_wb(gspca_dev, cmd, 0, buf, i); 875 reg_wb(gspca_dev, cmd, 0, buf, i);
658} 876}
@@ -688,8 +906,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
688 906
689 sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */ 907 sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */
690 908
909/*fixme: is this needed for icx098bp and mi0360?
691 if (sd->sensor != SENSOR_LZ24BP) 910 if (sd->sensor != SENSOR_LZ24BP)
692 reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000); 911 reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000);
912 */
693 913
694 reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8); 914 reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
695/* it returns: 915/* it returns:
@@ -706,7 +926,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
706 * 2: 06 / 07 / 12 = mode webcam? firmware?? 926 * 2: 06 / 07 / 12 = mode webcam? firmware??
707 * 3: 93 chip = 930b (930b or 930c) 927 * 3: 93 chip = 930b (930b or 930c)
708 * 4: 0b 928 * 4: 0b
709 * 5: f6 = cdd (icx098bq, lz24bp) / fe = cmos (i2c) (mi0360, ov9630) 929 * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors)
710 * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam? 930 * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
711 * 7: 00 931 * 7: 00
712 */ 932 */
@@ -720,14 +940,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
720 gspca_dev->usb_buf[6], 940 gspca_dev->usb_buf[6],
721 gspca_dev->usb_buf[7]); 941 gspca_dev->usb_buf[7]);
722 942
723/*fixme: no sensor probe - special case for icam tracer */ 943 bridge_init(sd);
724 if (gspca_dev->usb_buf[5] == 0xf6 944
725 && sd->sensor == SENSOR_MI0360) { 945 if (sd->sensor == SENSOR_MI0360) {
726 sd->sensor = SENSOR_ICX098BQ; 946
727 gspca_dev->cam.cam_mode = &vga_mode[1]; /* only 320x240 */ 947 /* no sensor probe for icam tracer */
728 gspca_dev->cam.nmodes = 1; 948 if (gspca_dev->usb_buf[5] == 0xf6) { /* if CMOS */
949 sd->sensor = SENSOR_ICX098BQ;
950 gspca_dev->cam.cam_mode = &vga_mode[1];
951 gspca_dev->cam.nmodes = 1; /* only 320x240 */
952 } else {
953 cmos_probe(gspca_dev);
954 }
729 } 955 }
730 956
957 PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
958
731 global_init(sd, 1); 959 global_init(sd, 1);
732 return gspca_dev->usb_err; 960 return gspca_dev->usb_err;
733} 961}
@@ -799,6 +1027,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
799 0x21); /* JPEG 422 */ 1027 0x21); /* JPEG 422 */
800 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality); 1028 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
801 1029
1030 bridge_init(sd);
802 global_init(sd, 0); 1031 global_init(sd, 0);
803 msleep(100); 1032 msleep(100);
804 1033
@@ -845,23 +1074,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
845 lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310); 1074 lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310);
846 msleep(10); 1075 msleep(10);
847 break; 1076 break;
848 default: 1077 case SENSOR_MI0360:
849/* case SENSOR_MI0360: */
850 ucbus_write(gspca_dev, mi0360_start_0, 1078 ucbus_write(gspca_dev, mi0360_start_0,
851 ARRAY_SIZE(mi0360_start_0), 1079 ARRAY_SIZE(mi0360_start_0),
852 8); 1080 8);
853 i2c_write(gspca_dev, mi0360_init_23, 1081 i2c_write(sd, mi0360_init_23,
854 ARRAY_SIZE(mi0360_init_23)); 1082 ARRAY_SIZE(mi0360_init_23));
855 i2c_write(gspca_dev, mi0360_init_24, 1083 i2c_write(sd, mi0360_init_24,
856 ARRAY_SIZE(mi0360_init_24)); 1084 ARRAY_SIZE(mi0360_init_24));
857 i2c_write(gspca_dev, mi0360_init_25, 1085 i2c_write(sd, mi0360_init_25,
858 ARRAY_SIZE(mi0360_init_25)); 1086 ARRAY_SIZE(mi0360_init_25));
859 ucbus_write(gspca_dev, mi0360_start_1, 1087 ucbus_write(gspca_dev, mi0360_start_1,
860 ARRAY_SIZE(mi0360_start_1), 1088 ARRAY_SIZE(mi0360_start_1),
861 5); 1089 5);
862 i2c_write(gspca_dev, mi0360_start_2, 1090 i2c_write(sd, mi0360_start_2,
863 ARRAY_SIZE(mi0360_start_2)); 1091 ARRAY_SIZE(mi0360_start_2));
864 i2c_write(gspca_dev, mi0360_start_3, 1092 i2c_write(sd, mi0360_start_3,
865 ARRAY_SIZE(mi0360_start_3)); 1093 ARRAY_SIZE(mi0360_start_3));
866 1094
867 /* 1st start */ 1095 /* 1st start */
@@ -869,9 +1097,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
869 msleep(60); 1097 msleep(60);
870 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000); 1098 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
871 1099
872 i2c_write(gspca_dev, 1100 i2c_write(sd,
873 mi0360_start_4, ARRAY_SIZE(mi0360_start_4)); 1101 mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
874 break; 1102 break;
1103 default:
1104/* case SENSOR_MT9V111: */
1105 ucbus_write(gspca_dev, mi0360_start_0,
1106 ARRAY_SIZE(mi0360_start_0),
1107 8);
1108 i2c_write(sd, mt9v111_init_0,
1109 ARRAY_SIZE(mt9v111_init_0));
1110 i2c_write(sd, mt9v111_init_1,
1111 ARRAY_SIZE(mt9v111_init_1));
1112 i2c_write(sd, mt9v111_init_2,
1113 ARRAY_SIZE(mt9v111_init_2));
1114 ucbus_write(gspca_dev, mt9v111_start_1,
1115 ARRAY_SIZE(mt9v111_start_1),
1116 8);
1117 i2c_write(sd, mt9v111_init_3,
1118 ARRAY_SIZE(mt9v111_init_3));
1119 i2c_write(sd, mt9v111_init_4,
1120 ARRAY_SIZE(mt9v111_init_4));
1121 break;
875 } 1122 }
876 1123
877 send_start(gspca_dev); 1124 send_start(gspca_dev);
@@ -880,6 +1127,9 @@ out:
880 1127
881 sd->eof_len = 0; /* init packet scan */ 1128 sd->eof_len = 0; /* init packet scan */
882 1129
1130 if (sd->sensor == SENSOR_MT9V111)
1131 gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
1132
883 sd->do_ctrl = 1; /* set the exposure */ 1133 sd->do_ctrl = 1; /* set the exposure */
884 1134
885 return gspca_dev->usb_err; 1135 return gspca_dev->usb_err;
@@ -887,6 +1137,10 @@ out:
887 1137
888static void sd_stopN(struct gspca_dev *gspca_dev) 1138static void sd_stopN(struct gspca_dev *gspca_dev)
889{ 1139{
1140 struct sd *sd = (struct sd *) gspca_dev;
1141
1142 if (sd->sensor == SENSOR_MT9V111)
1143 gpio_set(sd, 0, SQ930_GPIO_DFL_LED);
890 send_stop(gspca_dev); 1144 send_stop(gspca_dev);
891} 1145}
892 1146
@@ -1101,7 +1355,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1101 {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)}, 1355 {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
1102 {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)}, 1356 {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
1103 {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)}, 1357 {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
1104 {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)}, /* or ICX098BQ */ 1358 {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)},
1105 {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)}, 1359 {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
1106 {} 1360 {}
1107}; 1361};