]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixj.c
V4L/DVB (9711): gspca: Let gspca handle the webcams 045e:00f5 & 00f7 instead of sn9c102.
[linux-2.6-omap-h63xx.git] / drivers / media / video / gspca / sonixj.c
1 /*
2  *              Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "sonixj"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31 MODULE_LICENSE("GPL");
32
33 /* specific webcam descriptor */
34 struct sd {
35         struct gspca_dev gspca_dev;     /* !! must be the first item */
36
37         atomic_t avg_lum;
38         unsigned int exposure;
39
40         unsigned short brightness;
41         unsigned char contrast;
42         unsigned char colors;
43         unsigned char autogain;
44         __u8 vflip;                     /* ov7630 only */
45         __u8 infrared;                  /* mi0360 only */
46
47         signed char ag_cnt;
48 #define AG_CNT_START 13
49
50         char qindex;
51         unsigned char bridge;
52 #define BRIDGE_SN9C102P 0
53 #define BRIDGE_SN9C105 1
54 #define BRIDGE_SN9C110 2
55 #define BRIDGE_SN9C120 3
56 #define BRIDGE_SN9C325 4
57         char sensor;                    /* Type of image sensor chip */
58 #define SENSOR_HV7131R 0
59 #define SENSOR_MI0360 1
60 #define SENSOR_MO4000 2
61 #define SENSOR_OM6802 3
62 #define SENSOR_OV7630 4
63 #define SENSOR_OV7648 5
64 #define SENSOR_OV7660 6
65         unsigned char i2c_base;
66 };
67
68 /* V4L2 controls supported by the driver */
69 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
81
82 static struct ctrl sd_ctrls[] = {
83         {
84             {
85                 .id      = V4L2_CID_BRIGHTNESS,
86                 .type    = V4L2_CTRL_TYPE_INTEGER,
87                 .name    = "Brightness",
88                 .minimum = 0,
89 #define BRIGHTNESS_MAX 0xffff
90                 .maximum = BRIGHTNESS_MAX,
91                 .step    = 1,
92 #define BRIGHTNESS_DEF 0x7fff
93                 .default_value = BRIGHTNESS_DEF,
94             },
95             .set = sd_setbrightness,
96             .get = sd_getbrightness,
97         },
98         {
99             {
100                 .id      = V4L2_CID_CONTRAST,
101                 .type    = V4L2_CTRL_TYPE_INTEGER,
102                 .name    = "Contrast",
103                 .minimum = 0,
104 #define CONTRAST_MAX 127
105                 .maximum = CONTRAST_MAX,
106                 .step    = 1,
107 #define CONTRAST_DEF 63
108                 .default_value = CONTRAST_DEF,
109             },
110             .set = sd_setcontrast,
111             .get = sd_getcontrast,
112         },
113         {
114             {
115                 .id      = V4L2_CID_SATURATION,
116                 .type    = V4L2_CTRL_TYPE_INTEGER,
117                 .name    = "Color",
118                 .minimum = 0,
119                 .maximum = 64,
120                 .step    = 1,
121 #define COLOR_DEF 32
122                 .default_value = COLOR_DEF,
123             },
124             .set = sd_setcolors,
125             .get = sd_getcolors,
126         },
127 #define AUTOGAIN_IDX 3
128         {
129             {
130                 .id      = V4L2_CID_AUTOGAIN,
131                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
132                 .name    = "Auto Gain",
133                 .minimum = 0,
134                 .maximum = 1,
135                 .step    = 1,
136 #define AUTOGAIN_DEF 1
137                 .default_value = AUTOGAIN_DEF,
138             },
139             .set = sd_setautogain,
140             .get = sd_getautogain,
141         },
142 /* ov7630 only */
143 #define VFLIP_IDX 4
144         {
145             {
146                 .id      = V4L2_CID_VFLIP,
147                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
148                 .name    = "Vflip",
149                 .minimum = 0,
150                 .maximum = 1,
151                 .step    = 1,
152 #define VFLIP_DEF 1
153                 .default_value = VFLIP_DEF,
154             },
155             .set = sd_setvflip,
156             .get = sd_getvflip,
157         },
158 /* mi0360 only */
159 #define INFRARED_IDX 5
160         {
161             {
162                 .id      = V4L2_CID_INFRARED,
163                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
164                 .name    = "Infrared",
165                 .minimum = 0,
166                 .maximum = 1,
167                 .step    = 1,
168 #define INFRARED_DEF 0
169                 .default_value = INFRARED_DEF,
170             },
171             .set = sd_setinfrared,
172             .get = sd_getinfrared,
173         },
174 };
175
176 static struct v4l2_pix_format vga_mode[] = {
177         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
178                 .bytesperline = 160,
179                 .sizeimage = 160 * 120 * 4 / 8 + 590,
180                 .colorspace = V4L2_COLORSPACE_JPEG,
181                 .priv = 2},
182         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
183                 .bytesperline = 320,
184                 .sizeimage = 320 * 240 * 3 / 8 + 590,
185                 .colorspace = V4L2_COLORSPACE_JPEG,
186                 .priv = 1},
187         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
188                 .bytesperline = 640,
189                 .sizeimage = 640 * 480 * 3 / 8 + 590,
190                 .colorspace = V4L2_COLORSPACE_JPEG,
191                 .priv = 0},
192 };
193
194 /*Data from sn9c102p+hv71331r */
195 static const __u8 sn_hv7131[] = {
196 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
197         0x00,   0x03,   0x64,   0x00,   0x1a,   0x20,   0x20,   0x20,
198 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
199         0xa1,   0x11,   0x02,   0x09,   0x00,   0x00,   0x00,   0x10,
200 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
201         0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
202 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
203         0x0a,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
204 };
205
206 static const __u8 sn_mi0360[] = {
207 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
208         0x00,   0x61,   0x44,   0x00,   0x1a,   0x20,   0x20,   0x20,
209 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
210         0xb1,   0x5d,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
211 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
212         0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
213 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
214         0x06,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
215 };
216
217 static const __u8 sn_mo4000[] = {
218 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
219         0x12,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
220 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
221         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
222 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
223         0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
224 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
225         0x08,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
226 };
227
228 static const __u8 sn_om6802[] = {
229 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
230         0x00,   0x23,   0x72,   0x00,   0x1a,   0x34,   0x27,   0x20,
231 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
232         0x80,   0x34,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
233 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
234         0x03,   0x00,   0x51,   0x01,   0x00,   0x28,   0x1e,   0x40,
235 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
236         0x05,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
237         0x08,   0x22,   0x44,   0x63,   0x7d,   0x92,   0xa3,   0xaf,
238         0xbc,   0xc4,   0xcd,   0xd5,   0xdc,   0xe1,   0xe8,   0xef,
239         0xf7
240 };
241
242 static const __u8 sn_ov7630[] = {
243 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
244         0x00,   0x21,   0x40,   0x00,   0x1a,   0x20,   0x1f,   0x20,
245 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
246         0xa1,   0x21,   0x76,   0x21,   0x00,   0x00,   0x00,   0x10,
247 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
248         0x03,   0x00,   0x04,   0x01,   0x0a,   0x28,   0x1e,   0xc2,
249 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
250         0x0b,   0x00,   0x00,   0x00,   0x00,   0x00
251 };
252
253 static const __u8 sn_ov7648[] = {
254 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
255         0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
256 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
257         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x10,
258 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
259         0x03,   0x00,   0x00,   0x01,   0x00,   0x28,   0x1e,   0x00,
260 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
261         0x0b,   0x00,   0x00,   0x00,   0x00,   0x00
262 };
263
264 static const __u8 sn_ov7660[]   = {
265 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
266         0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
267 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
268         0x81,   0x21,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
269 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
270         0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
271 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
272         0x07,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
273 };
274
275 /* sequence specific to the sensors - !! index = SENSOR_xxx */
276 static const __u8 *sn_tb[] = {
277         sn_hv7131,
278         sn_mi0360,
279         sn_mo4000,
280         sn_om6802,
281         sn_ov7630,
282         sn_ov7648,
283         sn_ov7660
284 };
285
286 static const __u8 gamma_def[] = {
287         0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
288         0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
289 };
290
291 /* color matrix and offsets */
292 static const __u8 reg84[] = {
293         0x14, 0x00, 0x27, 0x00, 0x07, 0x00,     /* YR YG YB gains */
294         0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,     /* UR UG UB */
295         0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,     /* VR VG VB */
296         0x00, 0x00, 0x00                        /* YUV offsets */
297 };
298 static const __u8 hv7131r_sensor_init[][8] = {
299         {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
300         {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
301         {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
302         {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
303         {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
304         {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
305         {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
306
307         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
308         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
309         {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
310         {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
311         {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
312         {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
313         {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
314         {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
315
316         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
317         {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
318         {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
319         {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
320         {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
321
322         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
323         {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
324         {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
325         {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
326         {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
327         {}
328 };
329 static const __u8 mi0360_sensor_init[][8] = {
330         {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
331         {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
332         {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
333         {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
334         {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
335         {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
336         {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
337         {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
338         {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
339         {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
340         {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
341         {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
342         {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
343         {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
344         {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
345         {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
346         {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
347         {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
348         {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
349         {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
350         {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
351         {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
352         {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
353         {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
354         {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
355         {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
356         {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
357         {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
358         {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
359         {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
360         {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
361         {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
362         {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
363
364         {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
365         {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
366         {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
367         {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
368         {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
369
370         {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
371         {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
372         {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
373         {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
374
375         {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
376         {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
377 /*      {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
378 /*      {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
379         {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
380         {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
381         {}
382 };
383 static const __u8 mo4000_sensor_init[][8] = {
384         {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
385         {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
386         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
387         {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
388         {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
389         {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
390         {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
391         {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
392         {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
393         {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
394         {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
395         {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
396         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
397         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
398         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
399         {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
400         {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
401         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
402         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
403         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
404         {}
405 };
406 static __u8 om6802_sensor_init[][8] = {
407         {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
408         {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
409         {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
410         {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
411 /*      {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
412         {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
413                                         /* white balance & auto-exposure */
414 /*      {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
415                                                          * set color mode */
416 /*      {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
417                                                  * max AGC value in AE */
418 /*      {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
419                                                          * preset AGC */
420 /*      {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
421                                                  * preset brightness */
422 /*      {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
423                                                          * preset contrast */
424 /*      {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
425                                                          * preset gamma */
426         {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
427                                         /* luminance mode (0x4f = AE) */
428         {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
429                                                         /* preset shutter */
430 /*      {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
431                                                          * auto frame rate */
432 /*      {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
433
434 /*      {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
435 /*      {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
436 /*      {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
437 /*      {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
438         {}
439 };
440 static const __u8 ov7630_sensor_init[][8] = {
441         {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
442         {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
443 /* win: delay 20ms */
444         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
445         {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
446 /* win: delay 20ms */
447         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
448 /* win: i2c_r from 00 to 80 */
449         {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
450         {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
451         {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
452         {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
453         {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
454         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
455         {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
456         {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
457         {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
458         {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
459         {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
460         {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
461         {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
462         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
463         {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
464         {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
465         {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
466         {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
467         {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
468         {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
469         {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
470         {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
471         {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
472         {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
473         {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
474         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
475 /* */
476         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
477         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
478 /*fixme: + 0x12, 0x04*/
479 /*      {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
480                                                          * set by setvflip */
481         {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
482         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
483         {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
484 /* */
485         {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
486         {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
487         {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
488 /* */
489         {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
490 /*      {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
491         {}
492 };
493
494 static const __u8 ov7648_sensor_init[][8] = {
495         {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
496         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},       /* reset */
497         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
498         {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
499         {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
500         {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
501         {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
502         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
503         {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
504         {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
505         {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
506         {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
507         {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
508         {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
509         {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
510         {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
511         {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
512         {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
513         {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
514         {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
515         {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
516
517         {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
518 /*      {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
519 /*      {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
520         {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
521 /*...*/
522 /*      {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
523 /*      {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
524         {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
525         {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
526 /*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
527 /*      {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
528 /*      {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
529 /*...*/
530         {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
531 /*      {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
532 /*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
533 /*      {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
534 /*      {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
535 /*      {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
536
537         {}
538 };
539
540 static const __u8 ov7660_sensor_init[][8] = {
541         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
542 /*              (delay 20ms) */
543         {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
544                                                 /* Outformat = rawRGB */
545         {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
546         {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
547                                                 /* GAIN BLUE RED VREF */
548         {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
549                                                 /* COM 1 BAVE GEAVE AECHH */
550         {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
551         {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
552         {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
553                                                 /* AECH CLKRC COM7 COM8 */
554         {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
555         {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
556                                                 /* HSTART HSTOP VSTRT VSTOP */
557         {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
558         {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
559         {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
560                                         /* BOS GBOS GROS ROS (BGGR offset) */
561 /*      {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
562         {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
563                                                 /* AEW AEB VPT BBIAS */
564         {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
565                                                 /* GbBIAS RSVD EXHCH EXHCL */
566         {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
567                                                 /* RBIAS ADVFL ASDVFH YAVE */
568         {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
569                                                 /* HSYST HSYEN HREF */
570         {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
571         {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
572                                                 /* ADC ACOM OFON TSLB */
573         {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
574                                                 /* COM11 COM12 COM13 COM14 */
575         {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
576                                                 /* EDGE COM15 COM16 COM17 */
577         {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
578         {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
579         {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
580         {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
581         {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
582         {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
583         {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
584         {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
585         {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
586         {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
587                                                 /* LCC1 LCC2 LCC3 LCC4 */
588         {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
589         {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
590         {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
591                                         /* band gap reference [0:3] DBLV */
592         {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
593         {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
594         {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
595         {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
596         {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
597         {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
598         {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
599         {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
600         {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
601         {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
602 /****** (some exchanges in the win trace) ******/
603         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
604                                                 /* bits[3..0]reserved */
605         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
606         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
607                                                 /* VREF vertical frame ctrl */
608         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
609         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
610         {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
611         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
612         {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
613 /*      {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
614 /****** (some exchanges in the win trace) ******/
615         {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
616         {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
617         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
618         {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
619 /*      {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
620 /****** (some exchanges in the win trace) ******/
621 /******!! startsensor KO if changed !!****/
622         {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
623         {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
624         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
625         {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
626         {}
627 };
628
629 static const __u8 qtable4[] = {
630         0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
631         0x06, 0x08, 0x0A, 0x11,
632         0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
633         0x19, 0x19, 0x17, 0x15,
634         0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
635         0x21, 0x2E, 0x21, 0x23,
636         0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
637         0x25, 0x29, 0x2C, 0x29,
638         0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
639         0x17, 0x1B, 0x29, 0x29,
640         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
641         0x29, 0x29, 0x29, 0x29,
642         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
643         0x29, 0x29, 0x29, 0x29,
644         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
645         0x29, 0x29, 0x29, 0x29
646 };
647
648 /* read <len> bytes to gspca_dev->usb_buf */
649 static void reg_r(struct gspca_dev *gspca_dev,
650                   __u16 value, int len)
651 {
652 #ifdef GSPCA_DEBUG
653         if (len > USB_BUF_SZ) {
654                 err("reg_r: buffer overflow");
655                 return;
656         }
657 #endif
658         usb_control_msg(gspca_dev->dev,
659                         usb_rcvctrlpipe(gspca_dev->dev, 0),
660                         0,
661                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
662                         value, 0,
663                         gspca_dev->usb_buf, len,
664                         500);
665         PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
666 }
667
668 static void reg_w1(struct gspca_dev *gspca_dev,
669                    __u16 value,
670                    __u8 data)
671 {
672         PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
673         gspca_dev->usb_buf[0] = data;
674         usb_control_msg(gspca_dev->dev,
675                         usb_sndctrlpipe(gspca_dev->dev, 0),
676                         0x08,
677                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
678                         value,
679                         0,
680                         gspca_dev->usb_buf, 1,
681                         500);
682 }
683 static void reg_w(struct gspca_dev *gspca_dev,
684                           __u16 value,
685                           const __u8 *buffer,
686                           int len)
687 {
688         PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
689                 value, buffer[0], buffer[1]);
690 #ifdef GSPCA_DEBUG
691         if (len > USB_BUF_SZ) {
692                 err("reg_w: buffer overflow");
693                 return;
694         }
695 #endif
696         memcpy(gspca_dev->usb_buf, buffer, len);
697         usb_control_msg(gspca_dev->dev,
698                         usb_sndctrlpipe(gspca_dev->dev, 0),
699                         0x08,
700                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
701                         value, 0,
702                         gspca_dev->usb_buf, len,
703                         500);
704 }
705
706 /* I2C write 1 byte */
707 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
708 {
709         struct sd *sd = (struct sd *) gspca_dev;
710
711         PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
712         gspca_dev->usb_buf[0] = 0x81 | (2 << 4);        /* = a1 */
713         gspca_dev->usb_buf[1] = sd->i2c_base;
714         gspca_dev->usb_buf[2] = reg;
715         gspca_dev->usb_buf[3] = val;
716         gspca_dev->usb_buf[4] = 0;
717         gspca_dev->usb_buf[5] = 0;
718         gspca_dev->usb_buf[6] = 0;
719         gspca_dev->usb_buf[7] = 0x10;
720         usb_control_msg(gspca_dev->dev,
721                         usb_sndctrlpipe(gspca_dev->dev, 0),
722                         0x08,
723                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
724                         0x08,                   /* value = i2c */
725                         0,
726                         gspca_dev->usb_buf, 8,
727                         500);
728 }
729
730 /* I2C write 8 bytes */
731 static void i2c_w8(struct gspca_dev *gspca_dev,
732                    const __u8 *buffer)
733 {
734         memcpy(gspca_dev->usb_buf, buffer, 8);
735         usb_control_msg(gspca_dev->dev,
736                         usb_sndctrlpipe(gspca_dev->dev, 0),
737                         0x08,
738                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
739                         0x08, 0,                /* value, index */
740                         gspca_dev->usb_buf, 8,
741                         500);
742         msleep(2);
743 }
744
745 /* read 5 bytes in gspca_dev->usb_buf */
746 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
747 {
748         struct sd *sd = (struct sd *) gspca_dev;
749         __u8 mode[8];
750
751         mode[0] = 0x81 | 0x10;
752         mode[1] = sd->i2c_base;
753         mode[2] = reg;
754         mode[3] = 0;
755         mode[4] = 0;
756         mode[5] = 0;
757         mode[6] = 0;
758         mode[7] = 0x10;
759         i2c_w8(gspca_dev, mode);
760         msleep(2);
761         mode[0] = 0x81 | (5 << 4) | 0x02;
762         mode[2] = 0;
763         i2c_w8(gspca_dev, mode);
764         msleep(2);
765         reg_r(gspca_dev, 0x0a, 5);
766 }
767
768 static int probesensor(struct gspca_dev *gspca_dev)
769 {
770         struct sd *sd = (struct sd *) gspca_dev;
771
772         i2c_w1(gspca_dev, 0x02, 0);                     /* sensor wakeup */
773         msleep(10);
774         reg_w1(gspca_dev, 0x02, 0x66);                  /* Gpio on */
775         msleep(10);
776         i2c_r5(gspca_dev, 0);                           /* read sensor id */
777         if (gspca_dev->usb_buf[0] == 0x02
778             && gspca_dev->usb_buf[1] == 0x09
779             && gspca_dev->usb_buf[2] == 0x01
780             && gspca_dev->usb_buf[3] == 0x00
781             && gspca_dev->usb_buf[4] == 0x00) {
782                 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
783                 sd->sensor = SENSOR_HV7131R;
784                 return SENSOR_HV7131R;
785         }
786         PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
787                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
788                 gspca_dev->usb_buf[2]);
789         PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
790         return -ENODEV;
791 }
792
793 static int configure_gpio(struct gspca_dev *gspca_dev,
794                           const __u8 *sn9c1xx)
795 {
796         struct sd *sd = (struct sd *) gspca_dev;
797         const __u8 *reg9a;
798         static const __u8 reg9a_def[] =
799                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
800         static const __u8 reg9a_sn9c325[] =
801                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
802         static const __u8 regd4[] = {0x60, 0x00, 0x00};
803
804         reg_w1(gspca_dev, 0xf1, 0x00);
805         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
806
807         /* configure gpio */
808         reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
809         reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
810         reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
811         switch (sd->bridge) {
812         case BRIDGE_SN9C325:
813                 reg9a = reg9a_sn9c325;
814                 break;
815         default:
816                 reg9a = reg9a_def;
817                 break;
818         }
819         reg_w(gspca_dev, 0x9a, reg9a, 6);
820
821         reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
822
823         reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
824
825         switch (sd->sensor) {
826         case SENSOR_OM6802:
827                 reg_w1(gspca_dev, 0x02, 0x71);
828                 reg_w1(gspca_dev, 0x01, 0x42);
829                 reg_w1(gspca_dev, 0x17, 0x64);
830                 reg_w1(gspca_dev, 0x01, 0x42);
831                 break;
832 /*jfm: from win trace */
833         case SENSOR_OV7630:
834                 reg_w1(gspca_dev, 0x01, 0x61);
835                 reg_w1(gspca_dev, 0x17, 0xe2);
836                 reg_w1(gspca_dev, 0x01, 0x60);
837                 reg_w1(gspca_dev, 0x01, 0x40);
838                 break;
839         case SENSOR_OV7648:
840                 reg_w1(gspca_dev, 0x01, 0x63);
841                 reg_w1(gspca_dev, 0x17, 0x20);
842                 reg_w1(gspca_dev, 0x01, 0x42);
843                 break;
844 /*jfm: from win trace */
845         case SENSOR_OV7660:
846                 if (sd->bridge == BRIDGE_SN9C120) {
847                         reg_w1(gspca_dev, 0x01, 0x61);
848                         reg_w1(gspca_dev, 0x17, 0x20);
849                         reg_w1(gspca_dev, 0x01, 0x60);
850                         reg_w1(gspca_dev, 0x01, 0x40);
851                         break;
852                 }
853                 /* fall thru */
854         default:
855                 reg_w1(gspca_dev, 0x01, 0x43);
856                 reg_w1(gspca_dev, 0x17, 0x61);
857                 reg_w1(gspca_dev, 0x01, 0x42);
858                 if (sd->sensor == SENSOR_HV7131R) {
859                         if (probesensor(gspca_dev) < 0)
860                                 return -ENODEV;
861                 }
862                 break;
863         }
864         return 0;
865 }
866
867 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
868 {
869         int i = 0;
870         static const __u8 SetSensorClk[] =      /* 0x08 Mclk */
871                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
872
873         while (hv7131r_sensor_init[i][0]) {
874                 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
875                 i++;
876         }
877         i2c_w8(gspca_dev, SetSensorClk);
878 }
879
880 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
881 {
882         int i = 0;
883
884         while (mi0360_sensor_init[i][0]) {
885                 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
886                 i++;
887         }
888 }
889
890 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
891 {
892         int i = 0;
893
894         while (mo4000_sensor_init[i][0]) {
895                 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
896                 i++;
897         }
898 }
899
900 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
901 {
902         int i = 0;
903
904         while (om6802_sensor_init[i][0]) {
905                 i2c_w8(gspca_dev, om6802_sensor_init[i]);
906                 i++;
907         }
908 }
909
910 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
911 {
912         int i = 0;
913
914         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 76 01 */
915         i++;
916         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 (RGB+SRST) */
917         i++;
918         msleep(20);
919         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
920         i++;
921         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 */
922         i++;
923         msleep(20);
924         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
925         i++;
926 /*jfm:win i2c_r from 00 to 80*/
927
928         while (ov7630_sensor_init[i][0]) {
929                 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
930                 i++;
931         }
932 }
933
934 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
935 {
936         int i = 0;
937
938         i2c_w8(gspca_dev, ov7648_sensor_init[i]);
939         i++;
940 /* win: dble reset */
941         i2c_w8(gspca_dev, ov7648_sensor_init[i]);       /* reset */
942         i++;
943         msleep(20);
944 /* win: i2c reg read 00..7f */
945         while (ov7648_sensor_init[i][0]) {
946                 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
947                 i++;
948         }
949 }
950
951 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
952 {
953         int i = 0;
954
955         i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
956         i++;
957         msleep(20);
958         while (ov7660_sensor_init[i][0]) {
959                 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
960                 i++;
961         }
962 }
963
964 /* this function is called at probe time */
965 static int sd_config(struct gspca_dev *gspca_dev,
966                         const struct usb_device_id *id)
967 {
968         struct sd *sd = (struct sd *) gspca_dev;
969         struct cam *cam;
970
971         cam = &gspca_dev->cam;
972         cam->epaddr = 0x01;
973         cam->cam_mode = vga_mode;
974         cam->nmodes = ARRAY_SIZE(vga_mode);
975
976         sd->bridge = id->driver_info >> 16;
977         sd->sensor = id->driver_info >> 8;
978         sd->i2c_base = id->driver_info;
979
980         sd->qindex = 4;                 /* set the quantization table */
981         sd->brightness = BRIGHTNESS_DEF;
982         sd->contrast = CONTRAST_DEF;
983         sd->colors = COLOR_DEF;
984         sd->autogain = AUTOGAIN_DEF;
985         sd->ag_cnt = -1;
986         sd->vflip = VFLIP_DEF;
987         sd->infrared = INFRARED_DEF;
988
989         switch (sd->sensor) {
990         case SENSOR_OV7630:
991         case SENSOR_OV7648:
992         case SENSOR_OV7660:
993                 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
994                 break;
995         }
996         if (sd->sensor != SENSOR_OV7630)
997                 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
998         if (sd->sensor != SENSOR_MI0360)
999                 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
1000         return 0;
1001 }
1002
1003 /* this function is called at probe and resume time */
1004 static int sd_init(struct gspca_dev *gspca_dev)
1005 {
1006         struct sd *sd = (struct sd *) gspca_dev;
1007 /*      const __u8 *sn9c1xx; */
1008         __u8 regGpio[] = { 0x29, 0x74 };
1009         __u8 regF1;
1010
1011         /* setup a selector by bridge */
1012         reg_w1(gspca_dev, 0xf1, 0x01);
1013         reg_r(gspca_dev, 0x00, 1);
1014         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1015         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
1016         regF1 = gspca_dev->usb_buf[0];
1017         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1018         switch (sd->bridge) {
1019         case BRIDGE_SN9C102P:
1020                 if (regF1 != 0x11)
1021                         return -ENODEV;
1022                 reg_w1(gspca_dev, 0x02, regGpio[1]);
1023                 break;
1024         case BRIDGE_SN9C105:
1025                 if (regF1 != 0x11)
1026                         return -ENODEV;
1027                 reg_w(gspca_dev, 0x01, regGpio, 2);
1028                 break;
1029         case BRIDGE_SN9C120:
1030                 if (regF1 != 0x12)
1031                         return -ENODEV;
1032                 regGpio[1] = 0x70;
1033                 reg_w(gspca_dev, 0x01, regGpio, 2);
1034                 break;
1035         default:
1036 /*      case BRIDGE_SN9C110: */
1037 /*      case BRIDGE_SN9C325: */
1038                 if (regF1 != 0x12)
1039                         return -ENODEV;
1040                 reg_w1(gspca_dev, 0x02, 0x62);
1041                 break;
1042         }
1043
1044         reg_w1(gspca_dev, 0xf1, 0x01);
1045
1046         return 0;
1047 }
1048
1049 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1050                                 unsigned int expo)
1051 {
1052         struct sd *sd = (struct sd *) gspca_dev;
1053         static const __u8 doit[] =              /* update sensor */
1054                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1055         static const __u8 sensorgo[] =          /* sensor on */
1056                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1057         static const __u8 gainMo[] =
1058                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1059
1060         switch (sd->sensor) {
1061         case SENSOR_HV7131R: {
1062                 __u8 Expodoit[] =
1063                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1064
1065                 Expodoit[3] = expo >> 16;
1066                 Expodoit[4] = expo >> 8;
1067                 Expodoit[5] = expo;
1068                 i2c_w8(gspca_dev, Expodoit);
1069                 break;
1070             }
1071         case SENSOR_MI0360: {
1072                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
1073                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1074
1075                 if (expo > 0x0635)
1076                         expo = 0x0635;
1077                 else if (expo < 0x0001)
1078                         expo = 0x0001;
1079                 expoMi[3] = expo >> 8;
1080                 expoMi[4] = expo;
1081                 i2c_w8(gspca_dev, expoMi);
1082                 i2c_w8(gspca_dev, doit);
1083                 i2c_w8(gspca_dev, sensorgo);
1084                 break;
1085             }
1086         case SENSOR_MO4000: {
1087                 __u8 expoMof[] =
1088                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1089                 __u8 expoMo10[] =
1090                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1091
1092                 if (expo > 0x1fff)
1093                         expo = 0x1fff;
1094                 else if (expo < 0x0001)
1095                         expo = 0x0001;
1096                 expoMof[3] = (expo & 0x03fc) >> 2;
1097                 i2c_w8(gspca_dev, expoMof);
1098                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1099                                 | ((expo & 0x0003) << 4);
1100                 i2c_w8(gspca_dev, expoMo10);
1101                 i2c_w8(gspca_dev, gainMo);
1102                 PDEBUG(D_CONF, "set exposure %d",
1103                         ((expoMo10[3] & 0x07) << 10)
1104                         | (expoMof[3] << 2)
1105                         | ((expoMo10[3] & 0x30) >> 4));
1106                 break;
1107             }
1108         case SENSOR_OM6802: {
1109                 __u8 gainOm[] =
1110                         { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1111
1112                 if (expo > 0x03ff)
1113                         expo = 0x03ff;
1114                  if (expo < 0x0001)
1115                         expo = 0x0001;
1116                 gainOm[3] = expo >> 2;
1117                 i2c_w8(gspca_dev, gainOm);
1118                 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1119                 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1120                 break;
1121             }
1122         }
1123         return expo;
1124 }
1125
1126 /* this function is used for sensors o76xx only */
1127 static void setbrightcont(struct gspca_dev *gspca_dev)
1128 {
1129         struct sd *sd = (struct sd *) gspca_dev;
1130         int val;
1131         __u8 reg84_full[0x15];
1132
1133         memcpy(reg84_full, reg84, sizeof reg84_full);
1134         val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10;        /* 10..40 */
1135         reg84_full[0] = (val + 1) / 2;          /* red */
1136         reg84_full[2] = val;                    /* green */
1137         reg84_full[4] = (val + 1) / 5;          /* blue */
1138         val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1139                         / BRIGHTNESS_MAX;
1140         reg84_full[0x12] = val & 0x1f;          /* 5:0 signed value */
1141         reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1142 }
1143
1144 /* sensor != ov76xx */
1145 static void setbrightness(struct gspca_dev *gspca_dev)
1146 {
1147         struct sd *sd = (struct sd *) gspca_dev;
1148         unsigned int expo;
1149         __u8 k2;
1150
1151         k2 = sd->brightness >> 10;
1152         switch (sd->sensor) {
1153         case SENSOR_HV7131R:
1154                 expo = sd->brightness << 4;
1155                 if (expo > 0x002dc6c0)
1156                         expo = 0x002dc6c0;
1157                 else if (expo < 0x02a0)
1158                         expo = 0x02a0;
1159                 sd->exposure = setexposure(gspca_dev, expo);
1160                 break;
1161         case SENSOR_MI0360:
1162         case SENSOR_MO4000:
1163                 expo = sd->brightness >> 4;
1164                 sd->exposure = setexposure(gspca_dev, expo);
1165                 break;
1166         case SENSOR_OM6802:
1167                 expo = sd->brightness >> 6;
1168                 sd->exposure = setexposure(gspca_dev, expo);
1169                 k2 = sd->brightness >> 11;
1170                 break;
1171         }
1172
1173         reg_w1(gspca_dev, 0x96, k2);
1174 }
1175
1176 /* sensor != ov76xx */
1177 static void setcontrast(struct gspca_dev *gspca_dev)
1178 {
1179         struct sd *sd = (struct sd *) gspca_dev;
1180         __u8 k2;
1181         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1182
1183         k2 = sd->contrast;
1184         contrast[2] = k2;
1185         contrast[0] = (k2 + 1) >> 1;
1186         contrast[4] = (k2 + 1) / 5;
1187         reg_w(gspca_dev, 0x84, contrast, 6);
1188 }
1189
1190 static void setcolors(struct gspca_dev *gspca_dev)
1191 {
1192         struct sd *sd = (struct sd *) gspca_dev;
1193         __u8 blue, red;
1194
1195         if (sd->colors >= 32) {
1196                 red = 32 + (sd->colors - 32) / 2;
1197                 blue = 64 - sd->colors;
1198         } else {
1199                 red = sd->colors;
1200                 blue = 32 + (32 - sd->colors) / 2;
1201         }
1202         reg_w1(gspca_dev, 0x05, red);
1203 /*      reg_w1(gspca_dev, 0x07, 32); */
1204         reg_w1(gspca_dev, 0x06, blue);
1205 }
1206
1207 static void setautogain(struct gspca_dev *gspca_dev)
1208 {
1209         struct sd *sd = (struct sd *) gspca_dev;
1210
1211         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1212                 return;
1213         if (sd->autogain)
1214                 sd->ag_cnt = AG_CNT_START;
1215         else
1216                 sd->ag_cnt = -1;
1217 }
1218
1219 static void setvflip(struct sd *sd)
1220 {
1221         i2c_w1(&sd->gspca_dev, 0x75,                    /* COMN */
1222                 sd->vflip ? 0x82 : 0x02);
1223 }
1224
1225 static void setinfrared(struct sd *sd)
1226 {
1227 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1228 /* Clip */
1229         i2c_w1(&sd->gspca_dev, 0x02,                    /* gpio */
1230                 sd->infrared ? 0x66 : 0x64);
1231 }
1232
1233 /* -- start the camera -- */
1234 static int sd_start(struct gspca_dev *gspca_dev)
1235 {
1236         struct sd *sd = (struct sd *) gspca_dev;
1237         int i;
1238         __u8 reg1, reg17, reg18;
1239         const __u8 *sn9c1xx;
1240         int mode;
1241         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1242         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1243         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
1244         static const __u8 CE_ov76xx[] =
1245                                 { 0x32, 0xdd, 0x32, 0xdd };
1246
1247         sn9c1xx = sn_tb[(int) sd->sensor];
1248         configure_gpio(gspca_dev, sn9c1xx);
1249
1250         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1251         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1252         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1253         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1254         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1255         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1256         reg_w1(gspca_dev, 0xd3, 0x50);
1257         reg_w1(gspca_dev, 0xc6, 0x00);
1258         reg_w1(gspca_dev, 0xc7, 0x00);
1259         reg_w1(gspca_dev, 0xc8, 0x50);
1260         reg_w1(gspca_dev, 0xc9, 0x3c);
1261         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1262         switch (sd->sensor) {
1263         case SENSOR_OV7630:
1264                 reg17 = 0xe2;
1265                 break;
1266         case SENSOR_OV7648:
1267                 reg17 = 0x20;
1268                 break;
1269 /*jfm: from win trace */
1270         case SENSOR_OV7660:
1271                 if (sd->bridge == BRIDGE_SN9C120) {
1272                         reg17 = 0xa0;
1273                         break;
1274                 }
1275                 /* fall thru */
1276         default:
1277                 reg17 = 0x60;
1278                 break;
1279         }
1280         reg_w1(gspca_dev, 0x17, reg17);
1281 /* set reg1 was here */
1282         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1283         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1284         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1285         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1286         reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1287         for (i = 0; i < 8; i++)
1288                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1289         switch (sd->sensor) {
1290         case SENSOR_OV7648:
1291                 reg_w1(gspca_dev, 0x9a, 0x0a);
1292                 reg_w1(gspca_dev, 0x99, 0x60);
1293                 break;
1294         case SENSOR_OV7660:
1295                 if (sd->bridge == BRIDGE_SN9C120) {
1296                         reg_w1(gspca_dev, 0x9a, 0x05);
1297                         break;
1298                 }
1299                 /* fall thru */
1300         default:
1301                 reg_w1(gspca_dev, 0x9a, 0x08);
1302                 reg_w1(gspca_dev, 0x99, 0x59);
1303                 break;
1304         }
1305
1306         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1307         if (mode)
1308                 reg1 = 0x46;    /* 320x240: clk 48Mhz, video trf enable */
1309         else
1310                 reg1 = 0x06;    /* 640x480: clk 24Mhz, video trf enable */
1311         reg17 = 0x61;           /* 0x:20: enable sensor clock */
1312         switch (sd->sensor) {
1313         case SENSOR_HV7131R:
1314                 hv7131R_InitSensor(gspca_dev);
1315                 break;
1316         case SENSOR_MI0360:
1317                 mi0360_InitSensor(gspca_dev);
1318                 break;
1319         case SENSOR_MO4000:
1320                 mo4000_InitSensor(gspca_dev);
1321                 if (mode) {
1322 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1323                         reg1 = 0x06;    /* clk 24Mz */
1324                 } else {
1325                         reg17 = 0x22;   /* 640 MCKSIZE */
1326 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1327                 }
1328                 break;
1329         case SENSOR_OM6802:
1330                 om6802_InitSensor(gspca_dev);
1331                 reg17 = 0x64;           /* 640 MCKSIZE */
1332                 break;
1333         case SENSOR_OV7630:
1334                 ov7630_InitSensor(gspca_dev);
1335                 setvflip(sd);
1336                 reg17 = 0xe2;
1337                 reg1 = 0x44;
1338                 break;
1339         case SENSOR_OV7648:
1340                 ov7648_InitSensor(gspca_dev);
1341                 reg17 = 0x21;
1342 /*              reg1 = 0x42;             * 42 - 46? */
1343 /*              if (mode)
1344                         ;                * 320x2...
1345                 else
1346                         ;                * 640x... */
1347                 break;
1348         default:
1349 /*      case SENSOR_OV7660: */
1350                 ov7660_InitSensor(gspca_dev);
1351                 if (mode) {
1352 /*                      reg17 = 0x21;    * 320 */
1353 /*                      reg1 = 0x44; */
1354 /*                      reg1 = 0x46;    (done) */
1355                 } else {                        /* 640 */
1356                         if (sd->bridge == BRIDGE_SN9C120) {
1357                                 reg17 = 0xa2;
1358                                 reg1 = 0x44;    /* 48 Mhz, video trf eneble */
1359                         } else {
1360                                 reg17 = 0x22;
1361                                 reg1 = 0x06;    /* 24 Mhz, video trf eneble
1362                                                  * inverse power down */
1363                         }
1364                 }
1365                 break;
1366         }
1367         reg_w(gspca_dev, 0xc0, C0, 6);
1368         reg_w(gspca_dev, 0xca, CA, 4);
1369         switch (sd->sensor) {
1370         case SENSOR_OV7630:
1371         case SENSOR_OV7648:
1372         case SENSOR_OV7660:
1373                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1374                 break;
1375         default:
1376                 reg_w(gspca_dev, 0xce, CE, 4);
1377                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1378                 break;
1379         }
1380
1381         /* here change size mode 0 -> VGA; 1 -> CIF */
1382         reg18 = sn9c1xx[0x18] | (mode << 4);
1383         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1384
1385         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1386         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1387
1388         reg_w1(gspca_dev, 0x18, reg18);
1389
1390         reg_w1(gspca_dev, 0x17, reg17);
1391         reg_w1(gspca_dev, 0x01, reg1);
1392         switch (sd->sensor) {
1393         case SENSOR_MI0360:
1394                 setinfrared(sd);
1395                 /* fall thru */
1396         case SENSOR_HV7131R:
1397         case SENSOR_MO4000:
1398         case SENSOR_OM6802:
1399                 setbrightness(gspca_dev);
1400                 setcontrast(gspca_dev);
1401                 break;
1402         case SENSOR_OV7630:
1403                 setvflip(sd);
1404                 /* fall thru */
1405         default:                        /* OV76xx */
1406                 setbrightcont(gspca_dev);
1407                 break;
1408         }
1409         setautogain(gspca_dev);
1410         return 0;
1411 }
1412
1413 static void sd_stopN(struct gspca_dev *gspca_dev)
1414 {
1415         struct sd *sd = (struct sd *) gspca_dev;
1416         static const __u8 stophv7131[] =
1417                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1418         static const __u8 stopmi0360[] =
1419                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1420         static const __u8 stopov7648[] =
1421                 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1422         __u8 data;
1423         const __u8 *sn9c1xx;
1424
1425         data = 0x0b;
1426         switch (sd->sensor) {
1427         case SENSOR_HV7131R:
1428                 i2c_w8(gspca_dev, stophv7131);
1429                 data = 0x2b;
1430                 break;
1431         case SENSOR_MI0360:
1432                 i2c_w8(gspca_dev, stopmi0360);
1433                 data = 0x29;
1434                 break;
1435         case SENSOR_OV7648:
1436                 i2c_w8(gspca_dev, stopov7648);
1437                 /* fall thru */
1438         case SENSOR_OV7630:
1439                 data = 0x29;
1440                 break;
1441         default:
1442 /*      case SENSOR_MO4000: */
1443 /*      case SENSOR_OV7660: */
1444                 break;
1445         }
1446         sn9c1xx = sn_tb[(int) sd->sensor];
1447         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1448         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1449         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1450         reg_w1(gspca_dev, 0x01, data);
1451         reg_w1(gspca_dev, 0xf1, 0x00);
1452 }
1453
1454 static void do_autogain(struct gspca_dev *gspca_dev)
1455 {
1456         struct sd *sd = (struct sd *) gspca_dev;
1457         int delta;
1458         int expotimes;
1459         __u8 luma_mean = 130;
1460         __u8 luma_delta = 20;
1461
1462         /* Thanks S., without your advice, autobright should not work :) */
1463         if (sd->ag_cnt < 0)
1464                 return;
1465         if (--sd->ag_cnt >= 0)
1466                 return;
1467         sd->ag_cnt = AG_CNT_START;
1468
1469         delta = atomic_read(&sd->avg_lum);
1470         PDEBUG(D_FRAM, "mean lum %d", delta);
1471         if (delta < luma_mean - luma_delta ||
1472             delta > luma_mean + luma_delta) {
1473                 switch (sd->sensor) {
1474                 case SENSOR_HV7131R:
1475                         expotimes = sd->exposure >> 8;
1476                         expotimes += (luma_mean - delta) >> 4;
1477                         if (expotimes < 0)
1478                                 expotimes = 0;
1479                         sd->exposure = setexposure(gspca_dev,
1480                                         (unsigned int) (expotimes << 8));
1481                         break;
1482                 default:
1483 /*              case SENSOR_MO4000: */
1484 /*              case SENSOR_MI0360: */
1485 /*              case SENSOR_OM6802: */
1486                         expotimes = sd->exposure;
1487                         expotimes += (luma_mean - delta) >> 6;
1488                         if (expotimes < 0)
1489                                 expotimes = 0;
1490                         sd->exposure = setexposure(gspca_dev,
1491                                                    (unsigned int) expotimes);
1492                         setcolors(gspca_dev);
1493                         break;
1494                 }
1495         }
1496 }
1497
1498 /* scan the URB packets */
1499 /* This function is run at interrupt level. */
1500 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1501                         struct gspca_frame *frame,      /* target */
1502                         __u8 *data,                     /* isoc packet */
1503                         int len)                        /* iso packet length */
1504 {
1505         struct sd *sd = (struct sd *) gspca_dev;
1506         int sof, avg_lum;
1507
1508         sof = len - 64;
1509         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1510
1511                 /* end of frame */
1512                 gspca_frame_add(gspca_dev, LAST_PACKET,
1513                                 frame, data, sof + 2);
1514                 if (sd->ag_cnt < 0)
1515                         return;
1516 /* w1 w2 w3 */
1517 /* w4 w5 w6 */
1518 /* w7 w8 */
1519 /* w4 */
1520                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1521 /* w6 */
1522                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1523 /* w2 */
1524                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1525 /* w8 */
1526                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1527 /* w5 */
1528                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1529                 avg_lum >>= 4;
1530                 atomic_set(&sd->avg_lum, avg_lum);
1531                 return;
1532         }
1533         if (gspca_dev->last_packet_type == LAST_PACKET) {
1534
1535                 /* put the JPEG 422 header */
1536                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1537         }
1538         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1539 }
1540
1541 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1542 {
1543         struct sd *sd = (struct sd *) gspca_dev;
1544
1545         sd->brightness = val;
1546         if (gspca_dev->streaming) {
1547                 switch (sd->sensor) {
1548                 case SENSOR_HV7131R:
1549                 case SENSOR_MI0360:
1550                 case SENSOR_MO4000:
1551                 case SENSOR_OM6802:
1552                         setbrightness(gspca_dev);
1553                         break;
1554                 default:                        /* OV76xx */
1555                         setbrightcont(gspca_dev);
1556                         break;
1557                 }
1558         }
1559         return 0;
1560 }
1561
1562 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1563 {
1564         struct sd *sd = (struct sd *) gspca_dev;
1565
1566         *val = sd->brightness;
1567         return 0;
1568 }
1569
1570 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1571 {
1572         struct sd *sd = (struct sd *) gspca_dev;
1573
1574         sd->contrast = val;
1575         if (gspca_dev->streaming) {
1576                 switch (sd->sensor) {
1577                 case SENSOR_HV7131R:
1578                 case SENSOR_MI0360:
1579                 case SENSOR_MO4000:
1580                 case SENSOR_OM6802:
1581                         setcontrast(gspca_dev);
1582                         break;
1583                 default:                        /* OV76xx */
1584                         setbrightcont(gspca_dev);
1585                         break;
1586                 }
1587         }
1588         return 0;
1589 }
1590
1591 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1592 {
1593         struct sd *sd = (struct sd *) gspca_dev;
1594
1595         *val = sd->contrast;
1596         return 0;
1597 }
1598
1599 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1600 {
1601         struct sd *sd = (struct sd *) gspca_dev;
1602
1603         sd->colors = val;
1604         if (gspca_dev->streaming)
1605                 setcolors(gspca_dev);
1606         return 0;
1607 }
1608
1609 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1610 {
1611         struct sd *sd = (struct sd *) gspca_dev;
1612
1613         *val = sd->colors;
1614         return 0;
1615 }
1616
1617 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1618 {
1619         struct sd *sd = (struct sd *) gspca_dev;
1620
1621         sd->autogain = val;
1622         if (gspca_dev->streaming)
1623                 setautogain(gspca_dev);
1624         return 0;
1625 }
1626
1627 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1628 {
1629         struct sd *sd = (struct sd *) gspca_dev;
1630
1631         *val = sd->autogain;
1632         return 0;
1633 }
1634
1635 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1636 {
1637         struct sd *sd = (struct sd *) gspca_dev;
1638
1639         sd->vflip = val;
1640         if (gspca_dev->streaming)
1641                 setvflip(sd);
1642         return 0;
1643 }
1644
1645 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1646 {
1647         struct sd *sd = (struct sd *) gspca_dev;
1648
1649         *val = sd->vflip;
1650         return 0;
1651 }
1652
1653 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1654 {
1655         struct sd *sd = (struct sd *) gspca_dev;
1656
1657         sd->infrared = val;
1658         if (gspca_dev->streaming)
1659                 setinfrared(sd);
1660         return 0;
1661 }
1662
1663 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1664 {
1665         struct sd *sd = (struct sd *) gspca_dev;
1666
1667         *val = sd->infrared;
1668         return 0;
1669 }
1670
1671 /* sub-driver description */
1672 static const struct sd_desc sd_desc = {
1673         .name = MODULE_NAME,
1674         .ctrls = sd_ctrls,
1675         .nctrls = ARRAY_SIZE(sd_ctrls),
1676         .config = sd_config,
1677         .init = sd_init,
1678         .start = sd_start,
1679         .stopN = sd_stopN,
1680         .pkt_scan = sd_pkt_scan,
1681         .dq_callback = do_autogain,
1682 };
1683
1684 /* -- module initialisation -- */
1685 #define BSI(bridge, sensor, i2c_addr) \
1686         .driver_info = (BRIDGE_ ## bridge << 16) \
1687                         | (SENSOR_ ## sensor << 8) \
1688                         | (i2c_addr)
1689 static const __devinitdata struct usb_device_id device_table[] = {
1690 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1691         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1692         {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1693 #endif
1694         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1695         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1696 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1697         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1698 #endif
1699         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1700         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1701         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1702 /* bw600.inf:
1703         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1704 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1705 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1706         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1707 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1708         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1709 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1710 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1711         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1712 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1713 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1714         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1715         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1716 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1717         {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1718 #endif
1719 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1720 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1721 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1722         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1723 /*bw600.inf:*/
1724         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1725         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1726         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1727 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1728 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1729         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1730 #endif
1731         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1732         {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1733 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1734         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1735         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1736 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1737 #endif
1738         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1739         {}
1740 };
1741 MODULE_DEVICE_TABLE(usb, device_table);
1742
1743 /* -- device connect -- */
1744 static int sd_probe(struct usb_interface *intf,
1745                     const struct usb_device_id *id)
1746 {
1747         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1748                                 THIS_MODULE);
1749 }
1750
1751 static struct usb_driver sd_driver = {
1752         .name = MODULE_NAME,
1753         .id_table = device_table,
1754         .probe = sd_probe,
1755         .disconnect = gspca_disconnect,
1756 #ifdef CONFIG_PM
1757         .suspend = gspca_suspend,
1758         .resume = gspca_resume,
1759 #endif
1760 };
1761
1762 /* -- module insert / remove -- */
1763 static int __init sd_mod_init(void)
1764 {
1765         if (usb_register(&sd_driver) < 0)
1766                 return -1;
1767         info("registered");
1768         return 0;
1769 }
1770 static void __exit sd_mod_exit(void)
1771 {
1772         usb_deregister(&sd_driver);
1773         info("deregistered");
1774 }
1775
1776 module_init(sd_mod_init);
1777 module_exit(sd_mod_exit);