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