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