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.c508
1 files changed, 306 insertions, 202 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 53cb82d9e7c6..3373b8d9d2a8 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,6 +24,8 @@
24#include "gspca.h" 24#include "gspca.h"
25#include "jpeg.h" 25#include "jpeg.h"
26 26
27#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -35,23 +37,26 @@ struct sd {
35 atomic_t avg_lum; 37 atomic_t avg_lum;
36 unsigned int exposure; 38 unsigned int exposure;
37 39
38 unsigned short brightness; 40 __u16 brightness;
39 unsigned char contrast; 41 __u8 contrast;
40 unsigned char colors; 42 __u8 colors;
41 unsigned char autogain; 43 __u8 autogain;
44 __u8 blue;
45 __u8 red;
42 __u8 vflip; /* ov7630 only */ 46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
43 48
44 signed char ag_cnt; 49 __s8 ag_cnt;
45#define AG_CNT_START 13 50#define AG_CNT_START 13
46 51
47 char qindex; 52 __u8 qindex;
48 unsigned char bridge; 53 __u8 bridge;
49#define BRIDGE_SN9C102P 0 54#define BRIDGE_SN9C102P 0
50#define BRIDGE_SN9C105 1 55#define BRIDGE_SN9C105 1
51#define BRIDGE_SN9C110 2 56#define BRIDGE_SN9C110 2
52#define BRIDGE_SN9C120 3 57#define BRIDGE_SN9C120 3
53#define BRIDGE_SN9C325 4 58#define BRIDGE_SN9C325 4
54 char sensor; /* Type of image sensor chip */ 59 __u8 sensor; /* Type of image sensor chip */
55#define SENSOR_HV7131R 0 60#define SENSOR_HV7131R 0
56#define SENSOR_MI0360 1 61#define SENSOR_MI0360 1
57#define SENSOR_MO4000 2 62#define SENSOR_MO4000 2
@@ -59,7 +64,7 @@ struct sd {
59#define SENSOR_OV7630 4 64#define SENSOR_OV7630 4
60#define SENSOR_OV7648 5 65#define SENSOR_OV7648 5
61#define SENSOR_OV7660 6 66#define SENSOR_OV7660 6
62 unsigned char i2c_base; 67 __u8 i2c_base;
63}; 68};
64 69
65/* V4L2 controls supported by the driver */ 70/* V4L2 controls supported by the driver */
@@ -69,10 +74,16 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 81static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 82static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
76 87
77static struct ctrl sd_ctrls[] = { 88static struct ctrl sd_ctrls[] = {
78 { 89 {
@@ -84,7 +95,7 @@ static struct ctrl sd_ctrls[] = {
84#define BRIGHTNESS_MAX 0xffff 95#define BRIGHTNESS_MAX 0xffff
85 .maximum = BRIGHTNESS_MAX, 96 .maximum = BRIGHTNESS_MAX,
86 .step = 1, 97 .step = 1,
87#define BRIGHTNESS_DEF 0x7fff 98#define BRIGHTNESS_DEF 0x8000
88 .default_value = BRIGHTNESS_DEF, 99 .default_value = BRIGHTNESS_DEF,
89 }, 100 },
90 .set = sd_setbrightness, 101 .set = sd_setbrightness,
@@ -111,7 +122,7 @@ static struct ctrl sd_ctrls[] = {
111 .type = V4L2_CTRL_TYPE_INTEGER, 122 .type = V4L2_CTRL_TYPE_INTEGER,
112 .name = "Color", 123 .name = "Color",
113 .minimum = 0, 124 .minimum = 0,
114 .maximum = 64, 125 .maximum = 40,
115 .step = 1, 126 .step = 1,
116#define COLOR_DEF 32 127#define COLOR_DEF 32
117 .default_value = COLOR_DEF, 128 .default_value = COLOR_DEF,
@@ -119,7 +130,35 @@ static struct ctrl sd_ctrls[] = {
119 .set = sd_setcolors, 130 .set = sd_setcolors,
120 .get = sd_getcolors, 131 .get = sd_getcolors,
121 }, 132 },
122#define AUTOGAIN_IDX 3 133 {
134 {
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141#define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155#define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161#define AUTOGAIN_IDX 5
123 { 162 {
124 { 163 {
125 .id = V4L2_CID_AUTOGAIN, 164 .id = V4L2_CID_AUTOGAIN,
@@ -135,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
135 .get = sd_getautogain, 174 .get = sd_getautogain,
136 }, 175 },
137/* ov7630 only */ 176/* ov7630 only */
138#define VFLIP_IDX 4 177#define VFLIP_IDX 6
139 { 178 {
140 { 179 {
141 .id = V4L2_CID_VFLIP, 180 .id = V4L2_CID_VFLIP,
@@ -150,9 +189,43 @@ static struct ctrl sd_ctrls[] = {
150 .set = sd_setvflip, 189 .set = sd_setvflip,
151 .get = sd_getvflip, 190 .get = sd_getvflip,
152 }, 191 },
192/* mi0360 only */
193#define INFRARED_IDX 7
194 {
195 {
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202#define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
208};
209
210/* table of the disabled controls */
211static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
214 (1 << VFLIP_IDX),
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
153}; 226};
154 227
155static struct v4l2_pix_format vga_mode[] = { 228static const struct v4l2_pix_format vga_mode[] = {
156 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157 .bytesperline = 160, 230 .bytesperline = 160,
158 .sizeimage = 160 * 120 * 4 / 8 + 590, 231 .sizeimage = 160 * 120 * 4 / 8 + 590,
@@ -231,13 +304,13 @@ static const __u8 sn_ov7630[] = {
231 304
232static const __u8 sn_ov7648[] = { 305static const __u8 sn_ov7648[] = {
233/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 306/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
234 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
235/* reg8 reg9 rega regb regc regd rege regf */ 308/* reg8 reg9 rega regb regc regd rege regf */
236 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, 309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
237/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 310/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
238 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, 311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
239/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ 312/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
240 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
241}; 314};
242 315
243static const __u8 sn_ov7660[] = { 316static const __u8 sn_ov7660[] = {
@@ -469,6 +542,53 @@ static const __u8 ov7630_sensor_init[][8] = {
469/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ 542/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
470 {} 543 {}
471}; 544};
545
546static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
568
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
573/*...*/
574/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
581/*...*/
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
588
589 {}
590};
591
472static const __u8 ov7660_sensor_init[][8] = { 592static const __u8 ov7660_sensor_init[][8] = {
473 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
474/* (delay 20ms) */ 594/* (delay 20ms) */
@@ -557,64 +677,6 @@ static const __u8 ov7660_sensor_init[][8] = {
557 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, 677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
558 {} 678 {}
559}; 679};
560/* reg 0x04 reg 0x07 reg 0x10 */
561/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
562
563static const __u8 ov7648_sensor_init[][8] = {
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
566 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
567 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
568 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
569 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
571 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
572 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
573 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
574 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
575 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
578 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
579 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
580 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
581 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
582 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
583 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
584 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
585 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
587 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
588 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
589 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
590 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
591 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
593 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
594 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
595 * This is currently setting a
596 * blue tint, and some things more , i leave it here for future test if
597 * somene is having problems with color on this sensor
598 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
601 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
602 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
604 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
609 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
611 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
612 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
613 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
614 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
615/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
616 {}
617};
618 680
619static const __u8 qtable4[] = { 681static const __u8 qtable4[] = {
620 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, 682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
@@ -757,8 +819,6 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
757 819
758static int probesensor(struct gspca_dev *gspca_dev) 820static int probesensor(struct gspca_dev *gspca_dev)
759{ 821{
760 struct sd *sd = (struct sd *) gspca_dev;
761
762 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ 822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
763 msleep(10); 823 msleep(10);
764 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ 824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
@@ -770,8 +830,7 @@ static int probesensor(struct gspca_dev *gspca_dev)
770 && gspca_dev->usb_buf[3] == 0x00 830 && gspca_dev->usb_buf[3] == 0x00
771 && gspca_dev->usb_buf[4] == 0x00) { 831 && gspca_dev->usb_buf[4] == 0x00) {
772 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); 832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
773 sd->sensor = SENSOR_HV7131R; 833 return 0;
774 return SENSOR_HV7131R;
775 } 834 }
776 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", 835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
777 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], 836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
@@ -827,17 +886,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
827 reg_w1(gspca_dev, 0x01, 0x40); 886 reg_w1(gspca_dev, 0x01, 0x40);
828 break; 887 break;
829 case SENSOR_OV7648: 888 case SENSOR_OV7648:
830 reg_w1(gspca_dev, 0x01, 0x43); 889 reg_w1(gspca_dev, 0x01, 0x63);
831 reg_w1(gspca_dev, 0x17, 0xae); 890 reg_w1(gspca_dev, 0x17, 0x20);
832 reg_w1(gspca_dev, 0x01, 0x42); 891 reg_w1(gspca_dev, 0x01, 0x42);
833 break; 892 break;
834/*jfm: from win trace */ 893/*jfm: from win trace */
835 case SENSOR_OV7660: 894 case SENSOR_OV7660:
836 reg_w1(gspca_dev, 0x01, 0x61); 895 if (sd->bridge == BRIDGE_SN9C120) {
837 reg_w1(gspca_dev, 0x17, 0x20); 896 reg_w1(gspca_dev, 0x01, 0x61);
838 reg_w1(gspca_dev, 0x01, 0x60); 897 reg_w1(gspca_dev, 0x17, 0x20);
839 reg_w1(gspca_dev, 0x01, 0x40); 898 reg_w1(gspca_dev, 0x01, 0x60);
840 break; 899 reg_w1(gspca_dev, 0x01, 0x40);
900 break;
901 }
902 /* fall thru */
841 default: 903 default:
842 reg_w1(gspca_dev, 0x01, 0x43); 904 reg_w1(gspca_dev, 0x01, 0x43);
843 reg_w1(gspca_dev, 0x17, 0x61); 905 reg_w1(gspca_dev, 0x17, 0x61);
@@ -922,6 +984,13 @@ static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
922{ 984{
923 int i = 0; 985 int i = 0;
924 986
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
988 i++;
989/* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
991 i++;
992 msleep(20);
993/* win: i2c reg read 00..7f */
925 while (ov7648_sensor_init[i][0]) { 994 while (ov7648_sensor_init[i][0]) {
926 i2c_w8(gspca_dev, ov7648_sensor_init[i]); 995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
927 i++; 996 i++;
@@ -961,19 +1030,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
961 sd->brightness = BRIGHTNESS_DEF; 1030 sd->brightness = BRIGHTNESS_DEF;
962 sd->contrast = CONTRAST_DEF; 1031 sd->contrast = CONTRAST_DEF;
963 sd->colors = COLOR_DEF; 1032 sd->colors = COLOR_DEF;
1033 sd->blue = BLUE_BALANCE_DEF;
1034 sd->red = RED_BALANCE_DEF;
964 sd->autogain = AUTOGAIN_DEF; 1035 sd->autogain = AUTOGAIN_DEF;
965 sd->ag_cnt = -1; 1036 sd->ag_cnt = -1;
1037 sd->vflip = VFLIP_DEF;
1038 sd->infrared = INFRARED_DEF;
966 1039
967 switch (sd->sensor) { 1040 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
968 case SENSOR_OV7630:
969 case SENSOR_OV7648:
970 case SENSOR_OV7660:
971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
972 break;
973 }
974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
976
977 return 0; 1041 return 0;
978} 1042}
979 1043
@@ -981,7 +1045,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
981static int sd_init(struct gspca_dev *gspca_dev) 1045static int sd_init(struct gspca_dev *gspca_dev)
982{ 1046{
983 struct sd *sd = (struct sd *) gspca_dev; 1047 struct sd *sd = (struct sd *) gspca_dev;
984/* const __u8 *sn9c1xx; */
985 __u8 regGpio[] = { 0x29, 0x74 }; 1048 __u8 regGpio[] = { 0x29, 0x74 };
986 __u8 regF1; 1049 __u8 regF1;
987 1050
@@ -1100,32 +1163,13 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
1100 return expo; 1163 return expo;
1101} 1164}
1102 1165
1103/* this function is used for sensors o76xx only */
1104static void setbrightcont(struct gspca_dev *gspca_dev)
1105{
1106 struct sd *sd = (struct sd *) gspca_dev;
1107 int val;
1108 __u8 reg84_full[0x15];
1109
1110 memcpy(reg84_full, reg84, sizeof reg84_full);
1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1112 reg84_full[0] = (val + 1) / 2; /* red */
1113 reg84_full[2] = val; /* green */
1114 reg84_full[4] = (val + 1) / 5; /* blue */
1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1116 / BRIGHTNESS_MAX;
1117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1119}
1120
1121/* sensor != ov76xx */
1122static void setbrightness(struct gspca_dev *gspca_dev) 1166static void setbrightness(struct gspca_dev *gspca_dev)
1123{ 1167{
1124 struct sd *sd = (struct sd *) gspca_dev; 1168 struct sd *sd = (struct sd *) gspca_dev;
1125 unsigned int expo; 1169 unsigned int expo;
1126 __u8 k2; 1170 __u8 k2;
1127 1171
1128 k2 = sd->brightness >> 10; 1172 k2 = ((int) sd->brightness - 0x8000) >> 10;
1129 switch (sd->sensor) { 1173 switch (sd->sensor) {
1130 case SENSOR_HV7131R: 1174 case SENSOR_HV7131R:
1131 expo = sd->brightness << 4; 1175 expo = sd->brightness << 4;
@@ -1147,38 +1191,49 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1147 break; 1191 break;
1148 } 1192 }
1149 1193
1150 reg_w1(gspca_dev, 0x96, k2); 1194 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1151} 1195}
1152 1196
1153/* sensor != ov76xx */
1154static void setcontrast(struct gspca_dev *gspca_dev) 1197static void setcontrast(struct gspca_dev *gspca_dev)
1155{ 1198{
1156 struct sd *sd = (struct sd *) gspca_dev; 1199 struct sd *sd = (struct sd *) gspca_dev;
1157 __u8 k2; 1200 __u8 k2;
1158 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; 1201 __u8 contrast[6];
1159 1202
1160 k2 = sd->contrast; 1203 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1161 contrast[2] = k2; 1204 contrast[0] = (k2 + 1) / 2; /* red */
1162 contrast[0] = (k2 + 1) >> 1; 1205 contrast[1] = 0;
1163 contrast[4] = (k2 + 1) / 5; 1206 contrast[2] = k2; /* green */
1164 reg_w(gspca_dev, 0x84, contrast, 6); 1207 contrast[3] = 0;
1208 contrast[4] = (k2 + 1) / 5; /* blue */
1209 contrast[5] = 0;
1210 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1165} 1211}
1166 1212
1167static void setcolors(struct gspca_dev *gspca_dev) 1213static void setcolors(struct gspca_dev *gspca_dev)
1168{ 1214{
1169 struct sd *sd = (struct sd *) gspca_dev; 1215 struct sd *sd = (struct sd *) gspca_dev;
1170 __u8 blue, red; 1216 int i, v;
1171 1217 __u8 reg8a[12]; /* U & V gains */
1172 if (sd->colors >= 32) { 1218 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1173 red = 32 + (sd->colors - 32) / 2; 1219 -24, -38, 64, /* UR UG UB */
1174 blue = 64 - sd->colors; 1220 62, -51, -9 /* VR VG VB */
1175 } else { 1221 };
1176 red = sd->colors; 1222 for (i = 0; i < 6; i++) {
1177 blue = 32 + (32 - sd->colors) / 2; 1223 v = uv[i] * sd->colors / COLOR_DEF;
1224 reg8a[i * 2] = v;
1225 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1178 } 1226 }
1179 reg_w1(gspca_dev, 0x05, red); 1227 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1228}
1229
1230static void setredblue(struct gspca_dev *gspca_dev)
1231{
1232 struct sd *sd = (struct sd *) gspca_dev;
1233
1234 reg_w1(gspca_dev, 0x05, sd->red);
1180/* reg_w1(gspca_dev, 0x07, 32); */ 1235/* reg_w1(gspca_dev, 0x07, 32); */
1181 reg_w1(gspca_dev, 0x06, blue); 1236 reg_w1(gspca_dev, 0x06, sd->blue);
1182} 1237}
1183 1238
1184static void setautogain(struct gspca_dev *gspca_dev) 1239static void setautogain(struct gspca_dev *gspca_dev)
@@ -1195,12 +1250,18 @@ static void setautogain(struct gspca_dev *gspca_dev)
1195 1250
1196static void setvflip(struct sd *sd) 1251static void setvflip(struct sd *sd)
1197{ 1252{
1198 if (sd->sensor != SENSOR_OV7630)
1199 return;
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ 1253 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02); 1254 sd->vflip ? 0x82 : 0x02);
1202} 1255}
1203 1256
1257static void setinfrared(struct sd *sd)
1258{
1259/*fixme: different sequence for StarCam Clip and StarCam 370i */
1260/* Clip */
1261 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1262 sd->infrared ? 0x66 : 0x64);
1263}
1264
1204/* -- start the camera -- */ 1265/* -- start the camera -- */
1205static int sd_start(struct gspca_dev *gspca_dev) 1266static int sd_start(struct gspca_dev *gspca_dev)
1206{ 1267{
@@ -1235,28 +1296,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
1235 reg17 = 0xe2; 1296 reg17 = 0xe2;
1236 break; 1297 break;
1237 case SENSOR_OV7648: 1298 case SENSOR_OV7648:
1238 reg17 = 0xae; 1299 reg17 = 0x20;
1239 break; 1300 break;
1240/*jfm: from win trace */ 1301/*jfm: from win trace */
1241 case SENSOR_OV7660: 1302 case SENSOR_OV7660:
1242 reg17 = 0xa0; 1303 if (sd->bridge == BRIDGE_SN9C120) {
1243 break; 1304 reg17 = 0xa0;
1305 break;
1306 }
1307 /* fall thru */
1244 default: 1308 default:
1245 reg17 = 0x60; 1309 reg17 = 0x60;
1246 break; 1310 break;
1247 } 1311 }
1248 reg_w1(gspca_dev, 0x17, reg17); 1312 reg_w1(gspca_dev, 0x17, reg17);
1249 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); 1313/* set reg1 was here */
1250 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1314 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1251 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1315 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1316 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1252 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1317 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1253 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); 1318 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1254 for (i = 0; i < 8; i++) 1319 for (i = 0; i < 8; i++)
1255 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 1320 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1256 switch (sd->sensor) { 1321 switch (sd->sensor) {
1257 case SENSOR_OV7660: 1322 case SENSOR_OV7648:
1258 reg_w1(gspca_dev, 0x9a, 0x05); 1323 reg_w1(gspca_dev, 0x9a, 0x0a);
1324 reg_w1(gspca_dev, 0x99, 0x60);
1259 break; 1325 break;
1326 case SENSOR_OV7660:
1327 if (sd->bridge == BRIDGE_SN9C120) {
1328 reg_w1(gspca_dev, 0x9a, 0x05);
1329 break;
1330 }
1331 /* fall thru */
1260 default: 1332 default:
1261 reg_w1(gspca_dev, 0x9a, 0x08); 1333 reg_w1(gspca_dev, 0x9a, 0x08);
1262 reg_w1(gspca_dev, 0x99, 0x59); 1334 reg_w1(gspca_dev, 0x99, 0x59);
@@ -1265,10 +1337,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
1265 1337
1266 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1338 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1267 if (mode) 1339 if (mode)
1268 reg1 = 0x46; /* 320 clk 48Mhz */ 1340 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1269 else 1341 else
1270 reg1 = 0x06; /* 640 clk 24Mz */ 1342 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1271 reg17 = 0x61; 1343 reg17 = 0x61; /* 0x:20: enable sensor clock */
1272 switch (sd->sensor) { 1344 switch (sd->sensor) {
1273 case SENSOR_HV7131R: 1345 case SENSOR_HV7131R:
1274 hv7131R_InitSensor(gspca_dev); 1346 hv7131R_InitSensor(gspca_dev);
@@ -1298,23 +1370,21 @@ static int sd_start(struct gspca_dev *gspca_dev)
1298 break; 1370 break;
1299 case SENSOR_OV7648: 1371 case SENSOR_OV7648:
1300 ov7648_InitSensor(gspca_dev); 1372 ov7648_InitSensor(gspca_dev);
1301 reg17 = 0xa2; 1373 reg17 = 0x21;
1302 reg1 = 0x44; 1374/* reg1 = 0x42; * 42 - 46? */
1303/* if (mode)
1304 ; * 320x2...
1305 else
1306 ; * 640x... */
1307 break; 1375 break;
1308 default: 1376 default:
1309/* case SENSOR_OV7660: */ 1377/* case SENSOR_OV7660: */
1310 ov7660_InitSensor(gspca_dev); 1378 ov7660_InitSensor(gspca_dev);
1311 if (mode) { 1379 if (sd->bridge == BRIDGE_SN9C120) {
1312/* reg17 = 0x21; * 320 */ 1380 if (mode) { /* 320x240 - 160x120 */
1313/* reg1 = 0x44; */ 1381 reg17 = 0xa2;
1314/* reg1 = 0x46; (done) */ 1382 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1383 }
1315 } else { 1384 } else {
1316 reg17 = 0xa2; /* 640 */ 1385 reg17 = 0x22;
1317 reg1 = 0x44; 1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1318 } 1388 }
1319 break; 1389 break;
1320 } 1390 }
@@ -1342,23 +1412,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
1342 reg_w1(gspca_dev, 0x18, reg18); 1412 reg_w1(gspca_dev, 0x18, reg18);
1343 1413
1344 reg_w1(gspca_dev, 0x17, reg17); 1414 reg_w1(gspca_dev, 0x17, reg17);
1415 reg_w1(gspca_dev, 0x01, reg1);
1345 switch (sd->sensor) { 1416 switch (sd->sensor) {
1346 case SENSOR_HV7131R:
1347 case SENSOR_MI0360: 1417 case SENSOR_MI0360:
1348 case SENSOR_MO4000: 1418 setinfrared(sd);
1349 case SENSOR_OM6802:
1350 setbrightness(gspca_dev);
1351 setcontrast(gspca_dev);
1352 break; 1419 break;
1353 case SENSOR_OV7630: 1420 case SENSOR_OV7630:
1354 setvflip(sd); 1421 setvflip(sd);
1355 /* fall thru */
1356 default: /* OV76xx */
1357 setbrightcont(gspca_dev);
1358 break; 1422 break;
1359 } 1423 }
1424 setbrightness(gspca_dev);
1425 setcontrast(gspca_dev);
1360 setautogain(gspca_dev); 1426 setautogain(gspca_dev);
1361 reg_w1(gspca_dev, 0x01, reg1);
1362 return 0; 1427 return 0;
1363} 1428}
1364 1429
@@ -1369,6 +1434,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1369 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; 1434 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1370 static const __u8 stopmi0360[] = 1435 static const __u8 stopmi0360[] =
1371 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1436 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437 static const __u8 stopov7648[] =
1438 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1372 __u8 data; 1439 __u8 data;
1373 const __u8 *sn9c1xx; 1440 const __u8 *sn9c1xx;
1374 1441
@@ -1382,8 +1449,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1382 i2c_w8(gspca_dev, stopmi0360); 1449 i2c_w8(gspca_dev, stopmi0360);
1383 data = 0x29; 1450 data = 0x29;
1384 break; 1451 break;
1385 case SENSOR_OV7630:
1386 case SENSOR_OV7648: 1452 case SENSOR_OV7648:
1453 i2c_w8(gspca_dev, stopov7648);
1454 /* fall thru */
1455 case SENSOR_OV7630:
1387 data = 0x29; 1456 data = 0x29;
1388 break; 1457 break;
1389 default: 1458 default:
@@ -1437,7 +1506,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1437 expotimes = 0; 1506 expotimes = 0;
1438 sd->exposure = setexposure(gspca_dev, 1507 sd->exposure = setexposure(gspca_dev,
1439 (unsigned int) expotimes); 1508 (unsigned int) expotimes);
1440 setcolors(gspca_dev); 1509 setredblue(gspca_dev);
1441 break; 1510 break;
1442 } 1511 }
1443 } 1512 }
@@ -1491,19 +1560,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1491 struct sd *sd = (struct sd *) gspca_dev; 1560 struct sd *sd = (struct sd *) gspca_dev;
1492 1561
1493 sd->brightness = val; 1562 sd->brightness = val;
1494 if (gspca_dev->streaming) { 1563 if (gspca_dev->streaming)
1495 switch (sd->sensor) { 1564 setbrightness(gspca_dev);
1496 case SENSOR_HV7131R:
1497 case SENSOR_MI0360:
1498 case SENSOR_MO4000:
1499 case SENSOR_OM6802:
1500 setbrightness(gspca_dev);
1501 break;
1502 default: /* OV76xx */
1503 setbrightcont(gspca_dev);
1504 break;
1505 }
1506 }
1507 return 0; 1565 return 0;
1508} 1566}
1509 1567
@@ -1520,19 +1578,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1520 struct sd *sd = (struct sd *) gspca_dev; 1578 struct sd *sd = (struct sd *) gspca_dev;
1521 1579
1522 sd->contrast = val; 1580 sd->contrast = val;
1523 if (gspca_dev->streaming) { 1581 if (gspca_dev->streaming)
1524 switch (sd->sensor) { 1582 setcontrast(gspca_dev);
1525 case SENSOR_HV7131R:
1526 case SENSOR_MI0360:
1527 case SENSOR_MO4000:
1528 case SENSOR_OM6802:
1529 setcontrast(gspca_dev);
1530 break;
1531 default: /* OV76xx */
1532 setbrightcont(gspca_dev);
1533 break;
1534 }
1535 }
1536 return 0; 1583 return 0;
1537} 1584}
1538 1585
@@ -1562,6 +1609,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1562 return 0; 1609 return 0;
1563} 1610}
1564 1611
1612static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1613{
1614 struct sd *sd = (struct sd *) gspca_dev;
1615
1616 sd->blue = val;
1617 if (gspca_dev->streaming)
1618 setredblue(gspca_dev);
1619 return 0;
1620}
1621
1622static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1623{
1624 struct sd *sd = (struct sd *) gspca_dev;
1625
1626 *val = sd->blue;
1627 return 0;
1628}
1629
1630static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1631{
1632 struct sd *sd = (struct sd *) gspca_dev;
1633
1634 sd->red = val;
1635 if (gspca_dev->streaming)
1636 setredblue(gspca_dev);
1637 return 0;
1638}
1639
1640static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1641{
1642 struct sd *sd = (struct sd *) gspca_dev;
1643
1644 *val = sd->red;
1645 return 0;
1646}
1647
1565static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1648static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1566{ 1649{
1567 struct sd *sd = (struct sd *) gspca_dev; 1650 struct sd *sd = (struct sd *) gspca_dev;
@@ -1598,6 +1681,24 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1598 return 0; 1681 return 0;
1599} 1682}
1600 1683
1684static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1685{
1686 struct sd *sd = (struct sd *) gspca_dev;
1687
1688 sd->infrared = val;
1689 if (gspca_dev->streaming)
1690 setinfrared(sd);
1691 return 0;
1692}
1693
1694static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1695{
1696 struct sd *sd = (struct sd *) gspca_dev;
1697
1698 *val = sd->infrared;
1699 return 0;
1700}
1701
1601/* sub-driver description */ 1702/* sub-driver description */
1602static const struct sd_desc sd_desc = { 1703static const struct sd_desc sd_desc = {
1603 .name = MODULE_NAME, 1704 .name = MODULE_NAME,
@@ -1620,12 +1721,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
1620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1721#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1722 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, 1723 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1724#endif
1623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1725 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1726 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1727#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, 1728 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1627#endif 1729#endif
1730 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1628 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 1731 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1732 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1629 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1630/* bw600.inf: 1734/* bw600.inf:
1631 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 1735 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -1649,7 +1753,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1649/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1753/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1650 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 1754 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1651/*bw600.inf:*/ 1755/*bw600.inf:*/
1652 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/ 1756 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1653 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1757 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1654 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)}, 1758 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1655/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1759/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
@@ -1657,8 +1761,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
1657 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1761 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1658#endif 1762#endif
1659 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1763 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1660#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1765#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1661/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1766 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1663 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1767 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1664/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ 1768/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */