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