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