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.c484
1 files changed, 129 insertions, 355 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index dbeebe8625c5..e18748c5a14d 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -24,9 +24,6 @@
24 24
25#include "gspca.h" 25#include "gspca.h"
26 26
27#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
28static const char version[] = "2.1.8";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 28MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
32MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
@@ -44,25 +41,29 @@ struct sd {
44 unsigned char brightness; 41 unsigned char brightness;
45 unsigned char autogain; 42 unsigned char autogain;
46 unsigned char autogain_ignore_frames; 43 unsigned char autogain_ignore_frames;
44 unsigned char frames_to_drop;
47 unsigned char freq; /* light freq filter setting */ 45 unsigned char freq; /* light freq filter setting */
48 unsigned char saturation;
49 unsigned char hue;
50 unsigned char contrast;
51 46
52 unsigned char fr_h_sz; /* size of frame header */ 47 unsigned char fr_h_sz; /* size of frame header */
53 char sensor; /* Type of image sensor chip */ 48 char sensor; /* Type of image sensor chip */
54#define SENSOR_HV7131R 0 49#define SENSOR_HV7131R 0
55#define SENSOR_OV6650 1 50#define SENSOR_OV6650 1
56#define SENSOR_OV7630 2 51#define SENSOR_OV7630 2
57#define SENSOR_OV7630_3 3 52#define SENSOR_PAS106 3
58#define SENSOR_PAS106 4 53#define SENSOR_PAS202 4
59#define SENSOR_PAS202 5 54#define SENSOR_TAS5110 5
60#define SENSOR_TAS5110 6 55#define SENSOR_TAS5130CXX 6
61#define SENSOR_TAS5130CXX 7
62 char sensor_has_gain; 56 char sensor_has_gain;
63 __u8 sensor_addr; 57 __u8 sensor_addr;
58 __u8 reg11;
64}; 59};
65 60
61/* flags used in the device id table */
62#define F_GAIN 0x01 /* has gain */
63#define F_AUTO 0x02 /* has autogain */
64#define F_SIF 0x04 /* sif or vga */
65#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */
66
66#define COMP2 0x8f 67#define COMP2 0x8f
67#define COMP 0xc7 /* 0x87 //0x07 */ 68#define COMP 0xc7 /* 0x87 //0x07 */
68#define COMP1 0xc9 /* 0x89 //0x09 */ 69#define COMP1 0xc9 /* 0x89 //0x09 */
@@ -92,12 +93,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 93static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 94static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 95static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
101 96
102static struct ctrl sd_ctrls[] = { 97static struct ctrl sd_ctrls[] = {
103 { 98 {
@@ -174,48 +169,6 @@ static struct ctrl sd_ctrls[] = {
174 .set = sd_setfreq, 169 .set = sd_setfreq,
175 .get = sd_getfreq, 170 .get = sd_getfreq,
176 }, 171 },
177 {
178 {
179 .id = V4L2_CID_SATURATION,
180 .type = V4L2_CTRL_TYPE_INTEGER,
181 .name = "Saturation",
182 .minimum = 0,
183 .maximum = 255,
184 .step = 1,
185#define SATURATION_DEF 127
186 .default_value = SATURATION_DEF,
187 },
188 .set = sd_setsaturation,
189 .get = sd_getsaturation,
190 },
191 {
192 {
193 .id = V4L2_CID_HUE,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Hue",
196 .minimum = 0,
197 .maximum = 255,
198 .step = 1,
199#define HUE_DEF 127
200 .default_value = HUE_DEF,
201 },
202 .set = sd_sethue,
203 .get = sd_gethue,
204 },
205 {
206 {
207 .id = V4L2_CID_CONTRAST,
208 .type = V4L2_CTRL_TYPE_INTEGER,
209 .name = "Contrast",
210 .minimum = 0,
211 .maximum = 255,
212 .step = 1,
213#define CONTRAST_DEF 127
214 .default_value = CONTRAST_DEF,
215 },
216 .set = sd_setcontrast,
217 .get = sd_getcontrast,
218 },
219}; 172};
220 173
221static struct v4l2_pix_format vga_mode[] = { 174static struct v4l2_pix_format vga_mode[] = {
@@ -248,8 +201,6 @@ static struct v4l2_pix_format sif_mode[] = {
248 .priv = 0}, 201 .priv = 0},
249}; 202};
250 203
251static const __u8 probe_ov7630[] = {0x08, 0x44};
252
253static const __u8 initHv7131[] = { 204static const __u8 initHv7131[] = {
254 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 205 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
255 0x00, 0x00, 206 0x00, 0x00,
@@ -321,7 +272,7 @@ static const __u8 initOv7630_3[] = {
321 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ 272 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
322 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ 273 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
323}; 274};
324static const __u8 ov7630_sensor_init_com[][8] = { 275static const __u8 ov7630_sensor_init[][8] = {
325 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, 276 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
326 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, 277 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
327/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ 278/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
@@ -342,17 +293,6 @@ static const __u8 ov7630_sensor_init_com[][8] = {
342 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, 293 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
343 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, 294 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
344}; 295};
345static const __u8 ov7630_sensor_init[][8] = {
346 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
347 {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
348 {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
349 {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
350 {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
351};
352static const __u8 ov7630_sensor_init_3[][8] = {
353 {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
354 {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
355};
356 296
357static const __u8 initPas106[] = { 297static const __u8 initPas106[] = {
358 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 298 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
@@ -542,7 +482,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
542 482
543 switch (sd->sensor) { 483 switch (sd->sensor) {
544 case SENSOR_OV6650: 484 case SENSOR_OV6650:
545 case SENSOR_OV7630_3:
546 case SENSOR_OV7630: { 485 case SENSOR_OV7630: {
547 __u8 i2cOV[] = 486 __u8 i2cOV[] =
548 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; 487 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
@@ -635,7 +574,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
635 case SENSOR_OV6650: 574 case SENSOR_OV6650:
636 gain >>= 1; 575 gain >>= 1;
637 /* fall thru */ 576 /* fall thru */
638 case SENSOR_OV7630_3: { 577 case SENSOR_OV7630: {
639 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 578 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
640 579
641 i2c[1] = sd->sensor_addr; 580 i2c[1] = sd->sensor_addr;
@@ -690,7 +629,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
690 break; 629 break;
691 } 630 }
692 case SENSOR_OV6650: 631 case SENSOR_OV6650:
693 case SENSOR_OV7630_3: { 632 case SENSOR_OV7630: {
694 /* The ov6650 / ov7630 have 2 registers which both influence 633 /* The ov6650 / ov7630 have 2 registers which both influence
695 exposure, register 11, whose low nibble sets the nr off fps 634 exposure, register 11, whose low nibble sets the nr off fps
696 according to: fps = 30 / (low_nibble + 1) 635 according to: fps = 30 / (low_nibble + 1)
@@ -705,16 +644,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
705 The code maps our 0 - 510 ms exposure ctrl to these 2 644 The code maps our 0 - 510 ms exposure ctrl to these 2
706 registers, trying to keep fps as high as possible. 645 registers, trying to keep fps as high as possible.
707 */ 646 */
708 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; 647 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
709 int reg10, reg11; 648 int reg10, reg11, reg10_max;
649
710 /* ov6645 datasheet says reg10_max is 9a, but that uses 650 /* ov6645 datasheet says reg10_max is 9a, but that uses
711 tline * 2 * reg10 as formula for calculating texpo, the 651 tline * 2 * reg10 as formula for calculating texpo, the
712 ov6650 probably uses the same formula as the 7730 which uses 652 ov6650 probably uses the same formula as the 7730 which uses
713 tline * 4 * reg10, which explains why the reg10max we've 653 tline * 4 * reg10, which explains why the reg10max we've
714 found experimentally for the ov6650 is exactly half that of 654 found experimentally for the ov6650 is exactly half that of
715 the ov6645. The ov7630 datasheet says the max is 0x41. */ 655 the ov6645. The ov7630 datasheet says the max is 0x41. */
716 const int reg10_max = (sd->sensor == SENSOR_OV6650) 656 if (sd->sensor == SENSOR_OV6650) {
717 ? 0x4d : 0x41; 657 reg10_max = 0x4d;
658 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
659 } else
660 reg10_max = 0x41;
718 661
719 reg11 = (60 * sd->exposure + 999) / 1000; 662 reg11 = (60 * sd->exposure + 999) / 1000;
720 if (reg11 < 1) 663 if (reg11 < 1)
@@ -735,20 +678,23 @@ static void setexposure(struct gspca_dev *gspca_dev)
735 else if (reg10 > reg10_max) 678 else if (reg10 > reg10_max)
736 reg10 = reg10_max; 679 reg10 = reg10_max;
737 680
681 /* In 640x480, if the reg11 has less than 3, the image is
682 unstable (not enough bandwidth). */
683 if (gspca_dev->width == 640 && reg11 < 3)
684 reg11 = 3;
685
738 /* Write reg 10 and reg11 low nibble */ 686 /* Write reg 10 and reg11 low nibble */
739 i2c[1] = sd->sensor_addr; 687 i2c[1] = sd->sensor_addr;
740 i2c[3] = reg10; 688 i2c[3] = reg10;
741 i2c[4] |= reg11 - 1; 689 i2c[4] |= reg11 - 1;
742 if (sd->sensor == SENSOR_OV7630_3) { 690
743 __u8 reg76 = reg10 & 0x03; 691 /* If register 11 didn't change, don't change it */
744 __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, 692 if (sd->reg11 == reg11 )
745 0x00, 0x00, 0x00, 0x10}; 693 i2c[0] = 0xa0;
746 reg10 >>= 2; 694
747 i2c_reg76[3] = reg76; 695 if (i2c_w(gspca_dev, i2c) == 0)
748 if (i2c_w(gspca_dev, i2c_reg76) < 0) 696 sd->reg11 = reg11;
749 PDEBUG(D_ERR, "i2c error exposure"); 697 else
750 }
751 if (i2c_w(gspca_dev, i2c) < 0)
752 PDEBUG(D_ERR, "i2c error exposure"); 698 PDEBUG(D_ERR, "i2c error exposure");
753 break; 699 break;
754 } 700 }
@@ -761,11 +707,11 @@ static void setfreq(struct gspca_dev *gspca_dev)
761 707
762 switch (sd->sensor) { 708 switch (sd->sensor) {
763 case SENSOR_OV6650: 709 case SENSOR_OV6650:
764 case SENSOR_OV7630_3: { 710 case SENSOR_OV7630: {
765 /* Framerate adjust register for artificial light 50 hz flicker 711 /* Framerate adjust register for artificial light 50 hz flicker
766 compensation, identical to ov6630 0x2b register, see ov6630 712 compensation, for the ov6650 this is identical to ov6630
767 datasheet. 713 0x2b register, see ov6630 datasheet.
768 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ 714 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
769 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; 715 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
770 switch (sd->freq) { 716 switch (sd->freq) {
771 default: 717 default:
@@ -786,69 +732,6 @@ static void setfreq(struct gspca_dev *gspca_dev)
786 } 732 }
787} 733}
788 734
789static void setsaturation(struct gspca_dev *gspca_dev)
790{
791 struct sd *sd = (struct sd *) gspca_dev;
792
793 switch (sd->sensor) {
794/* case SENSOR_OV6650: */
795 case SENSOR_OV7630_3:
796 case SENSOR_OV7630: {
797 __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
798 i2c[1] = sd->sensor_addr;
799 i2c[3] = sd->saturation & 0xf0;
800 if (i2c_w(gspca_dev, i2c) < 0)
801 PDEBUG(D_ERR, "i2c error setsaturation");
802 else
803 PDEBUG(D_CONF, "saturation set to: %d",
804 (int)sd->saturation);
805 break;
806 }
807 }
808}
809
810static void sethue(struct gspca_dev *gspca_dev)
811{
812 struct sd *sd = (struct sd *) gspca_dev;
813
814 switch (sd->sensor) {
815/* case SENSOR_OV6650: */
816 case SENSOR_OV7630_3:
817 case SENSOR_OV7630: {
818 __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
819 i2c[1] = sd->sensor_addr;
820 i2c[3] = 0x20 | (sd->hue >> 3);
821 if (i2c_w(gspca_dev, i2c) < 0)
822 PDEBUG(D_ERR, "i2c error setsaturation");
823 else
824 PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
825 break;
826 }
827 }
828}
829
830static void setcontrast(struct gspca_dev *gspca_dev)
831{
832 struct sd *sd = (struct sd *) gspca_dev;
833
834 switch (sd->sensor) {
835/* case SENSOR_OV6650: */
836 case SENSOR_OV7630_3:
837 case SENSOR_OV7630: {
838 __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
839 i2c[1] = sd->sensor_addr;
840 i2c[3] = 0x20 | (sd->contrast >> 3);
841 if (i2c_w(gspca_dev, i2c) < 0)
842 PDEBUG(D_ERR, "i2c error setcontrast");
843 else
844 PDEBUG(D_CONF, "contrast set to: %d",
845 (int)sd->contrast);
846 break;
847 }
848 }
849}
850
851
852static void do_autogain(struct gspca_dev *gspca_dev) 735static void do_autogain(struct gspca_dev *gspca_dev)
853{ 736{
854 struct sd *sd = (struct sd *) gspca_dev; 737 struct sd *sd = (struct sd *) gspca_dev;
@@ -874,88 +757,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
874{ 757{
875 struct sd *sd = (struct sd *) gspca_dev; 758 struct sd *sd = (struct sd *) gspca_dev;
876 struct cam *cam; 759 struct cam *cam;
877 __u16 product;
878 int sif = 0; 760 int sif = 0;
879 761
880 /* nctrls depends upon the sensor, so we use a per cam copy */ 762 /* nctrls depends upon the sensor, so we use a per cam copy */
881 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); 763 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
882 gspca_dev->sd_desc = &sd->sd_desc; 764 gspca_dev->sd_desc = &sd->sd_desc;
883 765
884 sd->fr_h_sz = 12; /* default size of the frame header */ 766 /* copy the webcam info from the device id */
885 sd->sd_desc.nctrls = 2; /* default nb of ctrls */ 767 sd->sensor = (id->driver_info >> 24) & 0xff;
886 sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ 768 if (id->driver_info & (F_GAIN << 16))
887 769 sd->sensor_has_gain = 1;
888 product = id->idProduct; 770 if (id->driver_info & (F_AUTO << 16))
889/* switch (id->idVendor) { */ 771 sd->sd_desc.dq_callback = do_autogain;
890/* case 0x0c45: * Sonix */ 772 if (id->driver_info & (F_SIF << 16))
891 switch (product) { 773 sif = 1;
892 case 0x6001: /* SN9C102 */ 774 if (id->driver_info & (F_H18 << 16))
893 case 0x6005: /* SN9C101 */ 775 sd->fr_h_sz = 18; /* size of frame header */
894 case 0x6007: /* SN9C101 */ 776 else
895 sd->sensor = SENSOR_TAS5110; 777 sd->fr_h_sz = 12;
896 sd->sensor_has_gain = 1; 778 sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
897 sd->sd_desc.nctrls = 4; 779 sd->sensor_addr = id->driver_info & 0xff;
898 sd->sd_desc.dq_callback = do_autogain;
899 sif = 1;
900 break;
901 case 0x6009: /* SN9C101 */
902 case 0x600d: /* SN9C101 */
903 case 0x6029: /* SN9C101 */
904 sd->sensor = SENSOR_PAS106;
905 sif = 1;
906 break;
907 case 0x6011: /* SN9C101 - SN9C101G */
908 sd->sensor = SENSOR_OV6650;
909 sd->sensor_has_gain = 1;
910 sd->sensor_addr = 0x60;
911 sd->sd_desc.nctrls = 5;
912 sd->sd_desc.dq_callback = do_autogain;
913 sif = 1;
914 break;
915 case 0x6019: /* SN9C101 */
916 case 0x602c: /* SN9C102 */
917 case 0x602e: /* SN9C102 */
918 sd->sensor = SENSOR_OV7630;
919 sd->sensor_addr = 0x21;
920 break;
921 case 0x60b0: /* SN9C103 */
922 sd->sensor = SENSOR_OV7630_3;
923 sd->sensor_addr = 0x21;
924 sd->fr_h_sz = 18; /* size of frame header */
925 sd->sensor_has_gain = 1;
926 sd->sd_desc.nctrls = 8;
927 sd->sd_desc.dq_callback = do_autogain;
928 sd->autogain = 0;
929 break;
930 case 0x6024: /* SN9C102 */
931 case 0x6025: /* SN9C102 */
932 sd->sensor = SENSOR_TAS5130CXX;
933 break;
934 case 0x6028: /* SN9C102 */
935 sd->sensor = SENSOR_PAS202;
936 break;
937 case 0x602d: /* SN9C102 */
938 sd->sensor = SENSOR_HV7131R;
939 break;
940 case 0x60af: /* SN9C103 */
941 sd->sensor = SENSOR_PAS202;
942 sd->fr_h_sz = 18; /* size of frame header (?) */
943 break;
944 }
945/* break; */
946/* } */
947 780
948 cam = &gspca_dev->cam; 781 cam = &gspca_dev->cam;
949 cam->dev_name = (char *) id->driver_info;
950 cam->epaddr = 0x01; 782 cam->epaddr = 0x01;
951 if (!sif) { 783 if (!sif) {
952 cam->cam_mode = vga_mode; 784 cam->cam_mode = vga_mode;
953 cam->nmodes = ARRAY_SIZE(vga_mode); 785 cam->nmodes = ARRAY_SIZE(vga_mode);
954 if (sd->sensor == SENSOR_OV7630_3) {
955 /* We only have 320x240 & 640x480 */
956 cam->cam_mode++;
957 cam->nmodes--;
958 }
959 } else { 786 } else {
960 cam->cam_mode = sif_mode; 787 cam->cam_mode = sif_mode;
961 cam->nmodes = ARRAY_SIZE(sif_mode); 788 cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -963,12 +790,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
963 sd->brightness = BRIGHTNESS_DEF; 790 sd->brightness = BRIGHTNESS_DEF;
964 sd->gain = GAIN_DEF; 791 sd->gain = GAIN_DEF;
965 sd->exposure = EXPOSURE_DEF; 792 sd->exposure = EXPOSURE_DEF;
793 sd->autogain = AUTOGAIN_DEF;
966 sd->freq = FREQ_DEF; 794 sd->freq = FREQ_DEF;
967 sd->contrast = CONTRAST_DEF; 795
968 sd->saturation = SATURATION_DEF;
969 sd->hue = HUE_DEF;
970 if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
971 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
972 return 0; 796 return 0;
973} 797}
974 798
@@ -1002,9 +826,8 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev)
1002static void sd_start(struct gspca_dev *gspca_dev) 826static void sd_start(struct gspca_dev *gspca_dev)
1003{ 827{
1004 struct sd *sd = (struct sd *) gspca_dev; 828 struct sd *sd = (struct sd *) gspca_dev;
1005 int mode, l; 829 int mode, l = 0x1f;
1006 const __u8 *sn9c10x; 830 const __u8 *sn9c10x;
1007 __u8 reg01, reg17;
1008 __u8 reg17_19[3]; 831 __u8 reg17_19[3];
1009 832
1010 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 833 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -1022,13 +845,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
1022 reg17_19[2] = 0x20; 845 reg17_19[2] = 0x20;
1023 break; 846 break;
1024 case SENSOR_OV7630: 847 case SENSOR_OV7630:
1025 sn9c10x = initOv7630; 848 if (sd->fr_h_sz == 18) { /* SN9C103 */
1026 reg17_19[0] = 0x68; 849 sn9c10x = initOv7630_3;
1027 reg17_19[1] = (mode << 4) | COMP2; 850 l = sizeof initOv7630_3;
1028 reg17_19[2] = MCK_INIT1; 851 } else
1029 break; 852 sn9c10x = initOv7630;
1030 case SENSOR_OV7630_3:
1031 sn9c10x = initOv7630_3;
1032 reg17_19[0] = 0x68; 853 reg17_19[0] = 0x68;
1033 reg17_19[1] = (mode << 4) | COMP2; 854 reg17_19[1] = (mode << 4) | COMP2;
1034 reg17_19[2] = MCK_INIT1; 855 reg17_19[2] = MCK_INIT1;
@@ -1059,30 +880,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
1059 reg17_19[2] = mode ? 0x23 : 0x43; 880 reg17_19[2] = mode ? 0x23 : 0x43;
1060 break; 881 break;
1061 } 882 }
1062 switch (sd->sensor) {
1063 case SENSOR_OV7630:
1064 reg01 = 0x06;
1065 reg17 = 0x29;
1066 l = sizeof initOv7630;
1067 break;
1068 case SENSOR_OV7630_3:
1069 reg01 = 0x44;
1070 reg17 = 0x68;
1071 l = sizeof initOv7630_3;
1072 break;
1073 default:
1074 reg01 = sn9c10x[0];
1075 reg17 = sn9c10x[0x17 - 1];
1076 l = 0x1f;
1077 break;
1078 }
1079 883
1080 /* reg 0x01 bit 2 video transfert on */ 884 /* reg 0x01 bit 2 video transfert on */
1081 reg_w(gspca_dev, 0x01, &reg01, 1); 885 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
1082 /* reg 0x17 SensorClk enable inv Clk 0x60 */ 886 /* reg 0x17 SensorClk enable inv Clk 0x60 */
1083 reg_w(gspca_dev, 0x17, &reg17, 1); 887 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
1084/*fixme: for ov7630 102
1085 reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
1086 /* Set the registers from the template */ 888 /* Set the registers from the template */
1087 reg_w_big(gspca_dev, 0x01, sn9c10x, l); 889 reg_w_big(gspca_dev, 0x01, sn9c10x, l);
1088 switch (sd->sensor) { 890 switch (sd->sensor) {
@@ -1095,17 +897,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
1095 sizeof ov6650_sensor_init); 897 sizeof ov6650_sensor_init);
1096 break; 898 break;
1097 case SENSOR_OV7630: 899 case SENSOR_OV7630:
1098 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
1099 sizeof ov7630_sensor_init_com);
1100 msleep(200);
1101 i2c_w_vector(gspca_dev, ov7630_sensor_init, 900 i2c_w_vector(gspca_dev, ov7630_sensor_init,
1102 sizeof ov7630_sensor_init); 901 sizeof ov7630_sensor_init);
1103 break; 902 if (sd->fr_h_sz == 18) { /* SN9C103 */
1104 case SENSOR_OV7630_3: 903 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
1105 i2c_w_vector(gspca_dev, ov7630_sensor_init_com, 904 0x00, 0x00, 0x10 };
1106 sizeof ov7630_sensor_init_com); 905 i2c_w(gspca_dev, i2c);
1107 msleep(200); 906 }
1108 i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
1109 break; 907 break;
1110 case SENSOR_PAS106: 908 case SENSOR_PAS106:
1111 pas106_i2cinit(gspca_dev); 909 pas106_i2cinit(gspca_dev);
@@ -1145,14 +943,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
1145 reg_w(gspca_dev, 0x18, &reg17_19[1], 2); 943 reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
1146 msleep(20); 944 msleep(20);
1147 945
946 sd->reg11 = -1;
947
1148 setgain(gspca_dev); 948 setgain(gspca_dev);
1149 setbrightness(gspca_dev); 949 setbrightness(gspca_dev);
1150 setexposure(gspca_dev); 950 setexposure(gspca_dev);
1151 setfreq(gspca_dev); 951 setfreq(gspca_dev);
1152 setsaturation(gspca_dev);
1153 sethue(gspca_dev);
1154 setcontrast(gspca_dev);
1155 952
953 sd->frames_to_drop = 0;
1156 sd->autogain_ignore_frames = 0; 954 sd->autogain_ignore_frames = 0;
1157 atomic_set(&sd->avg_lum, -1); 955 atomic_set(&sd->avg_lum, -1);
1158} 956}
@@ -1198,21 +996,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1198 && data[3 + i] == 0xc4 996 && data[3 + i] == 0xc4
1199 && data[4 + i] == 0xc4 997 && data[4 + i] == 0xc4
1200 && data[5 + i] == 0x96) { /* start of frame */ 998 && data[5 + i] == 0x96) { /* start of frame */
1201 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 999 int lum = -1;
1202 frame, data, 0); 1000 int pkt_type = LAST_PACKET;
1001
1203 if (len - i < sd->fr_h_sz) { 1002 if (len - i < sd->fr_h_sz) {
1204 atomic_set(&sd->avg_lum, -1);
1205 PDEBUG(D_STREAM, "packet too short to" 1003 PDEBUG(D_STREAM, "packet too short to"
1206 " get avg brightness"); 1004 " get avg brightness");
1207 } else if (sd->fr_h_sz == 12) { 1005 } else if (sd->fr_h_sz == 12) {
1208 atomic_set(&sd->avg_lum, 1006 lum = data[i + 8] + (data[i + 9] << 8);
1209 data[i + 8] +
1210 (data[i + 9] << 8));
1211 } else { 1007 } else {
1212 atomic_set(&sd->avg_lum, 1008 lum = data[i + 9] +
1213 data[i + 9] + 1009 (data[i + 10] << 8);
1214 (data[i + 10] << 8)); 1010 }
1011 if (lum == 0) {
1012 lum = -1;
1013 sd->frames_to_drop = 2;
1014 }
1015 atomic_set(&sd->avg_lum, lum);
1016
1017 if (sd->frames_to_drop) {
1018 sd->frames_to_drop--;
1019 pkt_type = DISCARD_PACKET;
1215 } 1020 }
1021
1022 frame = gspca_frame_add(gspca_dev, pkt_type,
1023 frame, data, 0);
1216 data += i + sd->fr_h_sz; 1024 data += i + sd->fr_h_sz;
1217 len -= i + sd->fr_h_sz; 1025 len -= i + sd->fr_h_sz;
1218 gspca_frame_add(gspca_dev, FIRST_PACKET, 1026 gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -1327,60 +1135,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1327 return 0; 1135 return 0;
1328} 1136}
1329 1137
1330static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1331{
1332 struct sd *sd = (struct sd *) gspca_dev;
1333
1334 sd->saturation = val;
1335 if (gspca_dev->streaming)
1336 setsaturation(gspca_dev);
1337 return 0;
1338}
1339
1340static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1341{
1342 struct sd *sd = (struct sd *) gspca_dev;
1343
1344 *val = sd->saturation;
1345 return 0;
1346}
1347
1348static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
1349{
1350 struct sd *sd = (struct sd *) gspca_dev;
1351
1352 sd->hue = val;
1353 if (gspca_dev->streaming)
1354 sethue(gspca_dev);
1355 return 0;
1356}
1357
1358static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
1359{
1360 struct sd *sd = (struct sd *) gspca_dev;
1361
1362 *val = sd->hue;
1363 return 0;
1364}
1365
1366static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1367{
1368 struct sd *sd = (struct sd *) gspca_dev;
1369
1370 sd->contrast = val;
1371 if (gspca_dev->streaming)
1372 setcontrast(gspca_dev);
1373 return 0;
1374}
1375
1376static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1377{
1378 struct sd *sd = (struct sd *) gspca_dev;
1379
1380 *val = sd->contrast;
1381 return 0;
1382}
1383
1384static int sd_querymenu(struct gspca_dev *gspca_dev, 1138static int sd_querymenu(struct gspca_dev *gspca_dev,
1385 struct v4l2_querymenu *menu) 1139 struct v4l2_querymenu *menu)
1386{ 1140{
@@ -1418,27 +1172,47 @@ static const struct sd_desc sd_desc = {
1418}; 1172};
1419 1173
1420/* -- module initialisation -- */ 1174/* -- module initialisation -- */
1421#define DVNM(name) .driver_info = (kernel_ulong_t) name 1175#define SFCI(sensor, flags, nctrls, i2c_addr) \
1176 .driver_info = (SENSOR_ ## sensor << 24) \
1177 | ((flags) << 16) \
1178 | ((nctrls) << 8) \
1179 | (i2c_addr)
1422static __devinitdata struct usb_device_id device_table[] = { 1180static __devinitdata struct usb_device_id device_table[] = {
1423#ifndef CONFIG_USB_SN9C102 1181#ifndef CONFIG_USB_SN9C102
1424 {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, 1182 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */
1425 {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, 1183 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1426 {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, 1184 {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */
1427 {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, 1185 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1428 {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, 1186 {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */
1187 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1188 {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
1189 SFCI(PAS106, F_SIF, 2, 0)},
1190 {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
1191 SFCI(PAS106, F_SIF, 2, 0)},
1429#endif 1192#endif
1430 {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, 1193 {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */
1194 SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
1431#ifndef CONFIG_USB_SN9C102 1195#ifndef CONFIG_USB_SN9C102
1432 {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, 1196 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */
1433 {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, 1197 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1434 {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, 1198 {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */
1435 {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, 1199 SFCI(TAS5130CXX, 0, 2, 0)},
1436 {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, 1200 {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */
1437 {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, 1201 SFCI(TAS5130CXX, 0, 2, 0)},
1438 {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, 1202 {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
1439 {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, 1203 SFCI(PAS202, 0, 2, 0)},
1440 {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, 1204 {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
1441 {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, 1205 SFCI(PAS106, F_SIF, 2, 0)},
1206 {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
1207 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1208 {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
1209 SFCI(HV7131R, 0, 2, 0)},
1210 {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
1211 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1212 {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
1213 SFCI(PAS202, F_H18, 2, 0)},
1214 {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
1215 SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
1442#endif 1216#endif
1443 {} 1217 {}
1444}; 1218};
@@ -1464,7 +1238,7 @@ static int __init sd_mod_init(void)
1464{ 1238{
1465 if (usb_register(&sd_driver) < 0) 1239 if (usb_register(&sd_driver) < 0)
1466 return -1; 1240 return -1;
1467 PDEBUG(D_PROBE, "v%s registered", version); 1241 PDEBUG(D_PROBE, "registered");
1468 return 0; 1242 return 0;
1469} 1243}
1470static void __exit sd_mod_exit(void) 1244static void __exit sd_mod_exit(void)