V4L/DVB (9852): gspca: Fix image problem at low resolutions with ov7660 in sonixj.
[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 reg8a[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                 reg8a[i * 2] = v;
1218                 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1219         }
1220         reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
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 (sd->bridge == BRIDGE_SN9C120) {
1377                         if (mode) {             /* 320x240 - 160x120 */
1378                                 reg17 = 0xa2;
1379                                 reg1 = 0x44;    /* 48 Mhz, video trf eneble */
1380                         }
1381                 } else {
1382                         reg17 = 0x22;
1383                         reg1 = 0x06;    /* 24 Mhz, video trf eneble
1384                                          * inverse power down */
1385                 }
1386                 break;
1387         }
1388         reg_w(gspca_dev, 0xc0, C0, 6);
1389         reg_w(gspca_dev, 0xca, CA, 4);
1390         switch (sd->sensor) {
1391         case SENSOR_OV7630:
1392         case SENSOR_OV7648:
1393         case SENSOR_OV7660:
1394                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1395                 break;
1396         default:
1397                 reg_w(gspca_dev, 0xce, CE, 4);
1398                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1399                 break;
1400         }
1401
1402         /* here change size mode 0 -> VGA; 1 -> CIF */
1403         reg18 = sn9c1xx[0x18] | (mode << 4);
1404         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1405
1406         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1407         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1408
1409         reg_w1(gspca_dev, 0x18, reg18);
1410
1411         reg_w1(gspca_dev, 0x17, reg17);
1412         reg_w1(gspca_dev, 0x01, reg1);
1413         switch (sd->sensor) {
1414         case SENSOR_MI0360:
1415                 setinfrared(sd);
1416                 break;
1417         case SENSOR_OV7630:
1418                 setvflip(sd);
1419                 break;
1420         }
1421         setbrightness(gspca_dev);
1422         setcontrast(gspca_dev);
1423         setautogain(gspca_dev);
1424         return 0;
1425 }
1426
1427 static void sd_stopN(struct gspca_dev *gspca_dev)
1428 {
1429         struct sd *sd = (struct sd *) gspca_dev;
1430         static const __u8 stophv7131[] =
1431                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1432         static const __u8 stopmi0360[] =
1433                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1434         static const __u8 stopov7648[] =
1435                 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1436         __u8 data;
1437         const __u8 *sn9c1xx;
1438
1439         data = 0x0b;
1440         switch (sd->sensor) {
1441         case SENSOR_HV7131R:
1442                 i2c_w8(gspca_dev, stophv7131);
1443                 data = 0x2b;
1444                 break;
1445         case SENSOR_MI0360:
1446                 i2c_w8(gspca_dev, stopmi0360);
1447                 data = 0x29;
1448                 break;
1449         case SENSOR_OV7648:
1450                 i2c_w8(gspca_dev, stopov7648);
1451                 /* fall thru */
1452         case SENSOR_OV7630:
1453                 data = 0x29;
1454                 break;
1455         default:
1456 /*      case SENSOR_MO4000: */
1457 /*      case SENSOR_OV7660: */
1458                 break;
1459         }
1460         sn9c1xx = sn_tb[(int) sd->sensor];
1461         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1462         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1463         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1464         reg_w1(gspca_dev, 0x01, data);
1465         reg_w1(gspca_dev, 0xf1, 0x00);
1466 }
1467
1468 static void do_autogain(struct gspca_dev *gspca_dev)
1469 {
1470         struct sd *sd = (struct sd *) gspca_dev;
1471         int delta;
1472         int expotimes;
1473         __u8 luma_mean = 130;
1474         __u8 luma_delta = 20;
1475
1476         /* Thanks S., without your advice, autobright should not work :) */
1477         if (sd->ag_cnt < 0)
1478                 return;
1479         if (--sd->ag_cnt >= 0)
1480                 return;
1481         sd->ag_cnt = AG_CNT_START;
1482
1483         delta = atomic_read(&sd->avg_lum);
1484         PDEBUG(D_FRAM, "mean lum %d", delta);
1485         if (delta < luma_mean - luma_delta ||
1486             delta > luma_mean + luma_delta) {
1487                 switch (sd->sensor) {
1488                 case SENSOR_HV7131R:
1489                         expotimes = sd->exposure >> 8;
1490                         expotimes += (luma_mean - delta) >> 4;
1491                         if (expotimes < 0)
1492                                 expotimes = 0;
1493                         sd->exposure = setexposure(gspca_dev,
1494                                         (unsigned int) (expotimes << 8));
1495                         break;
1496                 default:
1497 /*              case SENSOR_MO4000: */
1498 /*              case SENSOR_MI0360: */
1499 /*              case SENSOR_OM6802: */
1500                         expotimes = sd->exposure;
1501                         expotimes += (luma_mean - delta) >> 6;
1502                         if (expotimes < 0)
1503                                 expotimes = 0;
1504                         sd->exposure = setexposure(gspca_dev,
1505                                                    (unsigned int) expotimes);
1506                         setredblue(gspca_dev);
1507                         break;
1508                 }
1509         }
1510 }
1511
1512 /* scan the URB packets */
1513 /* This function is run at interrupt level. */
1514 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1515                         struct gspca_frame *frame,      /* target */
1516                         __u8 *data,                     /* isoc packet */
1517                         int len)                        /* iso packet length */
1518 {
1519         struct sd *sd = (struct sd *) gspca_dev;
1520         int sof, avg_lum;
1521
1522         sof = len - 64;
1523         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1524
1525                 /* end of frame */
1526                 gspca_frame_add(gspca_dev, LAST_PACKET,
1527                                 frame, data, sof + 2);
1528                 if (sd->ag_cnt < 0)
1529                         return;
1530 /* w1 w2 w3 */
1531 /* w4 w5 w6 */
1532 /* w7 w8 */
1533 /* w4 */
1534                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1535 /* w6 */
1536                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1537 /* w2 */
1538                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1539 /* w8 */
1540                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1541 /* w5 */
1542                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1543                 avg_lum >>= 4;
1544                 atomic_set(&sd->avg_lum, avg_lum);
1545                 return;
1546         }
1547         if (gspca_dev->last_packet_type == LAST_PACKET) {
1548
1549                 /* put the JPEG 422 header */
1550                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1551         }
1552         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1553 }
1554
1555 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1556 {
1557         struct sd *sd = (struct sd *) gspca_dev;
1558
1559         sd->brightness = val;
1560         if (gspca_dev->streaming)
1561                 setbrightness(gspca_dev);
1562         return 0;
1563 }
1564
1565 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1566 {
1567         struct sd *sd = (struct sd *) gspca_dev;
1568
1569         *val = sd->brightness;
1570         return 0;
1571 }
1572
1573 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1574 {
1575         struct sd *sd = (struct sd *) gspca_dev;
1576
1577         sd->contrast = val;
1578         if (gspca_dev->streaming)
1579                 setcontrast(gspca_dev);
1580         return 0;
1581 }
1582
1583 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1584 {
1585         struct sd *sd = (struct sd *) gspca_dev;
1586
1587         *val = sd->contrast;
1588         return 0;
1589 }
1590
1591 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1592 {
1593         struct sd *sd = (struct sd *) gspca_dev;
1594
1595         sd->colors = val;
1596         if (gspca_dev->streaming)
1597                 setcolors(gspca_dev);
1598         return 0;
1599 }
1600
1601 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1602 {
1603         struct sd *sd = (struct sd *) gspca_dev;
1604
1605         *val = sd->colors;
1606         return 0;
1607 }
1608
1609 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1610 {
1611         struct sd *sd = (struct sd *) gspca_dev;
1612
1613         sd->blue = val;
1614         if (gspca_dev->streaming)
1615                 setredblue(gspca_dev);
1616         return 0;
1617 }
1618
1619 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1620 {
1621         struct sd *sd = (struct sd *) gspca_dev;
1622
1623         *val = sd->blue;
1624         return 0;
1625 }
1626
1627 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1628 {
1629         struct sd *sd = (struct sd *) gspca_dev;
1630
1631         sd->red = val;
1632         if (gspca_dev->streaming)
1633                 setredblue(gspca_dev);
1634         return 0;
1635 }
1636
1637 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1638 {
1639         struct sd *sd = (struct sd *) gspca_dev;
1640
1641         *val = sd->red;
1642         return 0;
1643 }
1644
1645 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1646 {
1647         struct sd *sd = (struct sd *) gspca_dev;
1648
1649         sd->autogain = val;
1650         if (gspca_dev->streaming)
1651                 setautogain(gspca_dev);
1652         return 0;
1653 }
1654
1655 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1656 {
1657         struct sd *sd = (struct sd *) gspca_dev;
1658
1659         *val = sd->autogain;
1660         return 0;
1661 }
1662
1663 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1664 {
1665         struct sd *sd = (struct sd *) gspca_dev;
1666
1667         sd->vflip = val;
1668         if (gspca_dev->streaming)
1669                 setvflip(sd);
1670         return 0;
1671 }
1672
1673 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1674 {
1675         struct sd *sd = (struct sd *) gspca_dev;
1676
1677         *val = sd->vflip;
1678         return 0;
1679 }
1680
1681 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1682 {
1683         struct sd *sd = (struct sd *) gspca_dev;
1684
1685         sd->infrared = val;
1686         if (gspca_dev->streaming)
1687                 setinfrared(sd);
1688         return 0;
1689 }
1690
1691 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1692 {
1693         struct sd *sd = (struct sd *) gspca_dev;
1694
1695         *val = sd->infrared;
1696         return 0;
1697 }
1698
1699 /* sub-driver description */
1700 static const struct sd_desc sd_desc = {
1701         .name = MODULE_NAME,
1702         .ctrls = sd_ctrls,
1703         .nctrls = ARRAY_SIZE(sd_ctrls),
1704         .config = sd_config,
1705         .init = sd_init,
1706         .start = sd_start,
1707         .stopN = sd_stopN,
1708         .pkt_scan = sd_pkt_scan,
1709         .dq_callback = do_autogain,
1710 };
1711
1712 /* -- module initialisation -- */
1713 #define BSI(bridge, sensor, i2c_addr) \
1714         .driver_info = (BRIDGE_ ## bridge << 16) \
1715                         | (SENSOR_ ## sensor << 8) \
1716                         | (i2c_addr)
1717 static const __devinitdata struct usb_device_id device_table[] = {
1718 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1719         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1720         {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1721 #endif
1722         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1723         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1724 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1725         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1726 #endif
1727         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1728         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1729         {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1730         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1731 /* bw600.inf:
1732         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1733 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1734 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1735         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1736 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1737         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1738 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1739 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1740         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1741 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1742 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1743         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1744         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1745 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1746         {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1747 #endif
1748 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1749 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1750 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1751         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1752 /*bw600.inf:*/
1753         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1754         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1755         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1756 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1757 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1758         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1759 #endif
1760         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1761         {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1762 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1763         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1764         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1765 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1766 #endif
1767         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1768         {}
1769 };
1770 MODULE_DEVICE_TABLE(usb, device_table);
1771
1772 /* -- device connect -- */
1773 static int sd_probe(struct usb_interface *intf,
1774                     const struct usb_device_id *id)
1775 {
1776         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1777                                 THIS_MODULE);
1778 }
1779
1780 static struct usb_driver sd_driver = {
1781         .name = MODULE_NAME,
1782         .id_table = device_table,
1783         .probe = sd_probe,
1784         .disconnect = gspca_disconnect,
1785 #ifdef CONFIG_PM
1786         .suspend = gspca_suspend,
1787         .resume = gspca_resume,
1788 #endif
1789 };
1790
1791 /* -- module insert / remove -- */
1792 static int __init sd_mod_init(void)
1793 {
1794         if (usb_register(&sd_driver) < 0)
1795                 return -1;
1796         info("registered");
1797         return 0;
1798 }
1799 static void __exit sd_mod_exit(void)
1800 {
1801         usb_deregister(&sd_driver);
1802         info("deregistered");
1803 }
1804
1805 module_init(sd_mod_init);
1806 module_exit(sd_mod_exit);