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