Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[pandora-kernel.git] / drivers / media / video / gspca / sonixj.c
1 /*
2  * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3  *
4  * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
5  * Copyright (C) 2005 Michel Xhaard mxhaard@magic.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 <linux/input.h>
25 #include <linux/slab.h>
26 #include "gspca.h"
27 #include "jpeg.h"
28
29 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
30
31 MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
32 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
33 MODULE_LICENSE("GPL");
34
35 /* specific webcam descriptor */
36 struct sd {
37         struct gspca_dev gspca_dev;     /* !! must be the first item */
38
39         atomic_t avg_lum;
40         u32 exposure;
41
42         u16 brightness;
43         u8 contrast;
44         u8 colors;
45         u8 autogain;
46         u8 blue;
47         u8 red;
48         u8 gamma;
49         u8 vflip;                       /* ov7630/ov7648 only */
50         u8 sharpness;
51         u8 infrared;                    /* mt9v111 only */
52         u8 freq;                        /* ov76xx only */
53         u8 quality;                     /* image quality */
54 #define QUALITY_MIN 60
55 #define QUALITY_MAX 95
56 #define QUALITY_DEF 80
57         u8 jpegqual;                    /* webcam quality */
58
59         u8 reg18;
60
61         s8 ag_cnt;
62 #define AG_CNT_START 13
63
64         u8 bridge;
65 #define BRIDGE_SN9C102P 0
66 #define BRIDGE_SN9C105 1
67 #define BRIDGE_SN9C110 2
68 #define BRIDGE_SN9C120 3
69         u8 sensor;                      /* Type of image sensor chip */
70 enum {
71         SENSOR_ADCM1700,
72         SENSOR_GC0307,
73         SENSOR_HV7131R,
74         SENSOR_MI0360,
75         SENSOR_MO4000,
76         SENSOR_MT9V111,
77         SENSOR_OM6802,
78         SENSOR_OV7630,
79         SENSOR_OV7648,
80         SENSOR_OV7660,
81         SENSOR_PO1030,
82         SENSOR_PO2030N,
83         SENSOR_SOI768,
84         SENSOR_SP80708,
85 } sensors;
86         u8 i2c_addr;
87
88         u8 jpeg_hdr[JPEG_HDR_SZ];
89 };
90
91 /* V4L2 controls supported by the driver */
92 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
93 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
94 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
95 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
96 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
97 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
98 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
99 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
100 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
101 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
102 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
103 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
104 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
105 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
106 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
107 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
108 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
109 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
110 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
111 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
112 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
113 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
114
115 static const struct ctrl sd_ctrls[] = {
116 #define BRIGHTNESS_IDX 0
117         {
118             {
119                 .id      = V4L2_CID_BRIGHTNESS,
120                 .type    = V4L2_CTRL_TYPE_INTEGER,
121                 .name    = "Brightness",
122                 .minimum = 0,
123 #define BRIGHTNESS_MAX 0xffff
124                 .maximum = BRIGHTNESS_MAX,
125                 .step    = 1,
126 #define BRIGHTNESS_DEF 0x8000
127                 .default_value = BRIGHTNESS_DEF,
128             },
129             .set = sd_setbrightness,
130             .get = sd_getbrightness,
131         },
132 #define CONTRAST_IDX 1
133         {
134             {
135                 .id      = V4L2_CID_CONTRAST,
136                 .type    = V4L2_CTRL_TYPE_INTEGER,
137                 .name    = "Contrast",
138                 .minimum = 0,
139 #define CONTRAST_MAX 127
140                 .maximum = CONTRAST_MAX,
141                 .step    = 1,
142 #define CONTRAST_DEF 63
143                 .default_value = CONTRAST_DEF,
144             },
145             .set = sd_setcontrast,
146             .get = sd_getcontrast,
147         },
148 #define COLOR_IDX 2
149         {
150             {
151                 .id      = V4L2_CID_SATURATION,
152                 .type    = V4L2_CTRL_TYPE_INTEGER,
153                 .name    = "Saturation",
154                 .minimum = 0,
155                 .maximum = 40,
156                 .step    = 1,
157 #define COLOR_DEF 25
158                 .default_value = COLOR_DEF,
159             },
160             .set = sd_setcolors,
161             .get = sd_getcolors,
162         },
163 #define BLUE_BALANCE_IDX 3
164         {
165             {
166                 .id      = V4L2_CID_BLUE_BALANCE,
167                 .type    = V4L2_CTRL_TYPE_INTEGER,
168                 .name    = "Blue Balance",
169                 .minimum = 24,
170                 .maximum = 40,
171                 .step    = 1,
172 #define BLUE_BALANCE_DEF 32
173                 .default_value = BLUE_BALANCE_DEF,
174             },
175             .set = sd_setblue_balance,
176             .get = sd_getblue_balance,
177         },
178 #define RED_BALANCE_IDX 4
179         {
180             {
181                 .id      = V4L2_CID_RED_BALANCE,
182                 .type    = V4L2_CTRL_TYPE_INTEGER,
183                 .name    = "Red Balance",
184                 .minimum = 24,
185                 .maximum = 40,
186                 .step    = 1,
187 #define RED_BALANCE_DEF 32
188                 .default_value = RED_BALANCE_DEF,
189             },
190             .set = sd_setred_balance,
191             .get = sd_getred_balance,
192         },
193 #define GAMMA_IDX 5
194         {
195             {
196                 .id      = V4L2_CID_GAMMA,
197                 .type    = V4L2_CTRL_TYPE_INTEGER,
198                 .name    = "Gamma",
199                 .minimum = 0,
200                 .maximum = 40,
201                 .step    = 1,
202 #define GAMMA_DEF 20
203                 .default_value = GAMMA_DEF,
204             },
205             .set = sd_setgamma,
206             .get = sd_getgamma,
207         },
208 #define AUTOGAIN_IDX 6
209         {
210             {
211                 .id      = V4L2_CID_AUTOGAIN,
212                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
213                 .name    = "Auto Gain",
214                 .minimum = 0,
215                 .maximum = 1,
216                 .step    = 1,
217 #define AUTOGAIN_DEF 1
218                 .default_value = AUTOGAIN_DEF,
219             },
220             .set = sd_setautogain,
221             .get = sd_getautogain,
222         },
223 /* ov7630/ov7648 only */
224 #define VFLIP_IDX 7
225         {
226             {
227                 .id      = V4L2_CID_VFLIP,
228                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
229                 .name    = "Vflip",
230                 .minimum = 0,
231                 .maximum = 1,
232                 .step    = 1,
233 #define VFLIP_DEF 0
234                 .default_value = VFLIP_DEF,
235             },
236             .set = sd_setvflip,
237             .get = sd_getvflip,
238         },
239 #define SHARPNESS_IDX 8
240         {
241             {
242                 .id      = V4L2_CID_SHARPNESS,
243                 .type    = V4L2_CTRL_TYPE_INTEGER,
244                 .name    = "Sharpness",
245                 .minimum = 0,
246                 .maximum = 255,
247                 .step    = 1,
248 #define SHARPNESS_DEF 90
249                 .default_value = SHARPNESS_DEF,
250             },
251             .set = sd_setsharpness,
252             .get = sd_getsharpness,
253         },
254 /* mt9v111 only */
255 #define INFRARED_IDX 9
256         {
257             {
258                 .id      = V4L2_CID_INFRARED,
259                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
260                 .name    = "Infrared",
261                 .minimum = 0,
262                 .maximum = 1,
263                 .step    = 1,
264 #define INFRARED_DEF 0
265                 .default_value = INFRARED_DEF,
266             },
267             .set = sd_setinfrared,
268             .get = sd_getinfrared,
269         },
270 /* ov7630/ov7648/ov7660 only */
271 #define FREQ_IDX 10
272         {
273             {
274                 .id      = V4L2_CID_POWER_LINE_FREQUENCY,
275                 .type    = V4L2_CTRL_TYPE_MENU,
276                 .name    = "Light frequency filter",
277                 .minimum = 0,
278                 .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
279                 .step    = 1,
280 #define FREQ_DEF 1
281                 .default_value = FREQ_DEF,
282             },
283             .set = sd_setfreq,
284             .get = sd_getfreq,
285         },
286 };
287
288 /* table of the disabled controls */
289 static const __u32 ctrl_dis[] = {
290 [SENSOR_ADCM1700] =     (1 << AUTOGAIN_IDX) |
291                         (1 << INFRARED_IDX) |
292                         (1 << VFLIP_IDX) |
293                         (1 << FREQ_IDX),
294
295 [SENSOR_GC0307] =       (1 << INFRARED_IDX) |
296                         (1 << VFLIP_IDX) |
297                         (1 << FREQ_IDX),
298
299 [SENSOR_HV7131R] =      (1 << INFRARED_IDX) |
300                         (1 << FREQ_IDX),
301
302 [SENSOR_MI0360] =       (1 << INFRARED_IDX) |
303                         (1 << VFLIP_IDX) |
304                         (1 << FREQ_IDX),
305
306 [SENSOR_MO4000] =       (1 << INFRARED_IDX) |
307                         (1 << VFLIP_IDX) |
308                         (1 << FREQ_IDX),
309
310 [SENSOR_MT9V111] =      (1 << VFLIP_IDX) |
311                         (1 << FREQ_IDX),
312
313 [SENSOR_OM6802] =       (1 << INFRARED_IDX) |
314                         (1 << VFLIP_IDX) |
315                         (1 << FREQ_IDX),
316
317 [SENSOR_OV7630] =       (1 << INFRARED_IDX),
318
319 [SENSOR_OV7648] =       (1 << INFRARED_IDX),
320
321 [SENSOR_OV7660] =       (1 << AUTOGAIN_IDX) |
322                         (1 << INFRARED_IDX) |
323                         (1 << VFLIP_IDX),
324
325 [SENSOR_PO1030] =       (1 << AUTOGAIN_IDX) |
326                         (1 << INFRARED_IDX) |
327                         (1 << VFLIP_IDX) |
328                         (1 << FREQ_IDX),
329
330 [SENSOR_PO2030N] =      (1 << AUTOGAIN_IDX) |
331                         (1 << INFRARED_IDX) |
332                         (1 << VFLIP_IDX) |
333                         (1 << FREQ_IDX),
334 [SENSOR_SOI768] =       (1 << AUTOGAIN_IDX) |
335                         (1 << INFRARED_IDX) |
336                         (1 << VFLIP_IDX) |
337                         (1 << FREQ_IDX),
338
339 [SENSOR_SP80708] =      (1 << AUTOGAIN_IDX) |
340                         (1 << INFRARED_IDX) |
341                         (1 << VFLIP_IDX) |
342                         (1 << FREQ_IDX),
343 };
344
345 static const struct v4l2_pix_format cif_mode[] = {
346         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
347                 .bytesperline = 352,
348                 .sizeimage = 352 * 288 * 4 / 8 + 590,
349                 .colorspace = V4L2_COLORSPACE_JPEG,
350                 .priv = 0},
351 };
352 static const struct v4l2_pix_format vga_mode[] = {
353         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
354                 .bytesperline = 160,
355                 .sizeimage = 160 * 120 * 4 / 8 + 590,
356                 .colorspace = V4L2_COLORSPACE_JPEG,
357                 .priv = 2},
358         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
359                 .bytesperline = 320,
360                 .sizeimage = 320 * 240 * 3 / 8 + 590,
361                 .colorspace = V4L2_COLORSPACE_JPEG,
362                 .priv = 1},
363         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
364                 .bytesperline = 640,
365                 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
366                 .sizeimage = 640 * 480 * 3 / 4 + 590,
367                 .colorspace = V4L2_COLORSPACE_JPEG,
368                 .priv = 0},
369 };
370
371 static const u8 sn_adcm1700[0x1c] = {
372 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
373         0x00,   0x43,   0x60,   0x00,   0x1a,   0x00,   0x00,   0x00,
374 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
375         0x80,   0x51,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
376 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
377         0x03,   0x00,   0x05,   0x01,   0x05,   0x16,   0x12,   0x42,
378 /*      reg18   reg19   reg1a   reg1b */
379         0x06,   0x00,   0x00,   0x00
380 };
381
382 static const u8 sn_gc0307[0x1c] = {
383 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
384         0x00,   0x61,   0x62,   0x00,   0x1a,   0x00,   0x00,   0x00,
385 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
386         0x80,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
387 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
388         0x03,   0x00,   0x03,   0x01,   0x08,   0x28,   0x1e,   0x02,
389 /*      reg18   reg19   reg1a   reg1b */
390         0x06,   0x00,   0x00,   0x00
391 };
392
393 static const u8 sn_hv7131[0x1c] = {
394 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
395         0x00,   0x03,   0x64,   0x00,   0x1a,   0x20,   0x20,   0x20,
396 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
397         0x81,   0x11,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
398 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
399         0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
400 /*      reg18   reg19   reg1a   reg1b */
401         0x0a,   0x00,   0x00,   0x00
402 };
403
404 static const u8 sn_mi0360[0x1c] = {
405 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
406         0x00,   0x61,   0x44,   0x00,   0x1a,   0x20,   0x20,   0x20,
407 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
408         0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
409 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
410         0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
411 /*      reg18   reg19   reg1a   reg1b */
412         0x06,   0x00,   0x00,   0x00
413 };
414
415 static const u8 sn_mo4000[0x1c] = {
416 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
417         0x00,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
418 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
419         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
420 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
421         0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
422 /*      reg18   reg19   reg1a   reg1b */
423         0x08,   0x00,   0x00,   0x00
424 };
425
426 static const u8 sn_mt9v111[0x1c] = {
427 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
428         0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
429 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
430         0x81,   0x5c,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
431 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
432         0x03,   0x00,   0x00,   0x02,   0x1c,   0x28,   0x1e,   0x40,
433 /*      reg18   reg19   reg1a   reg1b */
434         0x06,   0x00,   0x00,   0x00
435 };
436
437 static const u8 sn_om6802[0x1c] = {
438 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
439         0x00,   0x23,   0x72,   0x00,   0x1a,   0x20,   0x20,   0x19,
440 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
441         0x80,   0x34,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
442 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
443         0x03,   0x00,   0x51,   0x01,   0x00,   0x28,   0x1e,   0x40,
444 /*      reg18   reg19   reg1a   reg1b */
445         0x05,   0x00,   0x00,   0x00
446 };
447
448 static const u8 sn_ov7630[0x1c] = {
449 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
450         0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
451 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
452         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
453 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
454         0x03,   0x00,   0x04,   0x01,   0x0a,   0x28,   0x1e,   0xc2,
455 /*      reg18   reg19   reg1a   reg1b */
456         0x0b,   0x00,   0x00,   0x00
457 };
458
459 static const u8 sn_ov7648[0x1c] = {
460 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
461         0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
462 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
463         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
464 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
465         0x03,   0x00,   0x00,   0x01,   0x00,   0x28,   0x1e,   0x00,
466 /*      reg18   reg19   reg1a   reg1b */
467         0x0b,   0x00,   0x00,   0x00
468 };
469
470 static const u8 sn_ov7660[0x1c] = {
471 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
472         0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
473 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
474         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
475 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
476         0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
477 /*      reg18   reg19   reg1a   reg1b */
478         0x07,   0x00,   0x00,   0x00
479 };
480
481 static const u8 sn_po1030[0x1c] = {
482 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
483         0x00,   0x21,   0x62,   0x00,   0x1a,   0x20,   0x20,   0x20,
484 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
485         0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
486 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
487         0x03,   0x00,   0x00,   0x06,   0x06,   0x28,   0x1e,   0x00,
488 /*      reg18   reg19   reg1a   reg1b */
489         0x07,   0x00,   0x00,   0x00
490 };
491
492 static const u8 sn_po2030n[0x1c] = {
493 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
494         0x00,   0x63,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
495 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
496         0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
497 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
498         0x03,   0x00,   0x00,   0x01,   0x14,   0x28,   0x1e,   0x00,
499 /*      reg18   reg19   reg1a   reg1b */
500         0x07,   0x00,   0x00,   0x00
501 };
502
503 static const u8 sn_soi768[0x1c] = {
504 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
505         0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
506 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
507         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
508 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
509         0x03,   0x00,   0x00,   0x01,   0x08,   0x28,   0x1e,   0x00,
510 /*      reg18   reg19   reg1a   reg1b */
511         0x07,   0x00,   0x00,   0x00
512 };
513
514 static const u8 sn_sp80708[0x1c] = {
515 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
516         0x00,   0x63,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
517 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
518         0x81,   0x18,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
519 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
520         0x03,   0x00,   0x00,   0x03,   0x04,   0x28,   0x1e,   0x00,
521 /*      reg18   reg19   reg1a   reg1b */
522         0x07,   0x00,   0x00,   0x00
523 };
524
525 /* sequence specific to the sensors - !! index = SENSOR_xxx */
526 static const u8 *sn_tb[] = {
527 [SENSOR_ADCM1700] =     sn_adcm1700,
528 [SENSOR_GC0307] =       sn_gc0307,
529 [SENSOR_HV7131R] =      sn_hv7131,
530 [SENSOR_MI0360] =       sn_mi0360,
531 [SENSOR_MO4000] =       sn_mo4000,
532 [SENSOR_MT9V111] =      sn_mt9v111,
533 [SENSOR_OM6802] =       sn_om6802,
534 [SENSOR_OV7630] =       sn_ov7630,
535 [SENSOR_OV7648] =       sn_ov7648,
536 [SENSOR_OV7660] =       sn_ov7660,
537 [SENSOR_PO1030] =       sn_po1030,
538 [SENSOR_PO2030N] =      sn_po2030n,
539 [SENSOR_SOI768] =       sn_soi768,
540 [SENSOR_SP80708] =      sn_sp80708,
541 };
542
543 /* default gamma table */
544 static const u8 gamma_def[17] = {
545         0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
546         0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
547 };
548 /* gamma for sensor ADCM1700 */
549 static const u8 gamma_spec_0[17] = {
550         0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
551         0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
552 };
553 /* gamma for sensors HV7131R and MT9V111 */
554 static const u8 gamma_spec_1[17] = {
555         0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
556         0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
557 };
558 /* gamma for sensor GC0307 */
559 static const u8 gamma_spec_2[17] = {
560         0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
561         0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
562 };
563 /* gamma for sensor SP80708 */
564 static const u8 gamma_spec_3[17] = {
565         0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
566         0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
567 };
568
569 /* color matrix and offsets */
570 static const u8 reg84[] = {
571         0x14, 0x00, 0x27, 0x00, 0x07, 0x00,     /* YR YG YB gains */
572         0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,     /* UR UG UB */
573         0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,     /* VR VG VB */
574         0x00, 0x00, 0x00                        /* YUV offsets */
575 };
576 static const u8 adcm1700_sensor_init[][8] = {
577         {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
578         {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},       /* reset */
579         {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
580         {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
581         {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
582         {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
583         {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
584         {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
585         {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
586         {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
587         {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
588         {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
589         {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
590         {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
591         {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
592         {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
593         {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
594         {}
595 };
596 static const u8 adcm1700_sensor_param1[][8] = {
597         {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},       /* exposure? */
598         {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
599
600         {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
601         {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
602         {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
603         {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
604         {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},       /* exposure? */
605
606         {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
607         {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
608         {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
609         {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
610         {}
611 };
612 static const u8 gc0307_sensor_init[][8] = {
613         {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
614         {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
615         {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
616         {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
617         {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
618         {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
619         {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
620         {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
621         {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
622         {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
623         {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
624         {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
625         {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
626         {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
627         {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
628         {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
629         {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
630         {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
631         {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
632         {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
633         {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
634         {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
635         {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
636         {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
637         {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
638         {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
639         {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
640         {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
641         {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
642         {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
643         {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
644         {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
645         {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
646         {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
647         {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
648         {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
649         {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
650         {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
651         {}
652 };
653 static const u8 gc0307_sensor_param1[][8] = {
654         {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
655         {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
656         {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
657         {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
658 /*param3*/
659         {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
660         {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
661         {}
662 };
663
664 static const u8 hv7131r_sensor_init[][8] = {
665         {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
666         {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
667         {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
668 /*      {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
669         {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
670         {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
671 /*      {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
672
673         {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
674         {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
675         {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
676         {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
677         {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
678         {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
679         {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
680         {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
681
682         {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
683         {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
684         {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
685         {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
686         {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
687
688         {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
689         {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
690         {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
691         {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
692         {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
693         {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
694                                                         /* set sensor clock */
695         {}
696 };
697 static const u8 mi0360_sensor_init[][8] = {
698         {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
699         {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
700         {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
701         {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
702         {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
703         {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
704         {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
705         {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
706         {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
707         {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
708         {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
709         {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
710         {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
711         {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
712         {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
713         {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
714         {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
715         {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
716         {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
717         {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
718         {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
719         {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
720         {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
721         {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
722         {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
723         {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
724         {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
725         {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
726         {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
727         {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
728         {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
729         {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
730         {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
731
732         {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
733         {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
734         {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
735         {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
736         {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
737
738         {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
739         {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
740         {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
741         {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
742
743         {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
744         {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
745 /*      {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
746 /*      {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
747         {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
748         {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
749         {}
750 };
751 static const u8 mo4000_sensor_init[][8] = {
752         {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
753         {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
754         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
755         {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
756         {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
757         {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
758         {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
759         {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
760         {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
761         {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
762         {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
763         {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
764         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
765         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
766         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
767         {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
768         {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
769         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
770         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
771         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
772         {}
773 };
774 static const u8 mt9v111_sensor_init[][8] = {
775         {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
776         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
777         {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
778         {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
779         {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
780         {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
781         {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
782         {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
783         {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
784         {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
785         {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
786         {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
787         {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
788         {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
789         {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
790         {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
791         {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
792         {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
793         {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
794         {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
795         {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
796         {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
797         {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
798         {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
799         {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
800         {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
801         {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
802         {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
803         {}
804 };
805 static const u8 mt9v111_sensor_param1[][8] = {
806         {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
807         {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
808         {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
809         {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
810         {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
811         /*******/
812         {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
813         {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
814         {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
815         {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
816         {}
817 };
818 static const u8 om6802_init0[2][8] = {
819 /*fixme: variable*/
820         {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
821         {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
822 };
823 static const u8 om6802_sensor_init[][8] = {
824         {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
825                                                 /* factory mode */
826         {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
827                                                 /* output raw RGB */
828         {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
829 /*      {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
830         {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
831                 /* auto-exposure speed (0) / white balance mode (auto RGB) */
832 /*      {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
833                                                          * set color mode */
834 /*      {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
835                                                  * max AGC value in AE */
836 /*      {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
837                                                          * preset AGC */
838 /*      {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
839                                                  * preset brightness */
840 /*      {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
841                                                          * preset contrast */
842 /*      {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
843                                                          * preset gamma */
844         {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
845                                 /* luminance mode (0x4f -> AutoExpo on) */
846         {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
847                                                         /* preset shutter */
848 /*      {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
849                                                          * auto frame rate */
850 /*      {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
851         {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
852         {}
853 };
854 static const u8 om6802_sensor_param1[][8] = {
855         {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
856         {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
857         {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
858         {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
859         {}
860 };
861 static const u8 ov7630_sensor_init[][8] = {
862         {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
863         {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
864         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
865         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
866         {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
867         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
868         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
869 /* win: i2c_r from 00 to 80 */
870         {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
871         {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
872 /* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
873         0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
874         {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
875         {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
876         {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
877         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
878         {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
879         {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
880         {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
881         {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
882         {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
883         {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
884         {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
885         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
886         {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
887         {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
888         {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
889         {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
890         {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
891         {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
892         {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
893         {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
894         {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
895         {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
896         {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
897         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
898         {}
899 };
900 static const u8 ov7630_sensor_param1[][8] = {
901         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
902         {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
903 /*fixme: + 0x12, 0x04*/
904 /*      {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
905                                                          * set by setvflip */
906         {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
907         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
908         {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
909 /* */
910 /*      {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
911 /*      {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
912 /* */
913         {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
914 /*      {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
915         {}
916 };
917
918 static const u8 ov7648_sensor_init[][8] = {
919         {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
920         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},       /* reset */
921         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
922         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
923         {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
924         {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
925         {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
926         {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
927         {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
928         {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
929         {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
930         {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
931         {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
932         {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
933         {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
934         {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
935         {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
936         {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
937         {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
938         {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
939         {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
940         {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
941
942         {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
943 /*      {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
944 /*      {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
945 /*      {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
946         {}
947 };
948 static const u8 ov7648_sensor_param1[][8] = {
949 /*      {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
950 /*      {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
951                                                          * set by setvflip */
952         {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
953         {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
954 /*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
955 /*      {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
956 /*      {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
957 /*...*/
958         {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
959 /*      {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
960 /*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
961 /*      {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
962 /*      {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
963 /*      {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
964
965         {}
966 };
967
968 static const u8 ov7660_sensor_init[][8] = {
969         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
970         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
971         {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
972                                                 /* Outformat = rawRGB */
973         {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
974         {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
975                                                 /* GAIN BLUE RED VREF */
976         {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
977                                                 /* COM 1 BAVE GEAVE AECHH */
978         {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
979         {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
980         {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
981                                                 /* AECH CLKRC COM7 COM8 */
982         {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
983         {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
984                                                 /* HSTART HSTOP VSTRT VSTOP */
985         {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
986         {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
987         {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
988                                         /* BOS GBOS GROS ROS (BGGR offset) */
989 /*      {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
990         {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
991                                                 /* AEW AEB VPT BBIAS */
992         {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
993                                                 /* GbBIAS RSVD EXHCH EXHCL */
994         {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
995                                                 /* RBIAS ADVFL ASDVFH YAVE */
996         {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
997                                                 /* HSYST HSYEN HREF */
998         {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
999         {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1000                                                 /* ADC ACOM OFON TSLB */
1001         {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1002                                                 /* COM11 COM12 COM13 COM14 */
1003         {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1004                                                 /* EDGE COM15 COM16 COM17 */
1005         {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1006         {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1007         {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1008         {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1009         {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1010         {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1011         {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1012         {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1013         {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1014         {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1015                                                 /* LCC1 LCC2 LCC3 LCC4 */
1016         {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
1017         {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
1018         {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
1019                                         /* band gap reference [0:3] DBLV */
1020         {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1021         {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1022         {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1023         {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1024         {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1025         {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1026         {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1027         {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1028         {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
1029         {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
1030 /* not in all ms-win traces*/
1031         {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
1032         {}
1033 };
1034 static const u8 ov7660_sensor_param1[][8] = {
1035         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
1036                                                 /* bits[3..0]reserved */
1037         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1038         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1039                                                 /* VREF vertical frame ctrl */
1040         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1041         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1042         {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1043         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1044         {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1045 /*      {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
1046 /****** (some exchanges in the win trace) ******/
1047 /*fixme:param2*/
1048         {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
1049         {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1050         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1051         {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1052 /*      {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
1053 /****** (some exchanges in the win trace) ******/
1054 /******!! startsensor KO if changed !!****/
1055 /*fixme: param3*/
1056         {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1057         {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1058         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1059         {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
1060         {}
1061 };
1062
1063 static const u8 po1030_sensor_init[][8] = {
1064 /* the sensor registers are described in m5602/m5602_po1030.h */
1065         {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1066         {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1067         {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1068         {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1069         {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1070         {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1071         {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1072         {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1073         {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1074         {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1075         {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1076         {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1077         {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1078         {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1079         {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1080         {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1081         {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1082         {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1083         {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1084         {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1085         {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1086         {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1087         {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1088         {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1089         {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1090         {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1091         {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1092         {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1093
1094         {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1095         {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1096         {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1097         {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1098         {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1099         {}
1100 };
1101 static const u8 po1030_sensor_param1[][8] = {
1102 /* from ms-win traces - these values change with auto gain/expo/wb.. */
1103         {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1104         {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1105 /* mean values */
1106         {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1107         {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1108         {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1109
1110         {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1111         {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1112         {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1113 /*      {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1114         {}
1115 };
1116
1117 static const u8 po2030n_sensor_init[][8] = {
1118         {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1119         {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1120         {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1121         {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1122         {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1123         {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1124         {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1125         {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1126         {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1127         {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1128         {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1129         {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1130         {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1131         {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1132         {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1133         {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1134         {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1135         {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1136         {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1137         {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1138         {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1139         {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1140         {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1141         {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1142         {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1143         {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1144         {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1145         {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1146         {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1147         {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1148         {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1149         {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1150         {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1151         {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1152         {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1153         {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1154         {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1155         {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1156         {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1157         {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1158         {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1159         {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1160         {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1161         {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1162         {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1163         {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1164         {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1165         {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1166         {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1167         {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1168         {}
1169 };
1170 static const u8 po2030n_sensor_param1[][8] = {
1171         {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1172         {0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1173         {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1174         {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1175         {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1176 /*param2*/
1177         {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1178         {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1179         {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1180         {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1181         {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1182         {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1183         {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1184 /*after start*/
1185         {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1186         {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1187         {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1188         {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1189         {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1190         {}
1191 };
1192
1193 static const u8 soi768_sensor_init[][8] = {
1194         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1195         {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1196         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1197         {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1198         {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1199         {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1200         {}
1201 };
1202 static const u8 soi768_sensor_param1[][8] = {
1203         {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1204         {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1205         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1206         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1207         {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1208 /* */
1209 /*      {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1210 /*      {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1211         {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1212 /*      {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1213         {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1214 /* the next sequence should be used for auto gain */
1215         {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1216                         /* global gain ? : 07 - change with 0x15 at the end */
1217         {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1218         {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1219         {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1220                         /* exposure ? : 0200 - change with 0x1e at the end */
1221         {}
1222 };
1223
1224 static const u8 sp80708_sensor_init[][8] = {
1225         {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1226         {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1227         {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1228         {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1229         {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1230         {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1231         {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1232         {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1233         {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1234         {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1235         {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1236         {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1237         {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1238         {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1239         {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1240         {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1241         {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1242         {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1243         {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1244         {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1245         {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1246         {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1247         {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1248         {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1249         {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1250         {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1251         {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1252         {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1253         {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1254         {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1255         {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1256         {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1257         {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1258         {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1259         {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1260         {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1261         {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1262         {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1263         {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1264         {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1265         {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1266         {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1267         {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1268         {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1269         {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1270         {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1271         {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1272         {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1273         {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1274         {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1275         {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1276         {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1277         {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1278         {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1279         {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1280         {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1281         {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1282         {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1283         {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1284         {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1285         {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1286         {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1287         {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1288         {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1289         {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1290         {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1291         {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1292         {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1293         {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1294         {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1295         {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1296         {}
1297 };
1298 static const u8 sp80708_sensor_param1[][8] = {
1299         {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1300         {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1301         {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1302         {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1303         {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1304         {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1305         {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1306         {}
1307 };
1308
1309 static const u8 (*sensor_init[])[8] = {
1310 [SENSOR_ADCM1700] =     adcm1700_sensor_init,
1311 [SENSOR_GC0307] =       gc0307_sensor_init,
1312 [SENSOR_HV7131R] =      hv7131r_sensor_init,
1313 [SENSOR_MI0360] =       mi0360_sensor_init,
1314 [SENSOR_MO4000] =       mo4000_sensor_init,
1315 [SENSOR_MT9V111] =      mt9v111_sensor_init,
1316 [SENSOR_OM6802] =       om6802_sensor_init,
1317 [SENSOR_OV7630] =       ov7630_sensor_init,
1318 [SENSOR_OV7648] =       ov7648_sensor_init,
1319 [SENSOR_OV7660] =       ov7660_sensor_init,
1320 [SENSOR_PO1030] =       po1030_sensor_init,
1321 [SENSOR_PO2030N] =      po2030n_sensor_init,
1322 [SENSOR_SOI768] =       soi768_sensor_init,
1323 [SENSOR_SP80708] =      sp80708_sensor_init,
1324 };
1325
1326 /* read <len> bytes to gspca_dev->usb_buf */
1327 static void reg_r(struct gspca_dev *gspca_dev,
1328                   u16 value, int len)
1329 {
1330 #ifdef GSPCA_DEBUG
1331         if (len > USB_BUF_SZ) {
1332                 err("reg_r: buffer overflow");
1333                 return;
1334         }
1335 #endif
1336         usb_control_msg(gspca_dev->dev,
1337                         usb_rcvctrlpipe(gspca_dev->dev, 0),
1338                         0,
1339                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1340                         value, 0,
1341                         gspca_dev->usb_buf, len,
1342                         500);
1343         PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
1344 }
1345
1346 static void reg_w1(struct gspca_dev *gspca_dev,
1347                    u16 value,
1348                    u8 data)
1349 {
1350         PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
1351         gspca_dev->usb_buf[0] = data;
1352         usb_control_msg(gspca_dev->dev,
1353                         usb_sndctrlpipe(gspca_dev->dev, 0),
1354                         0x08,
1355                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1356                         value,
1357                         0,
1358                         gspca_dev->usb_buf, 1,
1359                         500);
1360 }
1361 static void reg_w(struct gspca_dev *gspca_dev,
1362                           u16 value,
1363                           const u8 *buffer,
1364                           int len)
1365 {
1366         PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
1367                 value, buffer[0], buffer[1]);
1368 #ifdef GSPCA_DEBUG
1369         if (len > USB_BUF_SZ) {
1370                 err("reg_w: buffer overflow");
1371                 return;
1372         }
1373 #endif
1374         memcpy(gspca_dev->usb_buf, buffer, len);
1375         usb_control_msg(gspca_dev->dev,
1376                         usb_sndctrlpipe(gspca_dev->dev, 0),
1377                         0x08,
1378                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1379                         value, 0,
1380                         gspca_dev->usb_buf, len,
1381                         500);
1382 }
1383
1384 /* I2C write 1 byte */
1385 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1386 {
1387         struct sd *sd = (struct sd *) gspca_dev;
1388
1389         PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1390         switch (sd->sensor) {
1391         case SENSOR_ADCM1700:
1392         case SENSOR_OM6802:
1393         case SENSOR_GC0307:             /* i2c command = a0 (100 kHz) */
1394                 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1395                 break;
1396         default:                        /* i2c command = a1 (400 kHz) */
1397                 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1398                 break;
1399         }
1400         gspca_dev->usb_buf[1] = sd->i2c_addr;
1401         gspca_dev->usb_buf[2] = reg;
1402         gspca_dev->usb_buf[3] = val;
1403         gspca_dev->usb_buf[4] = 0;
1404         gspca_dev->usb_buf[5] = 0;
1405         gspca_dev->usb_buf[6] = 0;
1406         gspca_dev->usb_buf[7] = 0x10;
1407         usb_control_msg(gspca_dev->dev,
1408                         usb_sndctrlpipe(gspca_dev->dev, 0),
1409                         0x08,
1410                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1411                         0x08,                   /* value = i2c */
1412                         0,
1413                         gspca_dev->usb_buf, 8,
1414                         500);
1415 }
1416
1417 /* I2C write 8 bytes */
1418 static void i2c_w8(struct gspca_dev *gspca_dev,
1419                    const u8 *buffer)
1420 {
1421         PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1422                 buffer[2], buffer[3]);
1423         memcpy(gspca_dev->usb_buf, buffer, 8);
1424         usb_control_msg(gspca_dev->dev,
1425                         usb_sndctrlpipe(gspca_dev->dev, 0),
1426                         0x08,
1427                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1428                         0x08, 0,                /* value, index */
1429                         gspca_dev->usb_buf, 8,
1430                         500);
1431         msleep(2);
1432 }
1433
1434 /* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1435 static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1436 {
1437         struct sd *sd = (struct sd *) gspca_dev;
1438         u8 mode[8];
1439
1440         switch (sd->sensor) {
1441         case SENSOR_ADCM1700:
1442         case SENSOR_OM6802:
1443         case SENSOR_GC0307:             /* i2c command = a0 (100 kHz) */
1444                 mode[0] = 0x80 | 0x10;
1445                 break;
1446         default:                        /* i2c command = 91 (400 kHz) */
1447                 mode[0] = 0x81 | 0x10;
1448                 break;
1449         }
1450         mode[1] = sd->i2c_addr;
1451         mode[2] = reg;
1452         mode[3] = 0;
1453         mode[4] = 0;
1454         mode[5] = 0;
1455         mode[6] = 0;
1456         mode[7] = 0x10;
1457         i2c_w8(gspca_dev, mode);
1458         msleep(2);
1459         mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1460         mode[2] = 0;
1461         i2c_w8(gspca_dev, mode);
1462         msleep(2);
1463         reg_r(gspca_dev, 0x0a, 5);
1464 }
1465
1466 static void i2c_w_seq(struct gspca_dev *gspca_dev,
1467                         const u8 (*data)[8])
1468 {
1469         while ((*data)[0] != 0) {
1470                 if ((*data)[0] != 0xdd)
1471                         i2c_w8(gspca_dev, *data);
1472                 else
1473                         msleep((*data)[1]);
1474                 data++;
1475         }
1476 }
1477
1478 static void hv7131r_probe(struct gspca_dev *gspca_dev)
1479 {
1480         i2c_w1(gspca_dev, 0x02, 0);                     /* sensor wakeup */
1481         msleep(10);
1482         reg_w1(gspca_dev, 0x02, 0x66);                  /* Gpio on */
1483         msleep(10);
1484         i2c_r(gspca_dev, 0, 5);                         /* read sensor id */
1485         if (gspca_dev->usb_buf[0] == 0x02
1486             && gspca_dev->usb_buf[1] == 0x09
1487             && gspca_dev->usb_buf[2] == 0x01
1488             && gspca_dev->usb_buf[3] == 0x00
1489             && gspca_dev->usb_buf[4] == 0x00) {
1490                 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1491                 return;
1492         }
1493         PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
1494                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1495                 gspca_dev->usb_buf[2]);
1496 }
1497
1498 static void mi0360_probe(struct gspca_dev *gspca_dev)
1499 {
1500         struct sd *sd = (struct sd *) gspca_dev;
1501         int i, j;
1502         u16 val = 0;
1503         static const u8 probe_tb[][4][8] = {
1504             {                                   /* mi0360 */
1505                 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1506                 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1507                 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1508                 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1509             },
1510             {                                   /* mt9v111 */
1511                 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1512                 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1513                 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1514                 {}
1515             },
1516         };
1517
1518         for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1519                 reg_w1(gspca_dev, 0x17, 0x62);
1520                 reg_w1(gspca_dev, 0x01, 0x08);
1521                 for (j = 0; j < 3; j++)
1522                         i2c_w8(gspca_dev, probe_tb[i][j]);
1523                 msleep(2);
1524                 reg_r(gspca_dev, 0x0a, 5);
1525                 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1526                 if (probe_tb[i][3][0] != 0)
1527                         i2c_w8(gspca_dev, probe_tb[i][3]);
1528                 reg_w1(gspca_dev, 0x01, 0x29);
1529                 reg_w1(gspca_dev, 0x17, 0x42);
1530                 if (val != 0xffff)
1531                         break;
1532         }
1533         switch (val) {
1534         case 0x823a:
1535                 PDEBUG(D_PROBE, "Sensor mt9v111");
1536                 sd->sensor = SENSOR_MT9V111;
1537                 break;
1538         case 0x8243:
1539                 PDEBUG(D_PROBE, "Sensor mi0360");
1540                 break;
1541         default:
1542                 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1543                 break;
1544         }
1545 }
1546
1547 static void ov7630_probe(struct gspca_dev *gspca_dev)
1548 {
1549         struct sd *sd = (struct sd *) gspca_dev;
1550         u16 val;
1551
1552         /* check ov76xx */
1553         reg_w1(gspca_dev, 0x17, 0x62);
1554         reg_w1(gspca_dev, 0x01, 0x08);
1555         sd->i2c_addr = 0x21;
1556         i2c_r(gspca_dev, 0x0a, 2);
1557         val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1558         reg_w1(gspca_dev, 0x01, 0x29);
1559         reg_w1(gspca_dev, 0x17, 0x42);
1560         if (val == 0x7628) {                    /* soi768 */
1561                 sd->sensor = SENSOR_SOI768;
1562 /*fixme: only valid for 0c45:613e?*/
1563                 gspca_dev->cam.input_flags =
1564                                 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1565                 PDEBUG(D_PROBE, "Sensor soi768");
1566                 return;
1567         }
1568         PDEBUG(D_PROBE, "Sensor ov%04x", val);
1569 }
1570
1571 static void ov7648_probe(struct gspca_dev *gspca_dev)
1572 {
1573         struct sd *sd = (struct sd *) gspca_dev;
1574         u16 val;
1575
1576         /* check ov76xx */
1577         reg_w1(gspca_dev, 0x17, 0x62);
1578         reg_w1(gspca_dev, 0x01, 0x08);
1579         sd->i2c_addr = 0x21;
1580         i2c_r(gspca_dev, 0x0a, 2);
1581         val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1582         reg_w1(gspca_dev, 0x01, 0x29);
1583         reg_w1(gspca_dev, 0x17, 0x42);
1584         if ((val & 0xff00) == 0x7600) {         /* ov76xx */
1585                 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1586                 return;
1587         }
1588
1589         /* check po1030 */
1590         reg_w1(gspca_dev, 0x17, 0x62);
1591         reg_w1(gspca_dev, 0x01, 0x08);
1592         sd->i2c_addr = 0x6e;
1593         i2c_r(gspca_dev, 0x00, 2);
1594         val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1595         reg_w1(gspca_dev, 0x01, 0x29);
1596         reg_w1(gspca_dev, 0x17, 0x42);
1597         if (val == 0x1030) {                    /* po1030 */
1598                 PDEBUG(D_PROBE, "Sensor po1030");
1599                 sd->sensor = SENSOR_PO1030;
1600                 return;
1601         }
1602
1603         PDEBUG(D_PROBE, "Unknown sensor %04x", val);
1604 }
1605
1606 /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1607 static void po2030n_probe(struct gspca_dev *gspca_dev)
1608 {
1609         struct sd *sd = (struct sd *) gspca_dev;
1610         u16 val;
1611
1612         /* check gc0307 */
1613         reg_w1(gspca_dev, 0x17, 0x62);
1614         reg_w1(gspca_dev, 0x01, 0x08);
1615         reg_w1(gspca_dev, 0x02, 0x22);
1616         sd->i2c_addr = 0x21;
1617         i2c_r(gspca_dev, 0x00, 1);
1618         val = gspca_dev->usb_buf[4];
1619         reg_w1(gspca_dev, 0x01, 0x29);          /* reset */
1620         reg_w1(gspca_dev, 0x17, 0x42);
1621         if (val == 0x99) {                      /* gc0307 (?) */
1622                 PDEBUG(D_PROBE, "Sensor gc0307");
1623                 sd->sensor = SENSOR_GC0307;
1624                 return;
1625         }
1626
1627         /* check po2030n */
1628         reg_w1(gspca_dev, 0x17, 0x62);
1629         reg_w1(gspca_dev, 0x01, 0x0a);
1630         sd->i2c_addr = 0x6e;
1631         i2c_r(gspca_dev, 0x00, 2);
1632         val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1633         reg_w1(gspca_dev, 0x01, 0x29);
1634         reg_w1(gspca_dev, 0x17, 0x42);
1635         if (val == 0x2030) {
1636                 PDEBUG(D_PROBE, "Sensor po2030n");
1637 /*              sd->sensor = SENSOR_PO2030N; */
1638         } else {
1639                 PDEBUG(D_PROBE, "Unknown sensor ID %04x", val);
1640         }
1641 }
1642
1643 static void bridge_init(struct gspca_dev *gspca_dev,
1644                           const u8 *sn9c1xx)
1645 {
1646         struct sd *sd = (struct sd *) gspca_dev;
1647         const u8 *reg9a;
1648         static const u8 reg9a_def[] =
1649                 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1650         static const u8 reg9a_spec[] =
1651                 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1652         static const u8 regd4[] = {0x60, 0x00, 0x00};
1653
1654         /* sensor clock already enabled in sd_init */
1655         /* reg_w1(gspca_dev, 0xf1, 0x00); */
1656         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1657
1658         /* configure gpio */
1659         reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1660         reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1661         reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1662         switch (sd->sensor) {
1663         case SENSOR_GC0307:
1664         case SENSOR_OV7660:
1665         case SENSOR_PO1030:
1666         case SENSOR_PO2030N:
1667         case SENSOR_SOI768:
1668         case SENSOR_SP80708:
1669                 reg9a = reg9a_spec;
1670                 break;
1671         default:
1672                 reg9a = reg9a_def;
1673                 break;
1674         }
1675         reg_w(gspca_dev, 0x9a, reg9a, 6);
1676
1677         reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
1678
1679         reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1680
1681         switch (sd->sensor) {
1682         case SENSOR_ADCM1700:
1683                 reg_w1(gspca_dev, 0x01, 0x43);
1684                 reg_w1(gspca_dev, 0x17, 0x62);
1685                 reg_w1(gspca_dev, 0x01, 0x42);
1686                 reg_w1(gspca_dev, 0x01, 0x42);
1687                 break;
1688         case SENSOR_GC0307:
1689                 msleep(50);
1690                 reg_w1(gspca_dev, 0x01, 0x61);
1691                 reg_w1(gspca_dev, 0x17, 0x22);
1692                 reg_w1(gspca_dev, 0x01, 0x60);
1693                 reg_w1(gspca_dev, 0x01, 0x40);
1694                 msleep(50);
1695                 break;
1696         case SENSOR_MT9V111:
1697                 reg_w1(gspca_dev, 0x01, 0x61);
1698                 reg_w1(gspca_dev, 0x17, 0x61);
1699                 reg_w1(gspca_dev, 0x01, 0x60);
1700                 reg_w1(gspca_dev, 0x01, 0x40);
1701                 break;
1702         case SENSOR_OM6802:
1703                 msleep(10);
1704                 reg_w1(gspca_dev, 0x02, 0x73);
1705                 reg_w1(gspca_dev, 0x17, 0x60);
1706                 reg_w1(gspca_dev, 0x01, 0x22);
1707                 msleep(100);
1708                 reg_w1(gspca_dev, 0x01, 0x62);
1709                 reg_w1(gspca_dev, 0x17, 0x64);
1710                 reg_w1(gspca_dev, 0x17, 0x64);
1711                 reg_w1(gspca_dev, 0x01, 0x42);
1712                 msleep(10);
1713                 reg_w1(gspca_dev, 0x01, 0x42);
1714                 i2c_w8(gspca_dev, om6802_init0[0]);
1715                 i2c_w8(gspca_dev, om6802_init0[1]);
1716                 msleep(15);
1717                 reg_w1(gspca_dev, 0x02, 0x71);
1718                 msleep(150);
1719                 break;
1720         case SENSOR_OV7630:
1721                 reg_w1(gspca_dev, 0x01, 0x61);
1722                 reg_w1(gspca_dev, 0x17, 0xe2);
1723                 reg_w1(gspca_dev, 0x01, 0x60);
1724                 reg_w1(gspca_dev, 0x01, 0x40);
1725                 break;
1726         case SENSOR_OV7648:
1727                 reg_w1(gspca_dev, 0x01, 0x63);
1728                 reg_w1(gspca_dev, 0x17, 0x20);
1729                 reg_w1(gspca_dev, 0x01, 0x62);
1730                 reg_w1(gspca_dev, 0x01, 0x42);
1731                 break;
1732         case SENSOR_PO1030:
1733         case SENSOR_SOI768:
1734                 reg_w1(gspca_dev, 0x01, 0x61);
1735                 reg_w1(gspca_dev, 0x17, 0x20);
1736                 reg_w1(gspca_dev, 0x01, 0x60);
1737                 reg_w1(gspca_dev, 0x01, 0x40);
1738                 break;
1739         case SENSOR_PO2030N:
1740                 reg_w1(gspca_dev, 0x01, 0x63);
1741                 reg_w1(gspca_dev, 0x17, 0x20);
1742                 reg_w1(gspca_dev, 0x01, 0x62);
1743                 reg_w1(gspca_dev, 0x01, 0x42);
1744                 break;
1745         case SENSOR_OV7660:
1746                 /* fall thru */
1747         case SENSOR_SP80708:
1748                 reg_w1(gspca_dev, 0x01, 0x63);
1749                 reg_w1(gspca_dev, 0x17, 0x20);
1750                 reg_w1(gspca_dev, 0x01, 0x62);
1751                 reg_w1(gspca_dev, 0x01, 0x42);
1752                 msleep(100);
1753                 reg_w1(gspca_dev, 0x02, 0x62);
1754                 break;
1755         default:
1756 /*      case SENSOR_HV7131R: */
1757 /*      case SENSOR_MI0360: */
1758 /*      case SENSOR_MO4000: */
1759                 reg_w1(gspca_dev, 0x01, 0x43);
1760                 reg_w1(gspca_dev, 0x17, 0x61);
1761                 reg_w1(gspca_dev, 0x01, 0x42);
1762                 if (sd->sensor == SENSOR_HV7131R
1763                     && sd->bridge == BRIDGE_SN9C102P)
1764                         hv7131r_probe(gspca_dev);
1765                 break;
1766         }
1767 }
1768
1769 /* this function is called at probe time */
1770 static int sd_config(struct gspca_dev *gspca_dev,
1771                         const struct usb_device_id *id)
1772 {
1773         struct sd *sd = (struct sd *) gspca_dev;
1774         struct cam *cam;
1775
1776         sd->bridge = id->driver_info >> 16;
1777         sd->sensor = id->driver_info;
1778
1779         cam = &gspca_dev->cam;
1780         if (sd->sensor == SENSOR_ADCM1700) {
1781                 cam->cam_mode = cif_mode;
1782                 cam->nmodes = ARRAY_SIZE(cif_mode);
1783         } else {
1784                 cam->cam_mode = vga_mode;
1785                 cam->nmodes = ARRAY_SIZE(vga_mode);
1786         }
1787         cam->npkt = 24;                 /* 24 packets per ISOC message */
1788
1789         sd->brightness = BRIGHTNESS_DEF;
1790         sd->contrast = CONTRAST_DEF;
1791         sd->colors = COLOR_DEF;
1792         sd->blue = BLUE_BALANCE_DEF;
1793         sd->red = RED_BALANCE_DEF;
1794         sd->gamma = GAMMA_DEF;
1795         sd->autogain = AUTOGAIN_DEF;
1796         sd->ag_cnt = -1;
1797         sd->vflip = VFLIP_DEF;
1798         switch (sd->sensor) {
1799         case SENSOR_OM6802:
1800                 sd->sharpness = 0x10;
1801                 break;
1802         default:
1803                 sd->sharpness = SHARPNESS_DEF;
1804                 break;
1805         }
1806         sd->infrared = INFRARED_DEF;
1807         sd->freq = FREQ_DEF;
1808         sd->quality = QUALITY_DEF;
1809         sd->jpegqual = 80;
1810
1811         return 0;
1812 }
1813
1814 /* this function is called at probe and resume time */
1815 static int sd_init(struct gspca_dev *gspca_dev)
1816 {
1817         struct sd *sd = (struct sd *) gspca_dev;
1818         const u8 *sn9c1xx;
1819         u8 regGpio[] = { 0x29, 0x74 };
1820         u8 regF1;
1821
1822         /* setup a selector by bridge */
1823         reg_w1(gspca_dev, 0xf1, 0x01);
1824         reg_r(gspca_dev, 0x00, 1);
1825         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1826         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
1827         regF1 = gspca_dev->usb_buf[0];
1828         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1829         switch (sd->bridge) {
1830         case BRIDGE_SN9C102P:
1831                 if (regF1 != 0x11)
1832                         return -ENODEV;
1833                 reg_w1(gspca_dev, 0x02, regGpio[1]);
1834                 break;
1835         case BRIDGE_SN9C105:
1836                 if (regF1 != 0x11)
1837                         return -ENODEV;
1838                 if (sd->sensor == SENSOR_MI0360)
1839                         mi0360_probe(gspca_dev);
1840                 reg_w(gspca_dev, 0x01, regGpio, 2);
1841                 break;
1842         case BRIDGE_SN9C120:
1843                 if (regF1 != 0x12)
1844                         return -ENODEV;
1845                 switch (sd->sensor) {
1846                 case SENSOR_MI0360:
1847                         mi0360_probe(gspca_dev);
1848                         break;
1849                 case SENSOR_OV7630:
1850                         ov7630_probe(gspca_dev);
1851                         break;
1852                 case SENSOR_OV7648:
1853                         ov7648_probe(gspca_dev);
1854                         break;
1855                 case SENSOR_PO2030N:
1856                         po2030n_probe(gspca_dev);
1857                         break;
1858                 }
1859                 regGpio[1] = 0x70;
1860                 reg_w(gspca_dev, 0x01, regGpio, 2);
1861                 break;
1862         default:
1863 /*      case BRIDGE_SN9C110: */
1864 /*      case BRIDGE_SN9C325: */
1865                 if (regF1 != 0x12)
1866                         return -ENODEV;
1867                 reg_w1(gspca_dev, 0x02, 0x62);
1868                 break;
1869         }
1870
1871         /* Note we do not disable the sensor clock here (power saving mode),
1872            as that also disables the button on the cam. */
1873         reg_w1(gspca_dev, 0xf1, 0x00);
1874
1875         /* set the i2c address */
1876         sn9c1xx = sn_tb[sd->sensor];
1877         sd->i2c_addr = sn9c1xx[9];
1878
1879         gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1880
1881         return 0;
1882 }
1883
1884 static u32 setexposure(struct gspca_dev *gspca_dev,
1885                         u32 expo)
1886 {
1887         struct sd *sd = (struct sd *) gspca_dev;
1888
1889         switch (sd->sensor) {
1890         case SENSOR_GC0307: {
1891                 int a, b;
1892
1893                 /* expo = 0..255 -> a = 19..43 */
1894                 a = 19 + expo * 25 / 256;
1895                 i2c_w1(gspca_dev, 0x68, a);
1896                 a -= 12;
1897                 b = a * a * 4;                  /* heuristic */
1898                 i2c_w1(gspca_dev, 0x03, b >> 8);
1899                 i2c_w1(gspca_dev, 0x04, b);
1900                 break;
1901             }
1902         case SENSOR_HV7131R: {
1903                 u8 Expodoit[] =
1904                         { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1905
1906                 Expodoit[3] = expo >> 16;
1907                 Expodoit[4] = expo >> 8;
1908                 Expodoit[5] = expo;
1909                 i2c_w8(gspca_dev, Expodoit);
1910                 break;
1911             }
1912         case SENSOR_MI0360: {
1913                 u8 expoMi[] =           /* exposure 0x0635 -> 4 fp/s 0x10 */
1914                         { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1915                 static const u8 doit[] =                /* update sensor */
1916                         { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1917                 static const u8 sensorgo[] =            /* sensor on */
1918                         { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1919
1920                 if (expo > 0x0635)
1921                         expo = 0x0635;
1922                 else if (expo < 0x0001)
1923                         expo = 0x0001;
1924                 expoMi[3] = expo >> 8;
1925                 expoMi[4] = expo;
1926                 i2c_w8(gspca_dev, expoMi);
1927                 i2c_w8(gspca_dev, doit);
1928                 i2c_w8(gspca_dev, sensorgo);
1929                 break;
1930             }
1931         case SENSOR_MO4000: {
1932                 u8 expoMof[] =
1933                         { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1934                 u8 expoMo10[] =
1935                         { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1936                 static const u8 gainMo[] =
1937                         { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1938
1939                 if (expo > 0x1fff)
1940                         expo = 0x1fff;
1941                 else if (expo < 0x0001)
1942                         expo = 0x0001;
1943                 expoMof[3] = (expo & 0x03fc) >> 2;
1944                 i2c_w8(gspca_dev, expoMof);
1945                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1946                                 | ((expo & 0x0003) << 4);
1947                 i2c_w8(gspca_dev, expoMo10);
1948                 i2c_w8(gspca_dev, gainMo);
1949                 PDEBUG(D_FRAM, "set exposure %d",
1950                         ((expoMo10[3] & 0x07) << 10)
1951                         | (expoMof[3] << 2)
1952                         | ((expoMo10[3] & 0x30) >> 4));
1953                 break;
1954             }
1955         case SENSOR_MT9V111: {
1956                 u8 expo_c1[] =
1957                         { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1958
1959                 if (expo > 0x0280)
1960                         expo = 0x0280;
1961                 else if (expo < 0x0040)
1962                         expo = 0x0040;
1963                 expo_c1[3] = expo >> 8;
1964                 expo_c1[4] = expo;
1965                 i2c_w8(gspca_dev, expo_c1);
1966                 break;
1967             }
1968         case SENSOR_OM6802: {
1969                 u8 gainOm[] =
1970                         { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1971                                 /* preset AGC - works when AutoExpo = off */
1972
1973                 if (expo > 0x03ff)
1974                         expo = 0x03ff;
1975                  if (expo < 0x0001)
1976                         expo = 0x0001;
1977                 gainOm[3] = expo >> 2;
1978                 i2c_w8(gspca_dev, gainOm);
1979                 reg_w1(gspca_dev, 0x96, expo >> 5);
1980                 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1981                 break;
1982             }
1983         }
1984         return expo;
1985 }
1986
1987 static void setbrightness(struct gspca_dev *gspca_dev)
1988 {
1989         struct sd *sd = (struct sd *) gspca_dev;
1990         unsigned int expo;
1991         u8 k2;
1992
1993         k2 = ((int) sd->brightness - 0x8000) >> 10;
1994         switch (sd->sensor) {
1995         case SENSOR_ADCM1700:
1996                 if (k2 > 0x1f)
1997                         k2 = 0;         /* only positive Y offset */
1998                 break;
1999         case SENSOR_HV7131R:
2000                 expo = sd->brightness << 4;
2001                 if (expo > 0x002dc6c0)
2002                         expo = 0x002dc6c0;
2003                 else if (expo < 0x02a0)
2004                         expo = 0x02a0;
2005                 sd->exposure = setexposure(gspca_dev, expo);
2006                 break;
2007         case SENSOR_MI0360:
2008         case SENSOR_MO4000:
2009                 expo = sd->brightness >> 4;
2010                 sd->exposure = setexposure(gspca_dev, expo);
2011                 break;
2012         case SENSOR_GC0307:
2013         case SENSOR_MT9V111:
2014                 expo = sd->brightness >> 8;
2015                 sd->exposure = setexposure(gspca_dev, expo);
2016                 return;                 /* don't set the Y offset */
2017         case SENSOR_OM6802:
2018                 expo = sd->brightness >> 6;
2019                 sd->exposure = setexposure(gspca_dev, expo);
2020                 k2 = sd->brightness >> 11;
2021                 break;
2022         }
2023
2024         reg_w1(gspca_dev, 0x96, k2);    /* color matrix Y offset */
2025 }
2026
2027 static void setcontrast(struct gspca_dev *gspca_dev)
2028 {
2029         struct sd *sd = (struct sd *) gspca_dev;
2030         u8 k2;
2031         u8 contrast[6];
2032
2033         k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;   /* 10..40 */
2034         contrast[0] = (k2 + 1) / 2;             /* red */
2035         contrast[1] = 0;
2036         contrast[2] = k2;                       /* green */
2037         contrast[3] = 0;
2038         contrast[4] = (k2 + 1) / 5;             /* blue */
2039         contrast[5] = 0;
2040         reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
2041 }
2042
2043 static void setcolors(struct gspca_dev *gspca_dev)
2044 {
2045         struct sd *sd = (struct sd *) gspca_dev;
2046         int i, v;
2047         u8 reg8a[12];                   /* U & V gains */
2048         static const s16 uv[6] = {      /* same as reg84 in signed decimal */
2049                 -24, -38, 64,           /* UR UG UB */
2050                  62, -51, -9            /* VR VG VB */
2051         };
2052
2053         for (i = 0; i < 6; i++) {
2054                 v = uv[i] * sd->colors / COLOR_DEF;
2055                 reg8a[i * 2] = v;
2056                 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
2057         }
2058         reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
2059 }
2060
2061 static void setredblue(struct gspca_dev *gspca_dev)
2062 {
2063         struct sd *sd = (struct sd *) gspca_dev;
2064
2065         reg_w1(gspca_dev, 0x05, sd->red);
2066 /*      reg_w1(gspca_dev, 0x07, 32); */
2067         reg_w1(gspca_dev, 0x06, sd->blue);
2068 }
2069
2070 static void setgamma(struct gspca_dev *gspca_dev)
2071 {
2072         struct sd *sd = (struct sd *) gspca_dev;
2073         int i;
2074         u8 gamma[17];
2075         const u8 *gamma_base;
2076         static const u8 delta[17] = {
2077                 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2078                 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2079         };
2080
2081         switch (sd->sensor) {
2082         case SENSOR_ADCM1700:
2083                 gamma_base = gamma_spec_0;
2084                 break;
2085         case SENSOR_HV7131R:
2086         case SENSOR_MT9V111:
2087                 gamma_base = gamma_spec_1;
2088                 break;
2089         case SENSOR_GC0307:
2090                 gamma_base = gamma_spec_2;
2091                 break;
2092         case SENSOR_SP80708:
2093                 gamma_base = gamma_spec_3;
2094                 break;
2095         default:
2096                 gamma_base = gamma_def;
2097                 break;
2098         }
2099
2100         for (i = 0; i < sizeof gamma; i++)
2101                 gamma[i] = gamma_base[i]
2102                         + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
2103         reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2104 }
2105
2106 static void setautogain(struct gspca_dev *gspca_dev)
2107 {
2108         struct sd *sd = (struct sd *) gspca_dev;
2109
2110         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
2111                 return;
2112         switch (sd->sensor) {
2113         case SENSOR_OV7630:
2114         case SENSOR_OV7648: {
2115                 u8 comb;
2116
2117                 if (sd->sensor == SENSOR_OV7630)
2118                         comb = 0xc0;
2119                 else
2120                         comb = 0xa0;
2121                 if (sd->autogain)
2122                         comb |= 0x03;
2123                 i2c_w1(&sd->gspca_dev, 0x13, comb);
2124                 return;
2125             }
2126         }
2127         if (sd->autogain)
2128                 sd->ag_cnt = AG_CNT_START;
2129         else
2130                 sd->ag_cnt = -1;
2131 }
2132
2133 /* hv7131r/ov7630/ov7648 only */
2134 static void setvflip(struct sd *sd)
2135 {
2136         u8 comn;
2137
2138         if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
2139                 return;
2140         switch (sd->sensor) {
2141         case SENSOR_HV7131R:
2142                 comn = 0x18;                    /* clkdiv = 1, ablcen = 1 */
2143                 if (sd->vflip)
2144                         comn |= 0x01;
2145                 i2c_w1(&sd->gspca_dev, 0x01, comn);     /* sctra */
2146                 break;
2147         case SENSOR_OV7630:
2148                 comn = 0x02;
2149                 if (!sd->vflip)
2150                         comn |= 0x80;
2151                 i2c_w1(&sd->gspca_dev, 0x75, comn);
2152                 break;
2153         default:
2154 /*      case SENSOR_OV7648: */
2155                 comn = 0x06;
2156                 if (sd->vflip)
2157                         comn |= 0x80;
2158                 i2c_w1(&sd->gspca_dev, 0x75, comn);
2159                 break;
2160         }
2161 }
2162
2163 static void setsharpness(struct sd *sd)
2164 {
2165         reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
2166 }
2167
2168 static void setinfrared(struct sd *sd)
2169 {
2170         if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
2171                 return;
2172 /*fixme: different sequence for StarCam Clip and StarCam 370i */
2173 /* Clip */
2174         i2c_w1(&sd->gspca_dev, 0x02,                    /* gpio */
2175                 sd->infrared ? 0x66 : 0x64);
2176 }
2177
2178 static void setfreq(struct gspca_dev *gspca_dev)
2179 {
2180         struct sd *sd = (struct sd *) gspca_dev;
2181
2182         if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
2183                 return;
2184         if (sd->sensor == SENSOR_OV7660) {
2185                 u8 com8;
2186
2187                 com8 = 0xdf;            /* auto gain/wb/expo */
2188                 switch (sd->freq) {
2189                 case 0: /* Banding filter disabled */
2190                         i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2191                         break;
2192                 case 1: /* 50 hz */
2193                         i2c_w1(gspca_dev, 0x13, com8);
2194                         i2c_w1(gspca_dev, 0x3b, 0x0a);
2195                         break;
2196                 case 2: /* 60 hz */
2197                         i2c_w1(gspca_dev, 0x13, com8);
2198                         i2c_w1(gspca_dev, 0x3b, 0x02);
2199                         break;
2200                 }
2201         } else {
2202                 u8 reg2a = 0, reg2b = 0, reg2d = 0;
2203
2204                 /* Get reg2a / reg2d base values */
2205                 switch (sd->sensor) {
2206                 case SENSOR_OV7630:
2207                         reg2a = 0x08;
2208                         reg2d = 0x01;
2209                         break;
2210                 case SENSOR_OV7648:
2211                         reg2a = 0x11;
2212                         reg2d = 0x81;
2213                         break;
2214                 }
2215
2216                 switch (sd->freq) {
2217                 case 0: /* Banding filter disabled */
2218                         break;
2219                 case 1: /* 50 hz (filter on and framerate adj) */
2220                         reg2a |= 0x80;
2221                         reg2b = 0xac;
2222                         reg2d |= 0x04;
2223                         break;
2224                 case 2: /* 60 hz (filter on, no framerate adj) */
2225                         reg2a |= 0x80;
2226                         reg2d |= 0x04;
2227                         break;
2228                 }
2229                 i2c_w1(gspca_dev, 0x2a, reg2a);
2230                 i2c_w1(gspca_dev, 0x2b, reg2b);
2231                 i2c_w1(gspca_dev, 0x2d, reg2d);
2232         }
2233 }
2234
2235 static void setjpegqual(struct gspca_dev *gspca_dev)
2236 {
2237         struct sd *sd = (struct sd *) gspca_dev;
2238         int i, sc;
2239
2240         if (sd->jpegqual < 50)
2241                 sc = 5000 / sd->jpegqual;
2242         else
2243                 sc = 200 - sd->jpegqual * 2;
2244 #if USB_BUF_SZ < 64
2245 #error "No room enough in usb_buf for quantization table"
2246 #endif
2247         for (i = 0; i < 64; i++)
2248                 gspca_dev->usb_buf[i] =
2249                         (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2250         usb_control_msg(gspca_dev->dev,
2251                         usb_sndctrlpipe(gspca_dev->dev, 0),
2252                         0x08,
2253                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2254                         0x0100, 0,
2255                         gspca_dev->usb_buf, 64,
2256                         500);
2257         for (i = 0; i < 64; i++)
2258                 gspca_dev->usb_buf[i] =
2259                         (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2260         usb_control_msg(gspca_dev->dev,
2261                         usb_sndctrlpipe(gspca_dev->dev, 0),
2262                         0x08,
2263                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2264                         0x0140, 0,
2265                         gspca_dev->usb_buf, 64,
2266                         500);
2267
2268         sd->reg18 ^= 0x40;
2269         reg_w1(gspca_dev, 0x18, sd->reg18);
2270 }
2271
2272 /* -- start the camera -- */
2273 static int sd_start(struct gspca_dev *gspca_dev)
2274 {
2275         struct sd *sd = (struct sd *) gspca_dev;
2276         int i;
2277         u8 reg1, reg2, reg17;
2278         const u8 *sn9c1xx;
2279         const u8 (*init)[8];
2280         int mode;
2281         static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2282         static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2283         static const u8 CA_adcm1700[] =
2284                                 { 0x14, 0xec, 0x0a, 0xf6 };
2285         static const u8 CA_po2030n[] =
2286                                 { 0x1e, 0xe2, 0x14, 0xec };
2287         static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };      /* MI0360 */
2288         static const u8 CE_gc0307[] =
2289                                 { 0x32, 0xce, 0x2d, 0xd3 };
2290         static const u8 CE_ov76xx[] =
2291                                 { 0x32, 0xdd, 0x32, 0xdd };
2292         static const u8 CE_po2030n[] =
2293                                 { 0x14, 0xe7, 0x1e, 0xdd };
2294
2295         /* create the JPEG header */
2296         jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2297                         0x21);          /* JPEG 422 */
2298         jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2299
2300         /* initialize the bridge */
2301         sn9c1xx = sn_tb[sd->sensor];
2302         bridge_init(gspca_dev, sn9c1xx);
2303
2304         /* initialize the sensor */
2305         i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2306
2307         switch (sd->sensor) {
2308         case SENSOR_ADCM1700:
2309                 reg2 = 0x60;
2310                 break;
2311         case SENSOR_OM6802:
2312                 reg2 = 0x71;
2313                 break;
2314         case SENSOR_SP80708:
2315                 reg2 = 0x62;
2316                 break;
2317         default:
2318                 reg2 = 0x40;
2319                 break;
2320         }
2321         reg_w1(gspca_dev, 0x02, reg2);
2322         reg_w1(gspca_dev, 0x02, reg2);
2323
2324         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2325         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2326         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2327         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2328         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2329         if (sd->sensor == SENSOR_ADCM1700) {
2330                 reg_w1(gspca_dev, 0xd2, 0x3a);  /* AE_H_SIZE = 116 */
2331                 reg_w1(gspca_dev, 0xd3, 0x30);  /* AE_V_SIZE = 96 */
2332         } else {
2333                 reg_w1(gspca_dev, 0xd2, 0x6a);  /* AE_H_SIZE = 212 */
2334                 reg_w1(gspca_dev, 0xd3, 0x50);  /* AE_V_SIZE = 160 */
2335         }
2336         reg_w1(gspca_dev, 0xc6, 0x00);
2337         reg_w1(gspca_dev, 0xc7, 0x00);
2338         if (sd->sensor == SENSOR_ADCM1700) {
2339                 reg_w1(gspca_dev, 0xc8, 0x2c);  /* AW_H_STOP = 352 */
2340                 reg_w1(gspca_dev, 0xc9, 0x24);  /* AW_V_STOP = 288 */
2341         } else {
2342                 reg_w1(gspca_dev, 0xc8, 0x50);  /* AW_H_STOP = 640 */
2343                 reg_w1(gspca_dev, 0xc9, 0x3c);  /* AW_V_STOP = 480 */
2344         }
2345         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2346         switch (sd->sensor) {
2347         case SENSOR_GC0307:
2348                 reg17 = 0xa2;
2349                 break;
2350         case SENSOR_MT9V111:
2351                 reg17 = 0xe0;
2352                 break;
2353         case SENSOR_ADCM1700:
2354         case SENSOR_OV7630:
2355                 reg17 = 0xe2;
2356                 break;
2357         case SENSOR_OV7648:
2358                 reg17 = 0x20;
2359                 break;
2360         case SENSOR_OV7660:
2361         case SENSOR_SOI768:
2362                 reg17 = 0xa0;
2363                 break;
2364         case SENSOR_PO1030:
2365         case SENSOR_PO2030N:
2366                 reg17 = 0xa0;
2367                 break;
2368         default:
2369                 reg17 = 0x60;
2370                 break;
2371         }
2372         reg_w1(gspca_dev, 0x17, reg17);
2373
2374         reg_w1(gspca_dev, 0x05, 0x00);          /* red */
2375         reg_w1(gspca_dev, 0x07, 0x00);          /* green */
2376         reg_w1(gspca_dev, 0x06, 0x00);          /* blue */
2377         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2378
2379         setgamma(gspca_dev);
2380
2381 /*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2382         for (i = 0; i < 8; i++)
2383                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2384         switch (sd->sensor) {
2385         case SENSOR_ADCM1700:
2386         case SENSOR_OV7660:
2387         case SENSOR_SP80708:
2388                 reg_w1(gspca_dev, 0x9a, 0x05);
2389                 break;
2390         case SENSOR_GC0307:
2391         case SENSOR_MT9V111:
2392                 reg_w1(gspca_dev, 0x9a, 0x07);
2393                 break;
2394         case SENSOR_OV7630:
2395         case SENSOR_OV7648:
2396                 reg_w1(gspca_dev, 0x9a, 0x0a);
2397                 break;
2398         case SENSOR_PO2030N:
2399         case SENSOR_SOI768:
2400                 reg_w1(gspca_dev, 0x9a, 0x06);
2401                 break;
2402         default:
2403                 reg_w1(gspca_dev, 0x9a, 0x08);
2404                 break;
2405         }
2406         setsharpness(sd);
2407
2408         reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2409         reg_w1(gspca_dev, 0x05, 0x20);          /* red */
2410         reg_w1(gspca_dev, 0x07, 0x20);          /* green */
2411         reg_w1(gspca_dev, 0x06, 0x20);          /* blue */
2412
2413         init = NULL;
2414         mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2415         if (mode)
2416                 reg1 = 0x46;    /* 320x240: clk 48Mhz, video trf enable */
2417         else
2418                 reg1 = 0x06;    /* 640x480: clk 24Mhz, video trf enable */
2419         reg17 = 0x61;           /* 0x:20: enable sensor clock */
2420         switch (sd->sensor) {
2421         case SENSOR_ADCM1700:
2422                 init = adcm1700_sensor_param1;
2423                 reg1 = 0x46;
2424                 reg17 = 0xe2;
2425                 break;
2426         case SENSOR_GC0307:
2427                 init = gc0307_sensor_param1;
2428                 reg17 = 0xa2;
2429                 reg1 = 0x44;
2430                 break;
2431         case SENSOR_MO4000:
2432                 if (mode) {
2433 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
2434                         reg1 = 0x06;    /* clk 24Mz */
2435                 } else {
2436                         reg17 = 0x22;   /* 640 MCKSIZE */
2437 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
2438                 }
2439                 break;
2440         case SENSOR_MT9V111:
2441                 init = mt9v111_sensor_param1;
2442                 if (mode) {
2443                         reg1 = 0x04;    /* 320 clk 48Mhz */
2444                 } else {
2445 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
2446                         reg17 = 0xc2;
2447                 }
2448                 break;
2449         case SENSOR_OM6802:
2450                 init = om6802_sensor_param1;
2451                 reg17 = 0x64;           /* 640 MCKSIZE */
2452                 break;
2453         case SENSOR_OV7630:
2454                 init = ov7630_sensor_param1;
2455                 reg17 = 0xe2;
2456                 reg1 = 0x44;
2457                 break;
2458         case SENSOR_OV7648:
2459                 init = ov7648_sensor_param1;
2460                 reg17 = 0x21;
2461 /*              reg1 = 0x42;             * 42 - 46? */
2462                 break;
2463         case SENSOR_OV7660:
2464                 init = ov7660_sensor_param1;
2465                 if (sd->bridge == BRIDGE_SN9C120) {
2466                         if (mode) {             /* 320x240 - 160x120 */
2467                                 reg17 = 0xa2;
2468                                 reg1 = 0x44;    /* 48 Mhz, video trf eneble */
2469                         }
2470                 } else {
2471                         reg17 = 0x22;
2472                         reg1 = 0x06;    /* 24 Mhz, video trf eneble
2473                                          * inverse power down */
2474                 }
2475                 break;
2476         case SENSOR_PO1030:
2477                 init = po1030_sensor_param1;
2478                 reg17 = 0xa2;
2479                 reg1 = 0x44;
2480                 break;
2481         case SENSOR_PO2030N:
2482                 init = po2030n_sensor_param1;
2483                 reg1 = 0x46;
2484                 reg17 = 0xa2;
2485                 break;
2486         case SENSOR_SOI768:
2487                 init = soi768_sensor_param1;
2488                 reg1 = 0x44;
2489                 reg17 = 0xa2;
2490                 break;
2491         default:
2492 /*      case SENSOR_SP80708: */
2493                 init = sp80708_sensor_param1;
2494                 if (mode) {
2495 /*??                    reg1 = 0x04;     * 320 clk 48Mhz */
2496                 } else {
2497                         reg1 = 0x46;     /* 640 clk 48Mz */
2498                         reg17 = 0xa2;
2499                 }
2500                 break;
2501         }
2502
2503         /* more sensor initialization - param1 */
2504         if (init != NULL) {
2505                 i2c_w_seq(gspca_dev, init);
2506 /*              init = NULL; */
2507         }
2508
2509         reg_w(gspca_dev, 0xc0, C0, 6);
2510         switch (sd->sensor) {
2511         case SENSOR_ADCM1700:
2512         case SENSOR_GC0307:
2513         case SENSOR_SOI768:
2514                 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2515                 break;
2516         case SENSOR_PO2030N:
2517                 reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2518                 break;
2519         default:
2520                 reg_w(gspca_dev, 0xca, CA, 4);
2521                 break;
2522         }
2523         switch (sd->sensor) {
2524         case SENSOR_ADCM1700:
2525         case SENSOR_OV7630:
2526         case SENSOR_OV7648:
2527         case SENSOR_OV7660:
2528         case SENSOR_SOI768:
2529                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2530                 break;
2531         case SENSOR_GC0307:
2532                 reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2533                 break;
2534         case SENSOR_PO2030N:
2535                 reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2536                 break;
2537         default:
2538                 reg_w(gspca_dev, 0xce, CE, 4);
2539                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2540                 break;
2541         }
2542
2543
2544         /* here change size mode 0 -> VGA; 1 -> CIF */
2545         sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2546         reg_w1(gspca_dev, 0x18, sd->reg18);
2547         setjpegqual(gspca_dev);
2548
2549         reg_w1(gspca_dev, 0x17, reg17);
2550         reg_w1(gspca_dev, 0x01, reg1);
2551
2552         setvflip(sd);
2553         setbrightness(gspca_dev);
2554         setcontrast(gspca_dev);
2555         setcolors(gspca_dev);
2556         setautogain(gspca_dev);
2557         setfreq(gspca_dev);
2558         return 0;
2559 }
2560
2561 static void sd_stopN(struct gspca_dev *gspca_dev)
2562 {
2563         struct sd *sd = (struct sd *) gspca_dev;
2564         static const u8 stophv7131[] =
2565                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2566         static const u8 stopmi0360[] =
2567                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2568         static const u8 stopov7648[] =
2569                 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2570         static const u8 stopsoi768[] =
2571                 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2572         u8 data;
2573         const u8 *sn9c1xx;
2574
2575         data = 0x0b;
2576         switch (sd->sensor) {
2577         case SENSOR_GC0307:
2578                 data = 0x29;
2579                 break;
2580         case SENSOR_HV7131R:
2581                 i2c_w8(gspca_dev, stophv7131);
2582                 data = 0x2b;
2583                 break;
2584         case SENSOR_MI0360:
2585                 i2c_w8(gspca_dev, stopmi0360);
2586                 data = 0x29;
2587                 break;
2588         case SENSOR_OV7648:
2589                 i2c_w8(gspca_dev, stopov7648);
2590                 /* fall thru */
2591         case SENSOR_MT9V111:
2592         case SENSOR_OV7630:
2593         case SENSOR_PO1030:
2594                 data = 0x29;
2595                 break;
2596         case SENSOR_SOI768:
2597                 i2c_w8(gspca_dev, stopsoi768);
2598                 data = 0x29;
2599                 break;
2600         }
2601         sn9c1xx = sn_tb[sd->sensor];
2602         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2603         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2604         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2605         reg_w1(gspca_dev, 0x01, data);
2606         /* Don't disable sensor clock as that disables the button on the cam */
2607         /* reg_w1(gspca_dev, 0xf1, 0x01); */
2608 }
2609
2610 static void do_autogain(struct gspca_dev *gspca_dev)
2611 {
2612         struct sd *sd = (struct sd *) gspca_dev;
2613         int delta;
2614         int expotimes;
2615         u8 luma_mean = 130;
2616         u8 luma_delta = 20;
2617
2618         /* Thanks S., without your advice, autobright should not work :) */
2619         if (sd->ag_cnt < 0)
2620                 return;
2621         if (--sd->ag_cnt >= 0)
2622                 return;
2623         sd->ag_cnt = AG_CNT_START;
2624
2625         delta = atomic_read(&sd->avg_lum);
2626         PDEBUG(D_FRAM, "mean lum %d", delta);
2627         if (delta < luma_mean - luma_delta ||
2628             delta > luma_mean + luma_delta) {
2629                 switch (sd->sensor) {
2630                 case SENSOR_GC0307:
2631                         expotimes = sd->exposure;
2632                         expotimes += (luma_mean - delta) >> 6;
2633                         if (expotimes < 0)
2634                                 expotimes = 0;
2635                         sd->exposure = setexposure(gspca_dev,
2636                                                    (unsigned int) expotimes);
2637                         break;
2638                 case SENSOR_HV7131R:
2639                         expotimes = sd->exposure >> 8;
2640                         expotimes += (luma_mean - delta) >> 4;
2641                         if (expotimes < 0)
2642                                 expotimes = 0;
2643                         sd->exposure = setexposure(gspca_dev,
2644                                         (unsigned int) (expotimes << 8));
2645                         break;
2646                 case SENSOR_OM6802:
2647                         expotimes = sd->exposure;
2648                         expotimes += (luma_mean - delta) >> 2;
2649                         if (expotimes < 0)
2650                                 expotimes = 0;
2651                         sd->exposure = setexposure(gspca_dev,
2652                                                    (unsigned int) expotimes);
2653                         setredblue(gspca_dev);
2654                         break;
2655                 default:
2656 /*              case SENSOR_MO4000: */
2657 /*              case SENSOR_MI0360: */
2658 /*              case SENSOR_MT9V111: */
2659                         expotimes = sd->exposure;
2660                         expotimes += (luma_mean - delta) >> 6;
2661                         if (expotimes < 0)
2662                                 expotimes = 0;
2663                         sd->exposure = setexposure(gspca_dev,
2664                                                    (unsigned int) expotimes);
2665                         setredblue(gspca_dev);
2666                         break;
2667                 }
2668         }
2669 }
2670
2671 /* scan the URB packets */
2672 /* This function is run at interrupt level. */
2673 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2674                         u8 *data,                       /* isoc packet */
2675                         int len)                        /* iso packet length */
2676 {
2677         struct sd *sd = (struct sd *) gspca_dev;
2678         int sof, avg_lum;
2679
2680         sof = len - 64;
2681         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2682
2683                 /* end of frame */
2684                 gspca_frame_add(gspca_dev, LAST_PACKET,
2685                                 data, sof + 2);
2686                 if (sd->ag_cnt < 0)
2687                         return;
2688 /* w1 w2 w3 */
2689 /* w4 w5 w6 */
2690 /* w7 w8 */
2691 /* w4 */
2692                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2693 /* w6 */
2694                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2695 /* w2 */
2696                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2697 /* w8 */
2698                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2699 /* w5 */
2700                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2701                 avg_lum >>= 4;
2702                 atomic_set(&sd->avg_lum, avg_lum);
2703                 return;
2704         }
2705         if (gspca_dev->last_packet_type == LAST_PACKET) {
2706
2707                 /* put the JPEG 422 header */
2708                 gspca_frame_add(gspca_dev, FIRST_PACKET,
2709                         sd->jpeg_hdr, JPEG_HDR_SZ);
2710         }
2711         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2712 }
2713
2714 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2715 {
2716         struct sd *sd = (struct sd *) gspca_dev;
2717
2718         sd->brightness = val;
2719         if (gspca_dev->streaming)
2720                 setbrightness(gspca_dev);
2721         return 0;
2722 }
2723
2724 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2725 {
2726         struct sd *sd = (struct sd *) gspca_dev;
2727
2728         *val = sd->brightness;
2729         return 0;
2730 }
2731
2732 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2733 {
2734         struct sd *sd = (struct sd *) gspca_dev;
2735
2736         sd->contrast = val;
2737         if (gspca_dev->streaming)
2738                 setcontrast(gspca_dev);
2739         return 0;
2740 }
2741
2742 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2743 {
2744         struct sd *sd = (struct sd *) gspca_dev;
2745
2746         *val = sd->contrast;
2747         return 0;
2748 }
2749
2750 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2751 {
2752         struct sd *sd = (struct sd *) gspca_dev;
2753
2754         sd->colors = val;
2755         if (gspca_dev->streaming)
2756                 setcolors(gspca_dev);
2757         return 0;
2758 }
2759
2760 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2761 {
2762         struct sd *sd = (struct sd *) gspca_dev;
2763
2764         *val = sd->colors;
2765         return 0;
2766 }
2767
2768 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2769 {
2770         struct sd *sd = (struct sd *) gspca_dev;
2771
2772         sd->blue = val;
2773         if (gspca_dev->streaming)
2774                 setredblue(gspca_dev);
2775         return 0;
2776 }
2777
2778 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2779 {
2780         struct sd *sd = (struct sd *) gspca_dev;
2781
2782         *val = sd->blue;
2783         return 0;
2784 }
2785
2786 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2787 {
2788         struct sd *sd = (struct sd *) gspca_dev;
2789
2790         sd->red = val;
2791         if (gspca_dev->streaming)
2792                 setredblue(gspca_dev);
2793         return 0;
2794 }
2795
2796 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2797 {
2798         struct sd *sd = (struct sd *) gspca_dev;
2799
2800         *val = sd->red;
2801         return 0;
2802 }
2803
2804 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2805 {
2806         struct sd *sd = (struct sd *) gspca_dev;
2807
2808         sd->gamma = val;
2809         if (gspca_dev->streaming)
2810                 setgamma(gspca_dev);
2811         return 0;
2812 }
2813
2814 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2815 {
2816         struct sd *sd = (struct sd *) gspca_dev;
2817
2818         *val = sd->gamma;
2819         return 0;
2820 }
2821
2822 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2823 {
2824         struct sd *sd = (struct sd *) gspca_dev;
2825
2826         sd->autogain = val;
2827         if (gspca_dev->streaming)
2828                 setautogain(gspca_dev);
2829         return 0;
2830 }
2831
2832 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2833 {
2834         struct sd *sd = (struct sd *) gspca_dev;
2835
2836         *val = sd->autogain;
2837         return 0;
2838 }
2839
2840 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2841 {
2842         struct sd *sd = (struct sd *) gspca_dev;
2843
2844         sd->sharpness = val;
2845         if (gspca_dev->streaming)
2846                 setsharpness(sd);
2847         return 0;
2848 }
2849
2850 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2851 {
2852         struct sd *sd = (struct sd *) gspca_dev;
2853
2854         *val = sd->sharpness;
2855         return 0;
2856 }
2857
2858 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2859 {
2860         struct sd *sd = (struct sd *) gspca_dev;
2861
2862         sd->vflip = val;
2863         if (gspca_dev->streaming)
2864                 setvflip(sd);
2865         return 0;
2866 }
2867
2868 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2869 {
2870         struct sd *sd = (struct sd *) gspca_dev;
2871
2872         *val = sd->vflip;
2873         return 0;
2874 }
2875
2876 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2877 {
2878         struct sd *sd = (struct sd *) gspca_dev;
2879
2880         sd->infrared = val;
2881         if (gspca_dev->streaming)
2882                 setinfrared(sd);
2883         return 0;
2884 }
2885
2886 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2887 {
2888         struct sd *sd = (struct sd *) gspca_dev;
2889
2890         *val = sd->infrared;
2891         return 0;
2892 }
2893
2894 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2895 {
2896         struct sd *sd = (struct sd *) gspca_dev;
2897
2898         sd->freq = val;
2899         if (gspca_dev->streaming)
2900                 setfreq(gspca_dev);
2901         return 0;
2902 }
2903
2904 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2905 {
2906         struct sd *sd = (struct sd *) gspca_dev;
2907
2908         *val = sd->freq;
2909         return 0;
2910 }
2911
2912 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2913                         struct v4l2_jpegcompression *jcomp)
2914 {
2915         struct sd *sd = (struct sd *) gspca_dev;
2916
2917         if (jcomp->quality < QUALITY_MIN)
2918                 sd->quality = QUALITY_MIN;
2919         else if (jcomp->quality > QUALITY_MAX)
2920                 sd->quality = QUALITY_MAX;
2921         else
2922                 sd->quality = jcomp->quality;
2923         if (gspca_dev->streaming)
2924                 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2925         return 0;
2926 }
2927
2928 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2929                         struct v4l2_jpegcompression *jcomp)
2930 {
2931         struct sd *sd = (struct sd *) gspca_dev;
2932
2933         memset(jcomp, 0, sizeof *jcomp);
2934         jcomp->quality = sd->quality;
2935         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2936                         | V4L2_JPEG_MARKER_DQT;
2937         return 0;
2938 }
2939
2940 static int sd_querymenu(struct gspca_dev *gspca_dev,
2941                         struct v4l2_querymenu *menu)
2942 {
2943         switch (menu->id) {
2944         case V4L2_CID_POWER_LINE_FREQUENCY:
2945                 switch (menu->index) {
2946                 case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2947                         strcpy((char *) menu->name, "NoFliker");
2948                         return 0;
2949                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2950                         strcpy((char *) menu->name, "50 Hz");
2951                         return 0;
2952                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2953                         strcpy((char *) menu->name, "60 Hz");
2954                         return 0;
2955                 }
2956                 break;
2957         }
2958         return -EINVAL;
2959 }
2960
2961 #ifdef CONFIG_INPUT
2962 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2963                         u8 *data,               /* interrupt packet data */
2964                         int len)                /* interrupt packet length */
2965 {
2966         int ret = -EINVAL;
2967
2968         if (len == 1 && data[0] == 1) {
2969                 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2970                 input_sync(gspca_dev->input_dev);
2971                 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2972                 input_sync(gspca_dev->input_dev);
2973                 ret = 0;
2974         }
2975
2976         return ret;
2977 }
2978 #endif
2979
2980 /* sub-driver description */
2981 static const struct sd_desc sd_desc = {
2982         .name = MODULE_NAME,
2983         .ctrls = sd_ctrls,
2984         .nctrls = ARRAY_SIZE(sd_ctrls),
2985         .config = sd_config,
2986         .init = sd_init,
2987         .start = sd_start,
2988         .stopN = sd_stopN,
2989         .pkt_scan = sd_pkt_scan,
2990         .dq_callback = do_autogain,
2991         .get_jcomp = sd_get_jcomp,
2992         .set_jcomp = sd_set_jcomp,
2993         .querymenu = sd_querymenu,
2994 #ifdef CONFIG_INPUT
2995         .int_pkt_scan = sd_int_pkt_scan,
2996 #endif
2997 };
2998
2999 /* -- module initialisation -- */
3000 #define BS(bridge, sensor) \
3001         .driver_info = (BRIDGE_ ## bridge << 16) \
3002                         | SENSOR_ ## sensor
3003 static const __devinitdata struct usb_device_id device_table[] = {
3004 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3005         {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
3006         {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
3007 #endif
3008         {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
3009         {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
3010         {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
3011         {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
3012         {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3013         {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3014         {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3015 /*      {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3016         {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3017 /*      {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3018 /*      {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3019         {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3020 /*      {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3021         {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
3022 /*      {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3023 /*      {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3024 /*      {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3025         {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3026         {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3027 /*      {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3028 /*      {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3029 /*      {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3030         {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3031 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3032         {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3033         {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3034 #endif
3035         {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},      /*sn9c128*/
3036 /*      {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/
3037 /*      {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3038         {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},      /*sn9c128*/
3039         {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},      /*sn9c128*/
3040         {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)},     /*sn9c128*/
3041         {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},      /*sn9c128*/
3042 /*      {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3043 /*      {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3044 /*      {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3045         {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},      /*sn9c325?*/
3046 /*bw600.inf:*/
3047         {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},      /*sn9c325?*/
3048         {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3049         {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3050 /*      {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
3051 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3052         {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
3053 #endif
3054 /*      {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3055         {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3056         {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
3057 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3058         {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
3059 #endif
3060         {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3061         {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3062         {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},     /*sn9c120b*/
3063                                                 /* or GC0305 / GC0307 */
3064         {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},     /*sn9c120b*/
3065         {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},      /*sn9c120b*/
3066         {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)},    /*sn9c120b*/
3067         {}
3068 };
3069 MODULE_DEVICE_TABLE(usb, device_table);
3070
3071 /* -- device connect -- */
3072 static int sd_probe(struct usb_interface *intf,
3073                     const struct usb_device_id *id)
3074 {
3075         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3076                                 THIS_MODULE);
3077 }
3078
3079 static struct usb_driver sd_driver = {
3080         .name = MODULE_NAME,
3081         .id_table = device_table,
3082         .probe = sd_probe,
3083         .disconnect = gspca_disconnect,
3084 #ifdef CONFIG_PM
3085         .suspend = gspca_suspend,
3086         .resume = gspca_resume,
3087 #endif
3088 };
3089
3090 /* -- module insert / remove -- */
3091 static int __init sd_mod_init(void)
3092 {
3093         int ret;
3094         ret = usb_register(&sd_driver);
3095         if (ret < 0)
3096                 return ret;
3097         info("registered");
3098         return 0;
3099 }
3100 static void __exit sd_mod_exit(void)
3101 {
3102         usb_deregister(&sd_driver);
3103         info("deregistered");
3104 }
3105
3106 module_init(sd_mod_init);
3107 module_exit(sd_mod_exit);