V4L/DVB (10428): gspca - sonixj: Specific gamma tables per sensor.
[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 int mi0360_probe(struct gspca_dev *gspca_dev)
1013 {
1014         int i, j;
1015         u16 val;
1016         static const u8 probe_tb[][4][8] = {
1017             {
1018                 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1019                 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1020                 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1021                 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1022             },
1023             {
1024                 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1025                 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1026                 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1027                 {}
1028             },
1029         };
1030
1031         for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1032                 reg_w1(gspca_dev, 0x17, 0x62);
1033                 reg_w1(gspca_dev, 0x01, 0x08);
1034                 for (j = 0; j < 3; j++)
1035                         i2c_w8(gspca_dev, probe_tb[i][j]);
1036                 msleep(2);
1037                 reg_r(gspca_dev, 0x0a, 5);
1038                 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1039                 if (probe_tb[i][3][0] != 0)
1040                         i2c_w8(gspca_dev, probe_tb[i][3]);
1041                 reg_w1(gspca_dev, 0x01, 0x29);
1042                 reg_w1(gspca_dev, 0x17, 0x42);
1043                 if (val != 0xffff)
1044                         break;
1045         }
1046         switch (val) {
1047         case 0x823a:
1048                 PDEBUG(D_PROBE, "Sensor mt9v111");
1049                 return SENSOR_MT9V111;
1050         case 0x8243:
1051                 PDEBUG(D_PROBE, "Sensor mi0360");
1052                 return SENSOR_MI0360;
1053         }
1054         PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1055         return SENSOR_MI0360;
1056 }
1057
1058 static int configure_gpio(struct gspca_dev *gspca_dev,
1059                           const u8 *sn9c1xx)
1060 {
1061         struct sd *sd = (struct sd *) gspca_dev;
1062         const u8 *reg9a;
1063         static const u8 reg9a_def[] =
1064                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
1065         static const u8 reg9a_sn9c325[] =
1066                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
1067         static const u8 regd4[] = {0x60, 0x00, 0x00};
1068
1069         reg_w1(gspca_dev, 0xf1, 0x00);
1070         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1071
1072         /* configure gpio */
1073         reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1074         reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1075         reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
1076         switch (sd->bridge) {
1077         case BRIDGE_SN9C325:
1078                 reg9a = reg9a_sn9c325;
1079                 break;
1080         default:
1081                 reg9a = reg9a_def;
1082                 break;
1083         }
1084         reg_w(gspca_dev, 0x9a, reg9a, 6);
1085
1086         reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
1087
1088         reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1089
1090         switch (sd->sensor) {
1091         case SENSOR_MT9V111:
1092                 reg_w1(gspca_dev, 0x01, 0x61);
1093                 reg_w1(gspca_dev, 0x17, 0x61);
1094                 reg_w1(gspca_dev, 0x01, 0x60);
1095                 reg_w1(gspca_dev, 0x01, 0x40);
1096                 break;
1097         case SENSOR_OM6802:
1098                 reg_w1(gspca_dev, 0x02, 0x71);
1099                 reg_w1(gspca_dev, 0x01, 0x42);
1100                 reg_w1(gspca_dev, 0x17, 0x64);
1101                 reg_w1(gspca_dev, 0x01, 0x42);
1102                 break;
1103 /*jfm: from win trace */
1104         case SENSOR_OV7630:
1105                 reg_w1(gspca_dev, 0x01, 0x61);
1106                 reg_w1(gspca_dev, 0x17, 0xe2);
1107                 reg_w1(gspca_dev, 0x01, 0x60);
1108                 reg_w1(gspca_dev, 0x01, 0x40);
1109                 break;
1110         case SENSOR_OV7648:
1111                 reg_w1(gspca_dev, 0x01, 0x63);
1112                 reg_w1(gspca_dev, 0x17, 0x20);
1113                 reg_w1(gspca_dev, 0x01, 0x42);
1114                 break;
1115 /*jfm: from win trace */
1116         case SENSOR_OV7660:
1117                 if (sd->bridge == BRIDGE_SN9C120) {
1118                         reg_w1(gspca_dev, 0x01, 0x61);
1119                         reg_w1(gspca_dev, 0x17, 0x20);
1120                         reg_w1(gspca_dev, 0x01, 0x60);
1121                         reg_w1(gspca_dev, 0x01, 0x40);
1122                         break;
1123                 }
1124                 /* fall thru */
1125         case SENSOR_SP80708:
1126                 reg_w1(gspca_dev, 0x01, 0x63);
1127                 reg_w1(gspca_dev, 0x17, 0x20);
1128                 reg_w1(gspca_dev, 0x01, 0x62);
1129                 reg_w1(gspca_dev, 0x01, 0x42);
1130                 mdelay(100);
1131                 reg_w1(gspca_dev, 0x02, 0x62);
1132                 break;
1133         default:
1134                 reg_w1(gspca_dev, 0x01, 0x43);
1135                 reg_w1(gspca_dev, 0x17, 0x61);
1136                 reg_w1(gspca_dev, 0x01, 0x42);
1137                 if (sd->sensor == SENSOR_HV7131R) {
1138                         if (hv7131r_probe(gspca_dev) < 0)
1139                                 return -ENODEV;
1140                 }
1141                 break;
1142         }
1143         return 0;
1144 }
1145
1146 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1147 {
1148         int i = 0;
1149         static const u8 SetSensorClk[] =        /* 0x08 Mclk */
1150                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1151
1152         while (hv7131r_sensor_init[i][0]) {
1153                 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1154                 i++;
1155         }
1156         i2c_w8(gspca_dev, SetSensorClk);
1157 }
1158
1159 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1160 {
1161         int i = 0;
1162
1163         while (mi0360_sensor_init[i][0]) {
1164                 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1165                 i++;
1166         }
1167 }
1168
1169 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1170 {
1171         int i = 0;
1172
1173         while (mo4000_sensor_init[i][0]) {
1174                 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1175                 i++;
1176         }
1177 }
1178
1179 static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1180 {
1181         int i = 0;
1182
1183         i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1184         i++;
1185         msleep(20);
1186         while (mt9v111_sensor_init[i][0]) {
1187                 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1188                 i++;
1189         }
1190 }
1191
1192 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1193 {
1194         int i = 0;
1195
1196         while (om6802_sensor_init[i][0]) {
1197                 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1198                 i++;
1199         }
1200 }
1201
1202 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1203 {
1204         int i = 0;
1205
1206         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 76 01 */
1207         i++;
1208         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 (RGB+SRST) */
1209         i++;
1210         msleep(20);
1211         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
1212         i++;
1213         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 */
1214         i++;
1215         msleep(20);
1216         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
1217         i++;
1218 /*jfm:win i2c_r from 00 to 80*/
1219
1220         while (ov7630_sensor_init[i][0]) {
1221                 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1222                 i++;
1223         }
1224 }
1225
1226 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1227 {
1228         int i = 0;
1229
1230         i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1231         i++;
1232 /* win: dble reset */
1233         i2c_w8(gspca_dev, ov7648_sensor_init[i]);       /* reset */
1234         i++;
1235         msleep(20);
1236 /* win: i2c reg read 00..7f */
1237         while (ov7648_sensor_init[i][0]) {
1238                 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1239                 i++;
1240         }
1241 }
1242
1243 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1244 {
1245         int i = 0;
1246
1247         i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
1248         i++;
1249         msleep(20);
1250         while (ov7660_sensor_init[i][0]) {
1251                 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1252                 i++;
1253         }
1254 }
1255
1256 static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1257 {
1258         int i = 0;
1259
1260         i2c_w8(gspca_dev, sp80708_sensor_init[i]);      /* reset SCCB */
1261         i++;
1262         msleep(20);
1263         while (sp80708_sensor_init[i][0]) {
1264                 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1265                 i++;
1266         }
1267 }
1268
1269 /* this function is called at probe time */
1270 static int sd_config(struct gspca_dev *gspca_dev,
1271                         const struct usb_device_id *id)
1272 {
1273         struct sd *sd = (struct sd *) gspca_dev;
1274         struct cam *cam;
1275
1276         cam = &gspca_dev->cam;
1277         cam->cam_mode = vga_mode;
1278         cam->nmodes = ARRAY_SIZE(vga_mode);
1279
1280         sd->bridge = id->driver_info >> 16;
1281         sd->sensor = id->driver_info >> 8;
1282         sd->i2c_base = id->driver_info;
1283
1284         sd->brightness = BRIGHTNESS_DEF;
1285         sd->contrast = CONTRAST_DEF;
1286         sd->colors = COLOR_DEF;
1287         sd->blue = BLUE_BALANCE_DEF;
1288         sd->red = RED_BALANCE_DEF;
1289         sd->gamma = GAMMA_DEF;
1290         sd->autogain = AUTOGAIN_DEF;
1291         sd->ag_cnt = -1;
1292         sd->vflip = VFLIP_DEF;
1293         sd->infrared = INFRARED_DEF;
1294
1295         gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1296         return 0;
1297 }
1298
1299 /* this function is called at probe and resume time */
1300 static int sd_init(struct gspca_dev *gspca_dev)
1301 {
1302         struct sd *sd = (struct sd *) gspca_dev;
1303         u8 regGpio[] = { 0x29, 0x74 };
1304         u8 regF1;
1305
1306         /* setup a selector by bridge */
1307         reg_w1(gspca_dev, 0xf1, 0x01);
1308         reg_r(gspca_dev, 0x00, 1);
1309         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1310         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
1311         regF1 = gspca_dev->usb_buf[0];
1312         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1313         switch (sd->bridge) {
1314         case BRIDGE_SN9C102P:
1315                 if (regF1 != 0x11)
1316                         return -ENODEV;
1317                 reg_w1(gspca_dev, 0x02, regGpio[1]);
1318                 break;
1319         case BRIDGE_SN9C105:
1320                 if (regF1 != 0x11)
1321                         return -ENODEV;
1322                 if (sd->sensor == SENSOR_MI0360) {
1323                         sd->sensor = mi0360_probe(gspca_dev);
1324                         if (sd->sensor == SENSOR_MT9V111)
1325                                 sd->i2c_base = 0x5c;
1326                 }
1327                 reg_w(gspca_dev, 0x01, regGpio, 2);
1328                 break;
1329         case BRIDGE_SN9C120:
1330                 if (regF1 != 0x12)
1331                         return -ENODEV;
1332                 if (sd->sensor == SENSOR_MI0360) {
1333                         sd->sensor = mi0360_probe(gspca_dev);
1334                         if (sd->sensor == SENSOR_MT9V111)
1335                                 sd->i2c_base = 0x5c;
1336                 }
1337                 regGpio[1] = 0x70;
1338                 reg_w(gspca_dev, 0x01, regGpio, 2);
1339                 break;
1340         default:
1341 /*      case BRIDGE_SN9C110: */
1342 /*      case BRIDGE_SN9C325: */
1343                 if (regF1 != 0x12)
1344                         return -ENODEV;
1345                 reg_w1(gspca_dev, 0x02, 0x62);
1346                 break;
1347         }
1348
1349         reg_w1(gspca_dev, 0xf1, 0x01);
1350
1351         return 0;
1352 }
1353
1354 static u32 setexposure(struct gspca_dev *gspca_dev,
1355                         u32 expo)
1356 {
1357         struct sd *sd = (struct sd *) gspca_dev;
1358
1359         switch (sd->sensor) {
1360         case SENSOR_HV7131R: {
1361                 u8 Expodoit[] =
1362                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1363
1364                 Expodoit[3] = expo >> 16;
1365                 Expodoit[4] = expo >> 8;
1366                 Expodoit[5] = expo;
1367                 i2c_w8(gspca_dev, Expodoit);
1368                 break;
1369             }
1370         case SENSOR_MI0360: {
1371                 u8 expoMi[] =           /* exposure 0x0635 -> 4 fp/s 0x10 */
1372                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1373                 static const u8 doit[] =                /* update sensor */
1374                         { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1375                 static const u8 sensorgo[] =            /* sensor on */
1376                         { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1377
1378                 if (expo > 0x0635)
1379                         expo = 0x0635;
1380                 else if (expo < 0x0001)
1381                         expo = 0x0001;
1382                 expoMi[3] = expo >> 8;
1383                 expoMi[4] = expo;
1384                 i2c_w8(gspca_dev, expoMi);
1385                 i2c_w8(gspca_dev, doit);
1386                 i2c_w8(gspca_dev, sensorgo);
1387                 break;
1388             }
1389         case SENSOR_MO4000: {
1390                 u8 expoMof[] =
1391                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1392                 u8 expoMo10[] =
1393                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1394                 static const u8 gainMo[] =
1395                         { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1396
1397                 if (expo > 0x1fff)
1398                         expo = 0x1fff;
1399                 else if (expo < 0x0001)
1400                         expo = 0x0001;
1401                 expoMof[3] = (expo & 0x03fc) >> 2;
1402                 i2c_w8(gspca_dev, expoMof);
1403                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1404                                 | ((expo & 0x0003) << 4);
1405                 i2c_w8(gspca_dev, expoMo10);
1406                 i2c_w8(gspca_dev, gainMo);
1407                 PDEBUG(D_FRAM, "set exposure %d",
1408                         ((expoMo10[3] & 0x07) << 10)
1409                         | (expoMof[3] << 2)
1410                         | ((expoMo10[3] & 0x30) >> 4));
1411                 break;
1412             }
1413         case SENSOR_MT9V111: {
1414                 u8 expo_c1[] =
1415                         { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1416
1417                 if (expo > 0x0280)
1418                         expo = 0x0280;
1419                 else if (expo < 0x0040)
1420                         expo = 0x0040;
1421                 expo_c1[3] = expo >> 8;
1422                 expo_c1[4] = expo;
1423                 i2c_w8(gspca_dev, expo_c1);
1424                 break;
1425             }
1426         case SENSOR_OM6802: {
1427                 u8 gainOm[] =
1428                         { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1429
1430                 if (expo > 0x03ff)
1431                         expo = 0x03ff;
1432                  if (expo < 0x0001)
1433                         expo = 0x0001;
1434                 gainOm[3] = expo >> 2;
1435                 i2c_w8(gspca_dev, gainOm);
1436                 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1437                 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1438                 break;
1439             }
1440         }
1441         return expo;
1442 }
1443
1444 static void setbrightness(struct gspca_dev *gspca_dev)
1445 {
1446         struct sd *sd = (struct sd *) gspca_dev;
1447         unsigned int expo;
1448         u8 k2;
1449
1450         k2 = ((int) sd->brightness - 0x8000) >> 10;
1451         switch (sd->sensor) {
1452         case SENSOR_HV7131R:
1453                 expo = sd->brightness << 4;
1454                 if (expo > 0x002dc6c0)
1455                         expo = 0x002dc6c0;
1456                 else if (expo < 0x02a0)
1457                         expo = 0x02a0;
1458                 sd->exposure = setexposure(gspca_dev, expo);
1459                 break;
1460         case SENSOR_MI0360:
1461         case SENSOR_MO4000:
1462                 expo = sd->brightness >> 4;
1463                 sd->exposure = setexposure(gspca_dev, expo);
1464                 break;
1465         case SENSOR_MT9V111:
1466                 expo = sd->brightness >> 8;
1467                 sd->exposure = setexposure(gspca_dev, expo);
1468                 break;
1469         case SENSOR_OM6802:
1470                 expo = sd->brightness >> 6;
1471                 sd->exposure = setexposure(gspca_dev, expo);
1472                 k2 = sd->brightness >> 11;
1473                 break;
1474         }
1475
1476         if (sd->sensor != SENSOR_MT9V111)
1477                 reg_w1(gspca_dev, 0x96, k2);    /* color matrix Y offset */
1478 }
1479
1480 static void setcontrast(struct gspca_dev *gspca_dev)
1481 {
1482         struct sd *sd = (struct sd *) gspca_dev;
1483         u8 k2;
1484         u8 contrast[6];
1485
1486         k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;   /* 10..40 */
1487         contrast[0] = (k2 + 1) / 2;             /* red */
1488         contrast[1] = 0;
1489         contrast[2] = k2;                       /* green */
1490         contrast[3] = 0;
1491         contrast[4] = (k2 + 1) / 5;             /* blue */
1492         contrast[5] = 0;
1493         reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1494 }
1495
1496 static void setcolors(struct gspca_dev *gspca_dev)
1497 {
1498         struct sd *sd = (struct sd *) gspca_dev;
1499         int i, v;
1500         u8 reg8a[12];                   /* U & V gains */
1501         static s16 uv[6] = {            /* same as reg84 in signed decimal */
1502                 -24, -38, 64,           /* UR UG UB */
1503                  62, -51, -9            /* VR VG VB */
1504         };
1505         for (i = 0; i < 6; i++) {
1506                 v = uv[i] * sd->colors / COLOR_DEF;
1507                 reg8a[i * 2] = v;
1508                 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1509         }
1510         reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1511 }
1512
1513 static void setredblue(struct gspca_dev *gspca_dev)
1514 {
1515         struct sd *sd = (struct sd *) gspca_dev;
1516
1517         reg_w1(gspca_dev, 0x05, sd->red);
1518 /*      reg_w1(gspca_dev, 0x07, 32); */
1519         reg_w1(gspca_dev, 0x06, sd->blue);
1520 }
1521
1522 static void setgamma(struct gspca_dev *gspca_dev)
1523 {
1524         struct sd *sd = (struct sd *) gspca_dev;
1525         int i;
1526         u8 gamma[17];
1527         const u8 *gamma_base;
1528         static const u8 delta[17] = {
1529                 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1530                 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1531         };
1532
1533         switch (sd->sensor) {
1534         case SENSOR_HV7131R:
1535         case SENSOR_MT9V111:
1536                 gamma_base = gamma_spec_1;
1537                 break;
1538         case SENSOR_SP80708:
1539                 gamma_base = gamma_spec_2;
1540                 break;
1541         default:
1542                 gamma_base = gamma_def;
1543                 break;
1544         }
1545
1546         for (i = 0; i < sizeof gamma; i++)
1547                 gamma[i] = gamma_base[i]
1548                         + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1549         reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1550 }
1551
1552 static void setautogain(struct gspca_dev *gspca_dev)
1553 {
1554         struct sd *sd = (struct sd *) gspca_dev;
1555
1556         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1557                 return;
1558         if (sd->autogain)
1559                 sd->ag_cnt = AG_CNT_START;
1560         else
1561                 sd->ag_cnt = -1;
1562 }
1563
1564 static void setvflip(struct sd *sd)
1565 {
1566         i2c_w1(&sd->gspca_dev, 0x75,                    /* COMN */
1567                 sd->vflip ? 0x82 : 0x02);
1568 }
1569
1570 static void setinfrared(struct sd *sd)
1571 {
1572 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1573 /* Clip */
1574         i2c_w1(&sd->gspca_dev, 0x02,                    /* gpio */
1575                 sd->infrared ? 0x66 : 0x64);
1576 }
1577
1578 /* -- start the camera -- */
1579 static int sd_start(struct gspca_dev *gspca_dev)
1580 {
1581         struct sd *sd = (struct sd *) gspca_dev;
1582         int i;
1583         u8 reg1, reg17, reg18;
1584         const u8 *sn9c1xx;
1585         int mode;
1586         static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1587         static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1588         static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };      /* MI0360 */
1589         static const u8 CE_ov76xx[] =
1590                                 { 0x32, 0xdd, 0x32, 0xdd };
1591
1592         sn9c1xx = sn_tb[(int) sd->sensor];
1593         configure_gpio(gspca_dev, sn9c1xx);
1594
1595         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1596         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1597         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1598         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1599         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1600         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1601         reg_w1(gspca_dev, 0xd3, 0x50);
1602         reg_w1(gspca_dev, 0xc6, 0x00);
1603         reg_w1(gspca_dev, 0xc7, 0x00);
1604         reg_w1(gspca_dev, 0xc8, 0x50);
1605         reg_w1(gspca_dev, 0xc9, 0x3c);
1606         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1607         switch (sd->sensor) {
1608         case SENSOR_MT9V111:
1609                 reg17 = 0xe0;
1610                 break;
1611         case SENSOR_OV7630:
1612                 reg17 = 0xe2;
1613                 break;
1614         case SENSOR_OV7648:
1615                 reg17 = 0x20;
1616                 break;
1617 /*jfm: from win trace */
1618         case SENSOR_OV7660:
1619                 if (sd->bridge == BRIDGE_SN9C120) {
1620                         reg17 = 0xa0;
1621                         break;
1622                 }
1623                 /* fall thru */
1624         default:
1625                 reg17 = 0x60;
1626                 break;
1627         }
1628         reg_w1(gspca_dev, 0x17, reg17);
1629 /* set reg1 was here */
1630         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);    /* red */
1631         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);    /* green */
1632         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);    /* blue */
1633         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1634
1635         setgamma(gspca_dev);
1636
1637         for (i = 0; i < 8; i++)
1638                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1639         switch (sd->sensor) {
1640         case SENSOR_MT9V111:
1641                 reg_w1(gspca_dev, 0x9a, 0x07);
1642                 reg_w1(gspca_dev, 0x99, 0x59);
1643                 break;
1644         case SENSOR_OV7648:
1645                 reg_w1(gspca_dev, 0x9a, 0x0a);
1646                 reg_w1(gspca_dev, 0x99, 0x60);
1647                 break;
1648         case SENSOR_SP80708:
1649                 reg_w1(gspca_dev, 0x9a, 0x05);
1650                 reg_w1(gspca_dev, 0x99, 0x59);
1651                 break;
1652         case SENSOR_OV7660:
1653                 if (sd->bridge == BRIDGE_SN9C120) {
1654                         reg_w1(gspca_dev, 0x9a, 0x05);
1655                         break;
1656                 }
1657                 /* fall thru */
1658         default:
1659                 reg_w1(gspca_dev, 0x9a, 0x08);
1660                 reg_w1(gspca_dev, 0x99, 0x59);
1661                 break;
1662         }
1663
1664         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1665         if (mode)
1666                 reg1 = 0x46;    /* 320x240: clk 48Mhz, video trf enable */
1667         else
1668                 reg1 = 0x06;    /* 640x480: clk 24Mhz, video trf enable */
1669         reg17 = 0x61;           /* 0x:20: enable sensor clock */
1670         switch (sd->sensor) {
1671         case SENSOR_HV7131R:
1672                 hv7131R_InitSensor(gspca_dev);
1673                 break;
1674         case SENSOR_MI0360:
1675                 mi0360_InitSensor(gspca_dev);
1676                 break;
1677         case SENSOR_MO4000:
1678                 mo4000_InitSensor(gspca_dev);
1679                 if (mode) {
1680 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1681                         reg1 = 0x06;    /* clk 24Mz */
1682                 } else {
1683                         reg17 = 0x22;   /* 640 MCKSIZE */
1684 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1685                 }
1686                 break;
1687         case SENSOR_MT9V111:
1688                 mt9v111_InitSensor(gspca_dev);
1689                 if (mode) {
1690                         reg1 = 0x04;    /* 320 clk 48Mhz */
1691                 } else {
1692 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1693                         reg17 = 0xe2;
1694                 }
1695                 break;
1696         case SENSOR_OM6802:
1697                 om6802_InitSensor(gspca_dev);
1698                 reg17 = 0x64;           /* 640 MCKSIZE */
1699                 break;
1700         case SENSOR_OV7630:
1701                 ov7630_InitSensor(gspca_dev);
1702                 setvflip(sd);
1703                 reg17 = 0xe2;
1704                 reg1 = 0x44;
1705                 break;
1706         case SENSOR_OV7648:
1707                 ov7648_InitSensor(gspca_dev);
1708                 reg17 = 0x21;
1709 /*              reg1 = 0x42;             * 42 - 46? */
1710                 break;
1711         case SENSOR_OV7660:
1712                 ov7660_InitSensor(gspca_dev);
1713                 if (sd->bridge == BRIDGE_SN9C120) {
1714                         if (mode) {             /* 320x240 - 160x120 */
1715                                 reg17 = 0xa2;
1716                                 reg1 = 0x44;    /* 48 Mhz, video trf eneble */
1717                         }
1718                 } else {
1719                         reg17 = 0x22;
1720                         reg1 = 0x06;    /* 24 Mhz, video trf eneble
1721                                          * inverse power down */
1722                 }
1723                 break;
1724         default:
1725 /*      case SENSOR_SP80708: */
1726                 sp80708_InitSensor(gspca_dev);
1727                 if (mode) {
1728 /*??                    reg1 = 0x04;     * 320 clk 48Mhz */
1729                 } else {
1730                         reg1 = 0x46;     /* 640 clk 48Mz */
1731                         reg17 = 0xa2;
1732                 }
1733                 break;
1734         }
1735         reg_w(gspca_dev, 0xc0, C0, 6);
1736         reg_w(gspca_dev, 0xca, CA, 4);
1737         switch (sd->sensor) {
1738         case SENSOR_OV7630:
1739         case SENSOR_OV7648:
1740         case SENSOR_OV7660:
1741                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1742                 break;
1743         default:
1744                 reg_w(gspca_dev, 0xce, CE, 4);
1745                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1746                 break;
1747         }
1748
1749         /* here change size mode 0 -> VGA; 1 -> CIF */
1750         reg18 = sn9c1xx[0x18] | (mode << 4);
1751         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1752
1753         reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1754         reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
1755
1756         reg_w1(gspca_dev, 0x18, reg18);
1757
1758         reg_w1(gspca_dev, 0x17, reg17);
1759         reg_w1(gspca_dev, 0x01, reg1);
1760         switch (sd->sensor) {
1761         case SENSOR_OV7630:
1762                 setvflip(sd);
1763                 break;
1764         }
1765         setbrightness(gspca_dev);
1766         setcontrast(gspca_dev);
1767         setautogain(gspca_dev);
1768         return 0;
1769 }
1770
1771 static void sd_stopN(struct gspca_dev *gspca_dev)
1772 {
1773         struct sd *sd = (struct sd *) gspca_dev;
1774         static const u8 stophv7131[] =
1775                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1776         static const u8 stopmi0360[] =
1777                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1778         static const u8 stopov7648[] =
1779                 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1780         u8 data;
1781         const u8 *sn9c1xx;
1782
1783         data = 0x0b;
1784         switch (sd->sensor) {
1785         case SENSOR_HV7131R:
1786                 i2c_w8(gspca_dev, stophv7131);
1787                 data = 0x2b;
1788                 break;
1789         case SENSOR_MI0360:
1790                 i2c_w8(gspca_dev, stopmi0360);
1791                 data = 0x29;
1792                 break;
1793         case SENSOR_OV7648:
1794                 i2c_w8(gspca_dev, stopov7648);
1795                 /* fall thru */
1796         case SENSOR_MT9V111:
1797         case SENSOR_OV7630:
1798                 data = 0x29;
1799                 break;
1800         default:
1801 /*      case SENSOR_MO4000: */
1802 /*      case SENSOR_OV7660: */
1803                 break;
1804         }
1805         sn9c1xx = sn_tb[(int) sd->sensor];
1806         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1807         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1808         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1809         reg_w1(gspca_dev, 0x01, data);
1810         reg_w1(gspca_dev, 0xf1, 0x00);
1811 }
1812
1813 static void do_autogain(struct gspca_dev *gspca_dev)
1814 {
1815         struct sd *sd = (struct sd *) gspca_dev;
1816         int delta;
1817         int expotimes;
1818         u8 luma_mean = 130;
1819         u8 luma_delta = 20;
1820
1821         /* Thanks S., without your advice, autobright should not work :) */
1822         if (sd->ag_cnt < 0)
1823                 return;
1824         if (--sd->ag_cnt >= 0)
1825                 return;
1826         sd->ag_cnt = AG_CNT_START;
1827
1828         delta = atomic_read(&sd->avg_lum);
1829         PDEBUG(D_FRAM, "mean lum %d", delta);
1830         if (delta < luma_mean - luma_delta ||
1831             delta > luma_mean + luma_delta) {
1832                 switch (sd->sensor) {
1833                 case SENSOR_HV7131R:
1834                         expotimes = sd->exposure >> 8;
1835                         expotimes += (luma_mean - delta) >> 4;
1836                         if (expotimes < 0)
1837                                 expotimes = 0;
1838                         sd->exposure = setexposure(gspca_dev,
1839                                         (unsigned int) (expotimes << 8));
1840                         break;
1841                 default:
1842 /*              case SENSOR_MO4000: */
1843 /*              case SENSOR_MI0360: */
1844 /*              case SENSOR_MT9V111: */
1845 /*              case SENSOR_OM6802: */
1846                         expotimes = sd->exposure;
1847                         expotimes += (luma_mean - delta) >> 6;
1848                         if (expotimes < 0)
1849                                 expotimes = 0;
1850                         sd->exposure = setexposure(gspca_dev,
1851                                                    (unsigned int) expotimes);
1852                         setredblue(gspca_dev);
1853                         break;
1854                 }
1855         }
1856 }
1857
1858 /* scan the URB packets */
1859 /* This function is run at interrupt level. */
1860 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1861                         struct gspca_frame *frame,      /* target */
1862                         u8 *data,                       /* isoc packet */
1863                         int len)                        /* iso packet length */
1864 {
1865         struct sd *sd = (struct sd *) gspca_dev;
1866         int sof, avg_lum;
1867
1868         sof = len - 64;
1869         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1870
1871                 /* end of frame */
1872                 gspca_frame_add(gspca_dev, LAST_PACKET,
1873                                 frame, data, sof + 2);
1874                 if (sd->ag_cnt < 0)
1875                         return;
1876 /* w1 w2 w3 */
1877 /* w4 w5 w6 */
1878 /* w7 w8 */
1879 /* w4 */
1880                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1881 /* w6 */
1882                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1883 /* w2 */
1884                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1885 /* w8 */
1886                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1887 /* w5 */
1888                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1889                 avg_lum >>= 4;
1890                 atomic_set(&sd->avg_lum, avg_lum);
1891                 return;
1892         }
1893         if (gspca_dev->last_packet_type == LAST_PACKET) {
1894
1895                 /* put the JPEG 422 header */
1896                 jpeg_put_header(gspca_dev, frame, 0x21);
1897         }
1898         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1899 }
1900
1901 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1902 {
1903         struct sd *sd = (struct sd *) gspca_dev;
1904
1905         sd->brightness = val;
1906         if (gspca_dev->streaming)
1907                 setbrightness(gspca_dev);
1908         return 0;
1909 }
1910
1911 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1912 {
1913         struct sd *sd = (struct sd *) gspca_dev;
1914
1915         *val = sd->brightness;
1916         return 0;
1917 }
1918
1919 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1920 {
1921         struct sd *sd = (struct sd *) gspca_dev;
1922
1923         sd->contrast = val;
1924         if (gspca_dev->streaming)
1925                 setcontrast(gspca_dev);
1926         return 0;
1927 }
1928
1929 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1930 {
1931         struct sd *sd = (struct sd *) gspca_dev;
1932
1933         *val = sd->contrast;
1934         return 0;
1935 }
1936
1937 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1938 {
1939         struct sd *sd = (struct sd *) gspca_dev;
1940
1941         sd->colors = val;
1942         if (gspca_dev->streaming)
1943                 setcolors(gspca_dev);
1944         return 0;
1945 }
1946
1947 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1948 {
1949         struct sd *sd = (struct sd *) gspca_dev;
1950
1951         *val = sd->colors;
1952         return 0;
1953 }
1954
1955 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1956 {
1957         struct sd *sd = (struct sd *) gspca_dev;
1958
1959         sd->blue = val;
1960         if (gspca_dev->streaming)
1961                 setredblue(gspca_dev);
1962         return 0;
1963 }
1964
1965 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1966 {
1967         struct sd *sd = (struct sd *) gspca_dev;
1968
1969         *val = sd->blue;
1970         return 0;
1971 }
1972
1973 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1974 {
1975         struct sd *sd = (struct sd *) gspca_dev;
1976
1977         sd->red = val;
1978         if (gspca_dev->streaming)
1979                 setredblue(gspca_dev);
1980         return 0;
1981 }
1982
1983 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1984 {
1985         struct sd *sd = (struct sd *) gspca_dev;
1986
1987         *val = sd->red;
1988         return 0;
1989 }
1990
1991 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1992 {
1993         struct sd *sd = (struct sd *) gspca_dev;
1994
1995         sd->gamma = val;
1996         if (gspca_dev->streaming)
1997                 setgamma(gspca_dev);
1998         return 0;
1999 }
2000
2001 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2002 {
2003         struct sd *sd = (struct sd *) gspca_dev;
2004
2005         *val = sd->gamma;
2006         return 0;
2007 }
2008
2009 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2010 {
2011         struct sd *sd = (struct sd *) gspca_dev;
2012
2013         sd->autogain = val;
2014         if (gspca_dev->streaming)
2015                 setautogain(gspca_dev);
2016         return 0;
2017 }
2018
2019 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2020 {
2021         struct sd *sd = (struct sd *) gspca_dev;
2022
2023         *val = sd->autogain;
2024         return 0;
2025 }
2026
2027 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2028 {
2029         struct sd *sd = (struct sd *) gspca_dev;
2030
2031         sd->vflip = val;
2032         if (gspca_dev->streaming)
2033                 setvflip(sd);
2034         return 0;
2035 }
2036
2037 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2038 {
2039         struct sd *sd = (struct sd *) gspca_dev;
2040
2041         *val = sd->vflip;
2042         return 0;
2043 }
2044
2045 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2046 {
2047         struct sd *sd = (struct sd *) gspca_dev;
2048
2049         sd->infrared = val;
2050         if (gspca_dev->streaming)
2051                 setinfrared(sd);
2052         return 0;
2053 }
2054
2055 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2056 {
2057         struct sd *sd = (struct sd *) gspca_dev;
2058
2059         *val = sd->infrared;
2060         return 0;
2061 }
2062
2063 /* sub-driver description */
2064 static const struct sd_desc sd_desc = {
2065         .name = MODULE_NAME,
2066         .ctrls = sd_ctrls,
2067         .nctrls = ARRAY_SIZE(sd_ctrls),
2068         .config = sd_config,
2069         .init = sd_init,
2070         .start = sd_start,
2071         .stopN = sd_stopN,
2072         .pkt_scan = sd_pkt_scan,
2073         .dq_callback = do_autogain,
2074 };
2075
2076 /* -- module initialisation -- */
2077 #define BSI(bridge, sensor, i2c_addr) \
2078         .driver_info = (BRIDGE_ ## bridge << 16) \
2079                         | (SENSOR_ ## sensor << 8) \
2080                         | (i2c_addr)
2081 static const __devinitdata struct usb_device_id device_table[] = {
2082 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2083         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
2084         {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
2085 #endif
2086         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2087         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
2088 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2089         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
2090 #endif
2091         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2092         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2093         {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2094         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2095 /* bw600.inf:
2096         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2097 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2098 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2099         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2100 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2101         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2102 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2103 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2104         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2105 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2106 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2107         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2108         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2109 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2110         {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2111 #endif
2112 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2113 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2114 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2115         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2116 /*bw600.inf:*/
2117         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
2118         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
2119         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
2120 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
2121 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2122         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2123 #endif
2124         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2125         {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2126 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2127         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2128         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2129 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
2130 #endif
2131         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
2132         {}
2133 };
2134 MODULE_DEVICE_TABLE(usb, device_table);
2135
2136 /* -- device connect -- */
2137 static int sd_probe(struct usb_interface *intf,
2138                     const struct usb_device_id *id)
2139 {
2140         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2141                                 THIS_MODULE);
2142 }
2143
2144 static struct usb_driver sd_driver = {
2145         .name = MODULE_NAME,
2146         .id_table = device_table,
2147         .probe = sd_probe,
2148         .disconnect = gspca_disconnect,
2149 #ifdef CONFIG_PM
2150         .suspend = gspca_suspend,
2151         .resume = gspca_resume,
2152 #endif
2153 };
2154
2155 /* -- module insert / remove -- */
2156 static int __init sd_mod_init(void)
2157 {
2158         int ret;
2159         ret = usb_register(&sd_driver);
2160         if (ret < 0)
2161                 return ret;
2162         info("registered");
2163         return 0;
2164 }
2165 static void __exit sd_mod_exit(void)
2166 {
2167         usb_deregister(&sd_driver);
2168         info("deregistered");
2169 }
2170
2171 module_init(sd_mod_init);
2172 module_exit(sd_mod_exit);