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