V4L/DVB (9842): gspca: Center the brightness in sonixj.
[safe/jmp/linux-2.6] / 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 0x8000
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 static void setbrightness(struct gspca_dev *gspca_dev)
1127 {
1128         struct sd *sd = (struct sd *) gspca_dev;
1129         unsigned int expo;
1130         __u8 k2;
1131
1132         k2 = ((int) sd->brightness - 0x8000) >> 10;
1133         switch (sd->sensor) {
1134         case SENSOR_HV7131R:
1135                 expo = sd->brightness << 4;
1136                 if (expo > 0x002dc6c0)
1137                         expo = 0x002dc6c0;
1138                 else if (expo < 0x02a0)
1139                         expo = 0x02a0;
1140                 sd->exposure = setexposure(gspca_dev, expo);
1141                 break;
1142         case SENSOR_MI0360:
1143         case SENSOR_MO4000:
1144                 expo = sd->brightness >> 4;
1145                 sd->exposure = setexposure(gspca_dev, expo);
1146                 break;
1147         case SENSOR_OM6802:
1148                 expo = sd->brightness >> 6;
1149                 sd->exposure = setexposure(gspca_dev, expo);
1150                 k2 = sd->brightness >> 11;
1151                 break;
1152         }
1153
1154         reg_w1(gspca_dev, 0x96, k2);            /* color matrix Y offset */
1155 }
1156
1157 static void setcontrast(struct gspca_dev *gspca_dev)
1158 {
1159         struct sd *sd = (struct sd *) gspca_dev;
1160         __u8 k2;
1161         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1162
1163         k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;   /* 10..40 */
1164         contrast[0] = (k2 + 1) / 2;             /* red */
1165         contrast[2] = k2;                       /* green */
1166         contrast[4] = (k2 + 1) / 5;             /* blue */
1167         reg_w(gspca_dev, 0x84, contrast, 6);
1168 }
1169
1170 static void setcolors(struct gspca_dev *gspca_dev)
1171 {
1172         struct sd *sd = (struct sd *) gspca_dev;
1173         __u8 blue, red;
1174
1175         if (sd->colors >= 32) {
1176                 red = 32 + (sd->colors - 32) / 2;
1177                 blue = 64 - sd->colors;
1178         } else {
1179                 red = sd->colors;
1180                 blue = 32 + (32 - sd->colors) / 2;
1181         }
1182         reg_w1(gspca_dev, 0x05, red);
1183 /*      reg_w1(gspca_dev, 0x07, 32); */
1184         reg_w1(gspca_dev, 0x06, blue);
1185 }
1186
1187 static void setautogain(struct gspca_dev *gspca_dev)
1188 {
1189         struct sd *sd = (struct sd *) gspca_dev;
1190
1191         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1192                 return;
1193         if (sd->autogain)
1194                 sd->ag_cnt = AG_CNT_START;
1195         else
1196                 sd->ag_cnt = -1;
1197 }
1198
1199 static void setvflip(struct sd *sd)
1200 {
1201         i2c_w1(&sd->gspca_dev, 0x75,                    /* COMN */
1202                 sd->vflip ? 0x82 : 0x02);
1203 }
1204
1205 static void setinfrared(struct sd *sd)
1206 {
1207 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1208 /* Clip */
1209         i2c_w1(&sd->gspca_dev, 0x02,                    /* gpio */
1210                 sd->infrared ? 0x66 : 0x64);
1211 }
1212
1213 /* -- start the camera -- */
1214 static int sd_start(struct gspca_dev *gspca_dev)
1215 {
1216         struct sd *sd = (struct sd *) gspca_dev;
1217         int i;
1218         __u8 reg1, reg17, reg18;
1219         const __u8 *sn9c1xx;
1220         int mode;
1221         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1222         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1223         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
1224         static const __u8 CE_ov76xx[] =
1225                                 { 0x32, 0xdd, 0x32, 0xdd };
1226
1227         sn9c1xx = sn_tb[(int) sd->sensor];
1228         configure_gpio(gspca_dev, sn9c1xx);
1229
1230         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1231         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1232         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1233         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1234         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1235         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1236         reg_w1(gspca_dev, 0xd3, 0x50);
1237         reg_w1(gspca_dev, 0xc6, 0x00);
1238         reg_w1(gspca_dev, 0xc7, 0x00);
1239         reg_w1(gspca_dev, 0xc8, 0x50);
1240         reg_w1(gspca_dev, 0xc9, 0x3c);
1241         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1242         switch (sd->sensor) {
1243         case SENSOR_OV7630:
1244                 reg17 = 0xe2;
1245                 break;
1246         case SENSOR_OV7648:
1247                 reg17 = 0x20;
1248                 break;
1249 /*jfm: from win trace */
1250         case SENSOR_OV7660:
1251                 if (sd->bridge == BRIDGE_SN9C120) {
1252                         reg17 = 0xa0;
1253                         break;
1254                 }
1255                 /* fall thru */
1256         default:
1257                 reg17 = 0x60;
1258                 break;
1259         }
1260         reg_w1(gspca_dev, 0x17, reg17);
1261 /* set reg1 was here */
1262         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1263         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1264         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1265         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1266         reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1267         for (i = 0; i < 8; i++)
1268                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1269         switch (sd->sensor) {
1270         case SENSOR_OV7648:
1271                 reg_w1(gspca_dev, 0x9a, 0x0a);
1272                 reg_w1(gspca_dev, 0x99, 0x60);
1273                 break;
1274         case SENSOR_OV7660:
1275                 if (sd->bridge == BRIDGE_SN9C120) {
1276                         reg_w1(gspca_dev, 0x9a, 0x05);
1277                         break;
1278                 }
1279                 /* fall thru */
1280         default:
1281                 reg_w1(gspca_dev, 0x9a, 0x08);
1282                 reg_w1(gspca_dev, 0x99, 0x59);
1283                 break;
1284         }
1285
1286         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1287         if (mode)
1288                 reg1 = 0x46;    /* 320x240: clk 48Mhz, video trf enable */
1289         else
1290                 reg1 = 0x06;    /* 640x480: clk 24Mhz, video trf enable */
1291         reg17 = 0x61;           /* 0x:20: enable sensor clock */
1292         switch (sd->sensor) {
1293         case SENSOR_HV7131R:
1294                 hv7131R_InitSensor(gspca_dev);
1295                 break;
1296         case SENSOR_MI0360:
1297                 mi0360_InitSensor(gspca_dev);
1298                 break;
1299         case SENSOR_MO4000:
1300                 mo4000_InitSensor(gspca_dev);
1301                 if (mode) {
1302 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1303                         reg1 = 0x06;    /* clk 24Mz */
1304                 } else {
1305                         reg17 = 0x22;   /* 640 MCKSIZE */
1306 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1307                 }
1308                 break;
1309         case SENSOR_OM6802:
1310                 om6802_InitSensor(gspca_dev);
1311                 reg17 = 0x64;           /* 640 MCKSIZE */
1312                 break;
1313         case SENSOR_OV7630:
1314                 ov7630_InitSensor(gspca_dev);
1315                 setvflip(sd);
1316                 reg17 = 0xe2;
1317                 reg1 = 0x44;
1318                 break;
1319         case SENSOR_OV7648:
1320                 ov7648_InitSensor(gspca_dev);
1321                 reg17 = 0x21;
1322 /*              reg1 = 0x42;             * 42 - 46? */
1323 /*              if (mode)
1324                         ;                * 320x2...
1325                 else
1326                         ;                * 640x... */
1327                 break;
1328         default:
1329 /*      case SENSOR_OV7660: */
1330                 ov7660_InitSensor(gspca_dev);
1331                 if (mode) {
1332 /*                      reg17 = 0x21;    * 320 */
1333 /*                      reg1 = 0x44; */
1334 /*                      reg1 = 0x46;    (done) */
1335                 } else {                        /* 640 */
1336                         if (sd->bridge == BRIDGE_SN9C120) {
1337                                 reg17 = 0xa2;
1338                                 reg1 = 0x44;    /* 48 Mhz, video trf eneble */
1339                         } else {
1340                                 reg17 = 0x22;
1341                                 reg1 = 0x06;    /* 24 Mhz, video trf eneble
1342                                                  * inverse power down */
1343                         }
1344                 }
1345                 break;
1346         }
1347         reg_w(gspca_dev, 0xc0, C0, 6);
1348         reg_w(gspca_dev, 0xca, CA, 4);
1349         switch (sd->sensor) {
1350         case SENSOR_OV7630:
1351         case SENSOR_OV7648:
1352         case SENSOR_OV7660:
1353                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1354                 break;
1355         default:
1356                 reg_w(gspca_dev, 0xce, CE, 4);
1357                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1358                 break;
1359         }
1360
1361         /* here change size mode 0 -> VGA; 1 -> CIF */
1362         reg18 = sn9c1xx[0x18] | (mode << 4);
1363         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1364
1365         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1366         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1367
1368         reg_w1(gspca_dev, 0x18, reg18);
1369
1370         reg_w1(gspca_dev, 0x17, reg17);
1371         reg_w1(gspca_dev, 0x01, reg1);
1372         switch (sd->sensor) {
1373         case SENSOR_MI0360:
1374                 setinfrared(sd);
1375                 break;
1376         case SENSOR_OV7630:
1377                 setvflip(sd);
1378                 break;
1379         }
1380         setbrightness(gspca_dev);
1381         setcontrast(gspca_dev);
1382         setautogain(gspca_dev);
1383         return 0;
1384 }
1385
1386 static void sd_stopN(struct gspca_dev *gspca_dev)
1387 {
1388         struct sd *sd = (struct sd *) gspca_dev;
1389         static const __u8 stophv7131[] =
1390                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1391         static const __u8 stopmi0360[] =
1392                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1393         static const __u8 stopov7648[] =
1394                 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1395         __u8 data;
1396         const __u8 *sn9c1xx;
1397
1398         data = 0x0b;
1399         switch (sd->sensor) {
1400         case SENSOR_HV7131R:
1401                 i2c_w8(gspca_dev, stophv7131);
1402                 data = 0x2b;
1403                 break;
1404         case SENSOR_MI0360:
1405                 i2c_w8(gspca_dev, stopmi0360);
1406                 data = 0x29;
1407                 break;
1408         case SENSOR_OV7648:
1409                 i2c_w8(gspca_dev, stopov7648);
1410                 /* fall thru */
1411         case SENSOR_OV7630:
1412                 data = 0x29;
1413                 break;
1414         default:
1415 /*      case SENSOR_MO4000: */
1416 /*      case SENSOR_OV7660: */
1417                 break;
1418         }
1419         sn9c1xx = sn_tb[(int) sd->sensor];
1420         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1421         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1422         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1423         reg_w1(gspca_dev, 0x01, data);
1424         reg_w1(gspca_dev, 0xf1, 0x00);
1425 }
1426
1427 static void do_autogain(struct gspca_dev *gspca_dev)
1428 {
1429         struct sd *sd = (struct sd *) gspca_dev;
1430         int delta;
1431         int expotimes;
1432         __u8 luma_mean = 130;
1433         __u8 luma_delta = 20;
1434
1435         /* Thanks S., without your advice, autobright should not work :) */
1436         if (sd->ag_cnt < 0)
1437                 return;
1438         if (--sd->ag_cnt >= 0)
1439                 return;
1440         sd->ag_cnt = AG_CNT_START;
1441
1442         delta = atomic_read(&sd->avg_lum);
1443         PDEBUG(D_FRAM, "mean lum %d", delta);
1444         if (delta < luma_mean - luma_delta ||
1445             delta > luma_mean + luma_delta) {
1446                 switch (sd->sensor) {
1447                 case SENSOR_HV7131R:
1448                         expotimes = sd->exposure >> 8;
1449                         expotimes += (luma_mean - delta) >> 4;
1450                         if (expotimes < 0)
1451                                 expotimes = 0;
1452                         sd->exposure = setexposure(gspca_dev,
1453                                         (unsigned int) (expotimes << 8));
1454                         break;
1455                 default:
1456 /*              case SENSOR_MO4000: */
1457 /*              case SENSOR_MI0360: */
1458 /*              case SENSOR_OM6802: */
1459                         expotimes = sd->exposure;
1460                         expotimes += (luma_mean - delta) >> 6;
1461                         if (expotimes < 0)
1462                                 expotimes = 0;
1463                         sd->exposure = setexposure(gspca_dev,
1464                                                    (unsigned int) expotimes);
1465                         setcolors(gspca_dev);
1466                         break;
1467                 }
1468         }
1469 }
1470
1471 /* scan the URB packets */
1472 /* This function is run at interrupt level. */
1473 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1474                         struct gspca_frame *frame,      /* target */
1475                         __u8 *data,                     /* isoc packet */
1476                         int len)                        /* iso packet length */
1477 {
1478         struct sd *sd = (struct sd *) gspca_dev;
1479         int sof, avg_lum;
1480
1481         sof = len - 64;
1482         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1483
1484                 /* end of frame */
1485                 gspca_frame_add(gspca_dev, LAST_PACKET,
1486                                 frame, data, sof + 2);
1487                 if (sd->ag_cnt < 0)
1488                         return;
1489 /* w1 w2 w3 */
1490 /* w4 w5 w6 */
1491 /* w7 w8 */
1492 /* w4 */
1493                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1494 /* w6 */
1495                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1496 /* w2 */
1497                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1498 /* w8 */
1499                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1500 /* w5 */
1501                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1502                 avg_lum >>= 4;
1503                 atomic_set(&sd->avg_lum, avg_lum);
1504                 return;
1505         }
1506         if (gspca_dev->last_packet_type == LAST_PACKET) {
1507
1508                 /* put the JPEG 422 header */
1509                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1510         }
1511         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1512 }
1513
1514 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1515 {
1516         struct sd *sd = (struct sd *) gspca_dev;
1517
1518         sd->brightness = val;
1519         if (gspca_dev->streaming)
1520                 setbrightness(gspca_dev);
1521         return 0;
1522 }
1523
1524 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1525 {
1526         struct sd *sd = (struct sd *) gspca_dev;
1527
1528         *val = sd->brightness;
1529         return 0;
1530 }
1531
1532 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1533 {
1534         struct sd *sd = (struct sd *) gspca_dev;
1535
1536         sd->contrast = val;
1537         if (gspca_dev->streaming)
1538                 setcontrast(gspca_dev);
1539         return 0;
1540 }
1541
1542 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1543 {
1544         struct sd *sd = (struct sd *) gspca_dev;
1545
1546         *val = sd->contrast;
1547         return 0;
1548 }
1549
1550 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1551 {
1552         struct sd *sd = (struct sd *) gspca_dev;
1553
1554         sd->colors = val;
1555         if (gspca_dev->streaming)
1556                 setcolors(gspca_dev);
1557         return 0;
1558 }
1559
1560 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1561 {
1562         struct sd *sd = (struct sd *) gspca_dev;
1563
1564         *val = sd->colors;
1565         return 0;
1566 }
1567
1568 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1569 {
1570         struct sd *sd = (struct sd *) gspca_dev;
1571
1572         sd->autogain = val;
1573         if (gspca_dev->streaming)
1574                 setautogain(gspca_dev);
1575         return 0;
1576 }
1577
1578 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1579 {
1580         struct sd *sd = (struct sd *) gspca_dev;
1581
1582         *val = sd->autogain;
1583         return 0;
1584 }
1585
1586 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1587 {
1588         struct sd *sd = (struct sd *) gspca_dev;
1589
1590         sd->vflip = val;
1591         if (gspca_dev->streaming)
1592                 setvflip(sd);
1593         return 0;
1594 }
1595
1596 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1597 {
1598         struct sd *sd = (struct sd *) gspca_dev;
1599
1600         *val = sd->vflip;
1601         return 0;
1602 }
1603
1604 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1605 {
1606         struct sd *sd = (struct sd *) gspca_dev;
1607
1608         sd->infrared = val;
1609         if (gspca_dev->streaming)
1610                 setinfrared(sd);
1611         return 0;
1612 }
1613
1614 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1615 {
1616         struct sd *sd = (struct sd *) gspca_dev;
1617
1618         *val = sd->infrared;
1619         return 0;
1620 }
1621
1622 /* sub-driver description */
1623 static const struct sd_desc sd_desc = {
1624         .name = MODULE_NAME,
1625         .ctrls = sd_ctrls,
1626         .nctrls = ARRAY_SIZE(sd_ctrls),
1627         .config = sd_config,
1628         .init = sd_init,
1629         .start = sd_start,
1630         .stopN = sd_stopN,
1631         .pkt_scan = sd_pkt_scan,
1632         .dq_callback = do_autogain,
1633 };
1634
1635 /* -- module initialisation -- */
1636 #define BSI(bridge, sensor, i2c_addr) \
1637         .driver_info = (BRIDGE_ ## bridge << 16) \
1638                         | (SENSOR_ ## sensor << 8) \
1639                         | (i2c_addr)
1640 static const __devinitdata struct usb_device_id device_table[] = {
1641 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1642         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1643         {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1644 #endif
1645         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1646         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1647 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1648         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1649 #endif
1650         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1651         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1652         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1653 /* bw600.inf:
1654         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1655 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1656 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1657         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1658 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1659         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1660 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1661 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1662         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1663 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1664 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1665         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1666         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1667 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1668         {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1669 #endif
1670 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1671 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1672 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1673         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1674 /*bw600.inf:*/
1675         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1676         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1677         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1678 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1679 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1680         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1681 #endif
1682         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1683         {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1684 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1685         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1686         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1687 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1688 #endif
1689         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1690         {}
1691 };
1692 MODULE_DEVICE_TABLE(usb, device_table);
1693
1694 /* -- device connect -- */
1695 static int sd_probe(struct usb_interface *intf,
1696                     const struct usb_device_id *id)
1697 {
1698         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1699                                 THIS_MODULE);
1700 }
1701
1702 static struct usb_driver sd_driver = {
1703         .name = MODULE_NAME,
1704         .id_table = device_table,
1705         .probe = sd_probe,
1706         .disconnect = gspca_disconnect,
1707 #ifdef CONFIG_PM
1708         .suspend = gspca_suspend,
1709         .resume = gspca_resume,
1710 #endif
1711 };
1712
1713 /* -- module insert / remove -- */
1714 static int __init sd_mod_init(void)
1715 {
1716         if (usb_register(&sd_driver) < 0)
1717                 return -1;
1718         info("registered");
1719         return 0;
1720 }
1721 static void __exit sd_mod_exit(void)
1722 {
1723         usb_deregister(&sd_driver);
1724         info("deregistered");
1725 }
1726
1727 module_init(sd_mod_init);
1728 module_exit(sd_mod_exit);