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