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