b60ff600a757817907402346b3a78743fa87f2f0
[sfrench/cifs-2.6.git] / drivers / media / video / gspca / sonixj.c
1 /*
2  *              Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "sonixj"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29 MODULE_LICENSE("GPL");
30
31 /* specific webcam descriptor */
32 struct sd {
33         struct gspca_dev gspca_dev;     /* !! must be the first item */
34
35         int avg_lum;
36         unsigned int exposure;
37
38         unsigned short brightness;
39         unsigned char contrast;
40         unsigned char colors;
41         unsigned char autogain;
42
43         signed char ag_cnt;
44 #define AG_CNT_START 13
45
46         char qindex;
47         unsigned char bridge;
48 #define BRIDGE_SN9C102P 0
49 #define BRIDGE_SN9C105 1
50 #define BRIDGE_SN9C110 2
51 #define BRIDGE_SN9C120 3
52 #define BRIDGE_SN9C325 4
53         char sensor;                    /* Type of image sensor chip */
54 #define SENSOR_HV7131R 0
55 #define SENSOR_MI0360 1
56 #define SENSOR_MO4000 2
57 #define SENSOR_OV7648 3
58 #define SENSOR_OV7660 4
59         unsigned char i2c_base;
60 };
61
62 /* V4L2 controls supported by the driver */
63 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
71
72 static struct ctrl sd_ctrls[] = {
73         {
74             {
75                 .id      = V4L2_CID_BRIGHTNESS,
76                 .type    = V4L2_CTRL_TYPE_INTEGER,
77                 .name    = "Brightness",
78                 .minimum = 0,
79                 .maximum = 0xffff,
80                 .step    = 1,
81 #define BRIGHTNESS_DEF 0x7fff
82                 .default_value = BRIGHTNESS_DEF,
83             },
84             .set = sd_setbrightness,
85             .get = sd_getbrightness,
86         },
87         {
88             {
89                 .id      = V4L2_CID_CONTRAST,
90                 .type    = V4L2_CTRL_TYPE_INTEGER,
91                 .name    = "Contrast",
92                 .minimum = 0,
93                 .maximum = 127,
94                 .step    = 1,
95 #define CONTRAST_DEF 63
96                 .default_value = CONTRAST_DEF,
97             },
98             .set = sd_setcontrast,
99             .get = sd_getcontrast,
100         },
101         {
102             {
103                 .id      = V4L2_CID_SATURATION,
104                 .type    = V4L2_CTRL_TYPE_INTEGER,
105                 .name    = "Color",
106                 .minimum = 0,
107                 .maximum = 255,
108                 .step    = 1,
109 #define COLOR_DEF 127
110                 .default_value = COLOR_DEF,
111             },
112             .set = sd_setcolors,
113             .get = sd_getcolors,
114         },
115         {
116             {
117                 .id      = V4L2_CID_AUTOGAIN,
118                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
119                 .name    = "Auto Gain",
120                 .minimum = 0,
121                 .maximum = 1,
122                 .step    = 1,
123 #define AUTOGAIN_DEF 1
124                 .default_value = AUTOGAIN_DEF,
125             },
126             .set = sd_setautogain,
127             .get = sd_getautogain,
128         },
129 };
130
131 static struct v4l2_pix_format vga_mode[] = {
132         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133                 .bytesperline = 160,
134                 .sizeimage = 160 * 120 * 3 / 8 + 590,
135                 .colorspace = V4L2_COLORSPACE_JPEG,
136                 .priv = 2},
137         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
138                 .bytesperline = 320,
139                 .sizeimage = 320 * 240 * 3 / 8 + 590,
140                 .colorspace = V4L2_COLORSPACE_JPEG,
141                 .priv = 1},
142         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
143                 .bytesperline = 640,
144                 .sizeimage = 640 * 480 * 3 / 8 + 590,
145                 .colorspace = V4L2_COLORSPACE_JPEG,
146                 .priv = 0},
147 };
148
149 /*Data from sn9c102p+hv71331r */
150 static const __u8 sn_hv7131[] = {
151 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
152         0x00,   0x03,   0x64,   0x00,   0x1a,   0x20,   0x20,   0x20,
153 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
154         0xa1,   0x11,   0x02,   0x09,   0x00,   0x00,   0x00,   0x10,
155 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
156         0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
157 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
158         0x0a,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
159 };
160
161 static const __u8 sn_mi0360[] = {
162 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
163         0x00,   0x61,   0x44,   0x00,   0x1a,   0x20,   0x20,   0x20,
164 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
165         0xb1,   0x5d,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
166 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
167         0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
168 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
169         0x06,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
170 };
171
172 static const __u8 sn_mo4000[] = {
173 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
174         0x12,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
175 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
176         0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
177 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
178         0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
179 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
180         0x08,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00
181 };
182
183 static const __u8 sn_ov7648[] = {
184 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
185         0x00,   0x21,   0x62,   0x00,   0x1a,   0x20,   0x20,   0x20,
186 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
187         0xa1,   0x6e,   0x18,   0x65,   0x00,   0x00,   0x00,   0x10,
188 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
189         0x03,   0x00,   0x00,   0x06,   0x06,   0x28,   0x1e,   0x82,
190 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
191         0x07,   0x00,   0x00,   0x00,   0x00,   0x00
192 };
193
194 static const __u8 sn_ov7660[]   = {
195 /*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
196         0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
197 /*      reg8    reg9    rega    regb    regc    regd    rege    regf */
198         0x81,   0x21,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
199 /*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
200         0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
201 /*      reg18   reg19   reg1a   reg1b   reg1c   reg1d   reg1e   reg1f */
202         0x07,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
203 };
204
205 /* sequence specific to the sensors - !! index = SENSOR_xxx */
206 static const __u8 *sn_tb[] = {
207         sn_hv7131,
208         sn_mi0360,
209         sn_mo4000,
210         sn_ov7648,
211         sn_ov7660
212 };
213
214 static const __u8 regsn20[] = {
215         0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
216         0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
217 };
218 static const __u8 regsn20_sn9c325[] = {
219         0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
220         0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
221 };
222
223 static const __u8 reg84[] = {
224         0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
225         0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
226 /*      0x00, 0x00, 0x00, 0x00, 0x00 */
227         0xf7, 0x0f, 0x0a, 0x00, 0x00
228 };
229 static const __u8 reg84_sn9c325[] = {
230         0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
231         0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
232         0xf8, 0x0f, 0x00, 0x00, 0x00
233 };
234
235 static const __u8 hv7131r_sensor_init[][8] = {
236         {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
237         {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
238         {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
239         {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
240         {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
241         {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
242         {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
243
244         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
245         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
246         {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
247         {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
248         {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
249         {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
250         {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
251         {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
252
253         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
254         {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
255         {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
256         {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
257         {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
258
259         {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
260         {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
261         {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
262         {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
263         {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
264         {}
265 };
266 static const __u8 mi0360_sensor_init[][8] = {
267         {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
268         {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
269         {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
270         {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
271         {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
272         {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
273         {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
274         {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
275         {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
276         {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
277         {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
278         {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
279         {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
280         {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
281         {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
282         {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
283         {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
284         {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
285         {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
286         {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
287         {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
288         {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
289         {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
290         {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
291         {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
292         {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
293         {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
294         {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
295         {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
296         {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
297         {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
298         {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
299         {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
300
301         {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
302         {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
303         {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
304         {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
305         {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
306
307         {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
308         {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
309         {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
310         {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
311
312         {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
313         {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
314 /*      {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
315 /*      {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
316         {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
317         {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
318         {}
319 };
320 static const __u8 mo4000_sensor_init[][8] = {
321         {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
322         {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
323         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
324         {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
325         {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
326         {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
327         {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
328         {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
329         {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
330         {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
331         {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
332         {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
333         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
334         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
335         {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
336         {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
337         {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
338         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
339         {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
340         {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
341         {}
342 };
343 static const __u8 ov7660_sensor_init[][8] = {
344         {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
345 /*              (delay 20ms) */
346         {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
347                                                 /* Outformat = rawRGB */
348         {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
349         {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
350                                                 /* GAIN BLUE RED VREF */
351         {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
352                                                 /* COM 1 BAVE GEAVE AECHH */
353         {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
354         {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
355         {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
356                                                 /* AECH CLKRC COM7 COM8 */
357         {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
358         {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
359                                                 /* HSTART HSTOP VSTRT VSTOP */
360         {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
361         {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
362         {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
363                                         /* BOS GBOS GROS ROS (BGGR offset) */
364 /*      {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
365         {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
366                                                 /* AEW AEB VPT BBIAS */
367         {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
368                                                 /* GbBIAS RSVD EXHCH EXHCL */
369         {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
370                                                 /* RBIAS ADVFL ASDVFH YAVE */
371         {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
372                                                 /* HSYST HSYEN HREF */
373         {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
374         {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
375                                                 /* ADC ACOM OFON TSLB */
376         {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
377                                                 /* COM11 COM12 COM13 COM14 */
378         {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
379                                                 /* EDGE COM15 COM16 COM17 */
380         {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
381         {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
382         {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
383         {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
384         {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
385         {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
386         {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
387         {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
388         {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
389         {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
390                                                 /* LCC1 LCC2 LCC3 LCC4 */
391         {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
392         {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
393         {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
394                                         /* band gap reference [0:3] DBLV */
395         {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
396         {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
397         {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
398         {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
399         {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
400         {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
401         {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
402         {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
403         {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
404         {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
405 /****** (some exchanges in the win trace) ******/
406         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
407                                                 /* bits[3..0]reserved */
408         {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
409         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
410                                                 /* VREF vertical frame ctrl */
411         {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
412         {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
413         {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
414         {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
415         {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
416 /*      {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
417 /****** (some exchanges in the win trace) ******/
418         {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
419         {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
420         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
421         {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
422 /*      {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
423 /****** (some exchanges in the win trace) ******/
424 /******!! startsensor KO if changed !!****/
425         {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
426         {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
427         {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
428         {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
429         {}
430 };
431 /*        reg 0x04        reg 0x07                 reg 0x10 */
432 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
433
434 static const __u8 ov7648_sensor_init[][8] = {
435         {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
436         {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
437         {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
438         {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
439         {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
440         {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
441         {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
442         {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
443         {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
444         {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
445         {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
446         {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
447         {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
448         {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
449         {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
450         {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
451         {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
452         {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
453         {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
454         {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
455         {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
456         {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
457         {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
458         {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
459         {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
460         {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
461         {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
462         {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
463         {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
464   /*    {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
465         {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
466  * This is currently setting a
467  * blue tint, and some things more , i leave it here for future test if
468  * somene is having problems with color on this sensor
469         {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
470         {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
471         {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
472         {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
473         {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
474         {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
475         {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
476         {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
477         {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
478         {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
479         {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
480         {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
481         {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10},  */
482         {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
483         {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
484         {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
485         {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
486 /*      {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10},  * Bright/Witene */
487         {}
488 };
489
490 static const __u8 qtable4[] = {
491         0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
492         0x06, 0x08, 0x0A, 0x11,
493         0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
494         0x19, 0x19, 0x17, 0x15,
495         0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
496         0x21, 0x2E, 0x21, 0x23,
497         0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
498         0x25, 0x29, 0x2C, 0x29,
499         0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
500         0x17, 0x1B, 0x29, 0x29,
501         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
502         0x29, 0x29, 0x29, 0x29,
503         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
504         0x29, 0x29, 0x29, 0x29,
505         0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
506         0x29, 0x29, 0x29, 0x29
507 };
508
509 /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
510 static void reg_r(struct gspca_dev *gspca_dev,
511                   __u16 value, int len)
512 {
513         usb_control_msg(gspca_dev->dev,
514                         usb_rcvctrlpipe(gspca_dev->dev, 0),
515                         0,
516                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
517                         value, 0,
518                         gspca_dev->usb_buf, len,
519                         500);
520         PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
521 }
522
523 static void reg_w1(struct gspca_dev *gspca_dev,
524                    __u16 value,
525                    __u8 data)
526 {
527         PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
528         gspca_dev->usb_buf[0] = data;
529         usb_control_msg(gspca_dev->dev,
530                         usb_sndctrlpipe(gspca_dev->dev, 0),
531                         0x08,
532                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
533                         value,
534                         0,
535                         gspca_dev->usb_buf, 1,
536                         500);
537 }
538 static void reg_w(struct gspca_dev *gspca_dev,
539                           __u16 value,
540                           const __u8 *buffer,
541                           int len)
542 {
543         PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
544                 value, buffer[0], buffer[1]);
545         if (len <= sizeof gspca_dev->usb_buf) {
546                 memcpy(gspca_dev->usb_buf, buffer, len);
547                 usb_control_msg(gspca_dev->dev,
548                                 usb_sndctrlpipe(gspca_dev->dev, 0),
549                                 0x08,
550                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
551                                 value, 0,
552                                 gspca_dev->usb_buf, len,
553                                 500);
554         } else {
555                 __u8 *tmpbuf;
556
557                 tmpbuf = kmalloc(len, GFP_KERNEL);
558                 memcpy(tmpbuf, buffer, len);
559                 usb_control_msg(gspca_dev->dev,
560                                 usb_sndctrlpipe(gspca_dev->dev, 0),
561                                 0x08,
562                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
563                                 value, 0,
564                                 tmpbuf, len,
565                                 500);
566                 kfree(tmpbuf);
567         }
568 }
569
570 /* I2C write 1 byte */
571 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
572 {
573         struct sd *sd = (struct sd *) gspca_dev;
574
575         PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
576         gspca_dev->usb_buf[0] = 0x81 | (2 << 4);        /* = a1 */
577         gspca_dev->usb_buf[1] = sd->i2c_base;
578         gspca_dev->usb_buf[2] = reg;
579         gspca_dev->usb_buf[3] = val;
580         gspca_dev->usb_buf[4] = 0;
581         gspca_dev->usb_buf[5] = 0;
582         gspca_dev->usb_buf[6] = 0;
583         gspca_dev->usb_buf[7] = 0x10;
584         usb_control_msg(gspca_dev->dev,
585                         usb_sndctrlpipe(gspca_dev->dev, 0),
586                         0x08,
587                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
588                         0x08,                   /* value = i2c */
589                         0,
590                         gspca_dev->usb_buf, 8,
591                         500);
592 }
593
594 /* I2C write 8 bytes */
595 static void i2c_w8(struct gspca_dev *gspca_dev,
596                    const __u8 *buffer)
597 {
598         memcpy(gspca_dev->usb_buf, buffer, 8);
599         usb_control_msg(gspca_dev->dev,
600                         usb_sndctrlpipe(gspca_dev->dev, 0),
601                         0x08,
602                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
603                         0x08, 0,                /* value, index */
604                         gspca_dev->usb_buf, 8,
605                         500);
606 }
607
608 /* read 5 bytes in gspca_dev->usb_buf */
609 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
610 {
611         struct sd *sd = (struct sd *) gspca_dev;
612         __u8 mode[8];
613
614         mode[0] = 0x81 | 0x10;
615         mode[1] = sd->i2c_base;
616         mode[2] = reg;
617         mode[3] = 0;
618         mode[4] = 0;
619         mode[5] = 0;
620         mode[6] = 0;
621         mode[7] = 0x10;
622         i2c_w8(gspca_dev, mode);
623         msleep(2);
624         mode[0] = 0x81 | (5 << 4) | 0x02;
625         mode[2] = 0;
626         i2c_w8(gspca_dev, mode);
627         msleep(2);
628         reg_r(gspca_dev, 0x0a, 5);
629 }
630
631 static int probesensor(struct gspca_dev *gspca_dev)
632 {
633         struct sd *sd = (struct sd *) gspca_dev;
634
635         i2c_w1(gspca_dev, 0x02, 0);                     /* sensor wakeup */
636         msleep(10);
637         reg_w1(gspca_dev, 0x02, 0x66);                  /* Gpio on */
638         msleep(10);
639         i2c_r5(gspca_dev, 0);                           /* read sensor id */
640         if (gspca_dev->usb_buf[0] == 0x02
641             && gspca_dev->usb_buf[1] == 0x09
642             && gspca_dev->usb_buf[2] == 0x01
643             && gspca_dev->usb_buf[3] == 0x00
644             && gspca_dev->usb_buf[4] == 0x00) {
645                 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
646                 sd->sensor = SENSOR_HV7131R;
647                 return SENSOR_HV7131R;
648         }
649         PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
650                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
651                 gspca_dev->usb_buf[2]);
652         PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
653         return -ENODEV;
654 }
655
656 static int configure_gpio(struct gspca_dev *gspca_dev,
657                           const __u8 *sn9c1xx)
658 {
659         struct sd *sd = (struct sd *) gspca_dev;
660         const __u8 *reg9a;
661         static const __u8 reg9a_def[] =
662                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
663         static const __u8 reg9a_sn9c325[] =
664                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
665         static const __u8 regd4[] = {0x60, 0x00, 0x00};
666
667         reg_w1(gspca_dev, 0xf1, 0x00);
668         reg_w1(gspca_dev, 0x01, 0x00);          /*jfm was sn9c1xx[1] in v1*/
669
670         /* configure gpio */
671         reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
672         reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
673         reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
674         switch (sd->bridge) {
675         case BRIDGE_SN9C325:
676                 reg9a = reg9a_sn9c325;
677                 break;
678         default:
679                 reg9a = reg9a_def;
680                 break;
681         }
682         reg_w(gspca_dev, 0x9a, reg9a, 6);
683
684         reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
685
686         reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
687
688         switch (sd->bridge) {
689         case BRIDGE_SN9C325:
690                 reg_w1(gspca_dev, 0x01, 0x43);
691                 reg_w1(gspca_dev, 0x17, 0xae);
692                 reg_w1(gspca_dev, 0x01, 0x42);
693                 break;
694         default:
695                 reg_w1(gspca_dev, 0x01, 0x43);
696                 reg_w1(gspca_dev, 0x17, 0x61);
697                 reg_w1(gspca_dev, 0x01, 0x42);
698         }
699
700         if (sd->sensor == SENSOR_HV7131R) {
701                 if (probesensor(gspca_dev) < 0)
702                         return -ENODEV;
703         }
704         return 0;
705 }
706
707 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
708 {
709         int i = 0;
710         static const __u8 SetSensorClk[] =      /* 0x08 Mclk */
711                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
712
713         while (hv7131r_sensor_init[i][0]) {
714                 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
715                 i++;
716         }
717         i2c_w8(gspca_dev, SetSensorClk);
718 }
719
720 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
721 {
722         int i = 0;
723
724         while (mi0360_sensor_init[i][0]) {
725                 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
726                 i++;
727         }
728 }
729
730 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
731 {
732         int i = 0;
733
734         while (mo4000_sensor_init[i][0]) {
735                 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
736                 i++;
737         }
738 }
739
740 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
741 {
742         int i = 0;
743
744         while (ov7648_sensor_init[i][0]) {
745                 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
746                 i++;
747         }
748 }
749
750 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
751 {
752         int i = 0;
753
754         i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
755         i++;
756         msleep(20);
757         while (ov7660_sensor_init[i][0]) {
758                 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
759                 i++;
760         }
761 }
762
763 /* this function is called at probe time */
764 static int sd_config(struct gspca_dev *gspca_dev,
765                         const struct usb_device_id *id)
766 {
767         struct sd *sd = (struct sd *) gspca_dev;
768         struct cam *cam;
769
770         cam = &gspca_dev->cam;
771         cam->epaddr = 0x01;
772         cam->cam_mode = vga_mode;
773         cam->nmodes = ARRAY_SIZE(vga_mode);
774
775         sd->bridge = id->driver_info >> 16;
776         sd->sensor = id->driver_info >> 8;
777         sd->i2c_base = id->driver_info;
778
779         sd->qindex = 4;                 /* set the quantization table */
780         sd->brightness = BRIGHTNESS_DEF;
781         sd->contrast = CONTRAST_DEF;
782         sd->colors = COLOR_DEF;
783         sd->autogain = AUTOGAIN_DEF;
784         return 0;
785 }
786
787 /* this function is called at open time */
788 static int sd_open(struct gspca_dev *gspca_dev)
789 {
790         struct sd *sd = (struct sd *) gspca_dev;
791 /*      const __u8 *sn9c1xx; */
792         __u8 regGpio[] = { 0x29, 0x74 };
793         __u8 regF1;
794
795         /* setup a selector by bridge */
796         reg_w1(gspca_dev, 0xf1, 0x01);
797         reg_r(gspca_dev, 0x00, 1);
798         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
799         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
800         regF1 = gspca_dev->usb_buf[0];
801         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
802         switch (sd->bridge) {
803         case BRIDGE_SN9C102P:
804                 if (regF1 != 0x11)
805                         return -ENODEV;
806                 reg_w1(gspca_dev, 0x02, regGpio[1]);
807                 break;
808         case BRIDGE_SN9C105:
809                 if (regF1 != 0x11)
810                         return -ENODEV;
811                 reg_w(gspca_dev, 0x02, regGpio, 2);
812                 break;
813         case BRIDGE_SN9C120:
814                 if (regF1 != 0x12)
815                         return -ENODEV;
816                 regGpio[1] = 0x70;
817                 reg_w(gspca_dev, 0x02, regGpio, 2);
818                 break;
819         default:
820 /*      case BRIDGE_SN9C110: */
821 /*      case BRIDGE_SN9C325: */
822                 if (regF1 != 0x12)
823                         return -ENODEV;
824                 reg_w1(gspca_dev, 0x02, 0x62);
825                 break;
826         }
827
828         reg_w1(gspca_dev, 0xf1, 0x01);
829
830         return 0;
831 }
832
833 static unsigned int setexposure(struct gspca_dev *gspca_dev,
834                                 unsigned int expo)
835 {
836         struct sd *sd = (struct sd *) gspca_dev;
837         static const __u8 doit[] =              /* update sensor */
838                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
839         static const __u8 sensorgo[] =          /* sensor on */
840                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
841         static const __u8 gainMo[] =
842                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
843
844         switch (sd->sensor) {
845         case SENSOR_HV7131R: {
846                 __u8 Expodoit[] =
847                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
848
849                 Expodoit[3] = expo >> 16;
850                 Expodoit[4] = expo >> 8;
851                 Expodoit[5] = expo;
852                 i2c_w8(gspca_dev, Expodoit);
853                 break;
854             }
855         case SENSOR_MI0360: {
856                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
857                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
858
859                 if (expo > 0x0635)
860                         expo = 0x0635;
861                 else if (expo < 0x0001)
862                         expo = 0x0001;
863                 expoMi[3] = expo >> 8;
864                 expoMi[4] = expo;
865                 i2c_w8(gspca_dev, expoMi);
866                 i2c_w8(gspca_dev, doit);
867                 i2c_w8(gspca_dev, sensorgo);
868                 break;
869             }
870         case SENSOR_MO4000: {
871                 __u8 expoMof[] =
872                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
873                 __u8 expoMo10[] =
874                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
875
876                 if (expo > 0x1fff)
877                         expo = 0x1fff;
878                 else if (expo < 0x0001)
879                         expo = 0x0001;
880                 expoMof[3] = (expo & 0x03fc) >> 2;
881                 i2c_w8(gspca_dev, expoMof);
882                 expoMo10[3] = ((expo & 0x1c00) >> 10)
883                                 | ((expo & 0x0003) << 4);
884                 i2c_w8(gspca_dev, expoMo10);
885                 i2c_w8(gspca_dev, gainMo);
886                 PDEBUG(D_CONF, "set exposure %d",
887                         ((expoMo10[3] & 0x07) << 10)
888                         | (expoMof[3] << 2)
889                         | ((expoMo10[3] & 0x30) >> 4));
890                 break;
891             }
892         }
893         return expo;
894 }
895
896 static void setbrightness(struct gspca_dev *gspca_dev)
897 {
898         struct sd *sd = (struct sd *) gspca_dev;
899         unsigned int expo;
900         __u8 k2;
901
902         switch (sd->sensor) {
903         case SENSOR_HV7131R:
904                 expo = sd->brightness << 4;
905                 if (expo > 0x002dc6c0)
906                         expo = 0x002dc6c0;
907                 else if (expo < 0x02a0)
908                         expo = 0x02a0;
909                 sd->exposure = setexposure(gspca_dev, expo);
910                 break;
911         case SENSOR_MI0360:
912         case SENSOR_MO4000:
913                 expo = sd->brightness >> 4;
914                 sd->exposure = setexposure(gspca_dev, expo);
915                 break;
916         }
917
918         k2 = sd->brightness >> 10;
919         reg_w1(gspca_dev, 0x96, k2);
920 }
921
922 static void setcontrast(struct gspca_dev *gspca_dev)
923 {
924         struct sd *sd = (struct sd *) gspca_dev;
925         __u8 k2;
926         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
927
928         k2 = sd->contrast;
929         contrast[2] = k2;
930         contrast[0] = (k2 + 1) >> 1;
931         contrast[4] = (k2 + 1) / 5;
932         reg_w(gspca_dev, 0x84, contrast, 6);
933 }
934
935 static void setcolors(struct gspca_dev *gspca_dev)
936 {
937         struct sd *sd = (struct sd *) gspca_dev;
938         __u8 data;
939         int colour;
940
941         colour = sd->colors - 128;
942         if (colour > 0)
943                 data = (colour + 32) & 0x7f;    /* blue */
944         else
945                 data = (-colour + 32) & 0x7f;   /* red */
946         reg_w1(gspca_dev, 0x05, data);
947 }
948
949 /* -- start the camera -- */
950 static void sd_start(struct gspca_dev *gspca_dev)
951 {
952         struct sd *sd = (struct sd *) gspca_dev;
953         int i;
954         __u8 reg1, reg17, reg18;
955         const __u8 *sn9c1xx;
956         int mode;
957         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
958         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
959         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
960         static const __u8 CE_sn9c325[] =
961                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7648 - SN9C325 */
962
963         sn9c1xx = sn_tb[(int) sd->sensor];
964         configure_gpio(gspca_dev, sn9c1xx);
965
966 /*      reg_w1(gspca_dev, 0x01, 0x44);          jfm from win trace*/
967         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
968         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
969         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
970         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
971         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
972         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
973         reg_w1(gspca_dev, 0xd3, 0x50);
974         reg_w1(gspca_dev, 0xc6, 0x00);
975         reg_w1(gspca_dev, 0xc7, 0x00);
976         reg_w1(gspca_dev, 0xc8, 0x50);
977         reg_w1(gspca_dev, 0xc9, 0x3c);
978         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
979         switch (sd->bridge) {
980         case BRIDGE_SN9C325:
981                 reg17 = 0xae;
982                 break;
983         default:
984                 reg17 = 0x60;
985                 break;
986         }
987         reg_w1(gspca_dev, 0x17, reg17);
988         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
989         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
990         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
991         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
992         switch (sd->bridge) {
993         case BRIDGE_SN9C325:
994                 reg_w(gspca_dev, 0x20, regsn20_sn9c325,
995                                 sizeof regsn20_sn9c325);
996                 for (i = 0; i < 8; i++)
997                         reg_w(gspca_dev, 0x84, reg84_sn9c325,
998                                         sizeof reg84_sn9c325);
999                 reg_w1(gspca_dev, 0x9a, 0x0a);
1000                 reg_w1(gspca_dev, 0x99, 0x60);
1001                 break;
1002         default:
1003                 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1004                 for (i = 0; i < 8; i++)
1005                         reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1006                 reg_w1(gspca_dev, 0x9a, 0x08);
1007                 reg_w1(gspca_dev, 0x99, 0x59);
1008                 break;
1009         }
1010
1011         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1012         if (mode)
1013                 reg1 = 0x46;    /* 320 clk 48Mhz */
1014         else
1015                 reg1 = 0x06;    /* 640 clk 24Mz */
1016         reg17 = 0x61;
1017         switch (sd->sensor) {
1018         case SENSOR_HV7131R:
1019                 hv7131R_InitSensor(gspca_dev);
1020                 break;
1021         case SENSOR_MI0360:
1022                 mi0360_InitSensor(gspca_dev);
1023                 break;
1024         case SENSOR_MO4000:
1025                 mo4000_InitSensor(gspca_dev);
1026                 if (mode) {
1027 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1028                         reg1 = 0x06;    /* clk 24Mz */
1029                 } else {
1030                         reg17 = 0x22;   /* 640 MCKSIZE */
1031 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1032                 }
1033                 break;
1034         case SENSOR_OV7648:
1035                 ov7648_InitSensor(gspca_dev);
1036                 reg17 = 0xa2;
1037                 reg1 = 0x44;
1038 /*              if (mode)
1039                         ;                * 320x2...
1040                 else
1041                         ;                * 640x... */
1042                 break;
1043         default:
1044 /*      case SENSOR_OV7660: */
1045                 ov7660_InitSensor(gspca_dev);
1046                 if (mode) {
1047 /*                      reg17 = 0x21;    * 320 */
1048 /*                      reg1 = 0x44; */
1049 /*                      reg1 = 0x46;    (done) */
1050                 } else {
1051                         reg17 = 0x22;   /* 640 MCKSIZE */
1052                         reg1 = 0x06;
1053                 }
1054                 break;
1055         }
1056         reg_w(gspca_dev, 0xc0, C0, 6);
1057         reg_w(gspca_dev, 0xca, CA, 4);
1058         switch (sd->bridge) {
1059         case BRIDGE_SN9C325:
1060                 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1061                 break;
1062         default:
1063                 reg_w(gspca_dev, 0xce, CE, 4);
1064                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1065                 break;
1066         }
1067
1068         /* here change size mode 0 -> VGA; 1 -> CIF */
1069         reg18 = sn9c1xx[0x18] | (mode << 4);
1070         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1071
1072         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1073         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1074
1075         reg_w1(gspca_dev, 0x18, reg18);
1076
1077         reg_w1(gspca_dev, 0x17, reg17);
1078         reg_w1(gspca_dev, 0x01, reg1);
1079         setbrightness(gspca_dev);
1080         setcontrast(gspca_dev);
1081 }
1082
1083 static void sd_stopN(struct gspca_dev *gspca_dev)
1084 {
1085         struct sd *sd = (struct sd *) gspca_dev;
1086         static const __u8 stophv7131[] =
1087                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1088         static const __u8 stopmi0360[] =
1089                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1090         __u8 data;
1091         const __u8 *sn9c1xx;
1092
1093         data = 0x0b;
1094         switch (sd->sensor) {
1095         case SENSOR_HV7131R:
1096                 i2c_w8(gspca_dev, stophv7131);
1097                 data = 0x2b;
1098                 break;
1099         case SENSOR_MI0360:
1100                 i2c_w8(gspca_dev, stopmi0360);
1101                 data = 0x29;
1102                 break;
1103         case SENSOR_OV7648:
1104                 data = 0x29;
1105                 break;
1106         default:
1107 /*      case SENSOR_MO4000: */
1108 /*      case SENSOR_OV7660: */
1109                 break;
1110         }
1111         sn9c1xx = sn_tb[(int) sd->sensor];
1112         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1113         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1114         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1115         reg_w1(gspca_dev, 0x01, data);
1116         reg_w1(gspca_dev, 0xf1, 0x01);
1117 }
1118
1119 static void sd_stop0(struct gspca_dev *gspca_dev)
1120 {
1121 }
1122
1123 static void sd_close(struct gspca_dev *gspca_dev)
1124 {
1125 }
1126
1127 static void setautogain(struct gspca_dev *gspca_dev)
1128 {
1129         struct sd *sd = (struct sd *) gspca_dev;
1130         /* Thanks S., without your advice, autobright should not work :) */
1131         int delta;
1132         int expotimes = 0;
1133         __u8 luma_mean = 130;
1134         __u8 luma_delta = 20;
1135
1136         delta = sd->avg_lum;
1137         if (delta < luma_mean - luma_delta ||
1138             delta > luma_mean + luma_delta) {
1139                 switch (sd->sensor) {
1140                 case SENSOR_HV7131R:
1141                         expotimes = sd->exposure >> 8;
1142                         expotimes += (luma_mean - delta) >> 4;
1143                         if (expotimes < 0)
1144                                 expotimes = 0;
1145                         sd->exposure = setexposure(gspca_dev,
1146                                         (unsigned int) (expotimes << 8));
1147                         break;
1148                 case SENSOR_MO4000:
1149                 case SENSOR_MI0360:
1150                         expotimes = sd->exposure;
1151                         expotimes += (luma_mean - delta) >> 6;
1152                         if (expotimes < 0)
1153                                 expotimes = 0;
1154                         sd->exposure = setexposure(gspca_dev,
1155                                                    (unsigned int) expotimes);
1156                         setcolors(gspca_dev);
1157                         break;
1158                 }
1159         }
1160 }
1161
1162 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1163                         struct gspca_frame *frame,      /* target */
1164                         __u8 *data,                     /* isoc packet */
1165                         int len)                        /* iso packet length */
1166 {
1167         struct sd *sd = (struct sd *) gspca_dev;
1168         int sof, avg_lum;
1169
1170         sof = len - 64;
1171         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1172
1173                 /* end of frame */
1174                 gspca_frame_add(gspca_dev, LAST_PACKET,
1175                                 frame, data, sof + 2);
1176                 if (sd->ag_cnt < 0)
1177                         return;
1178                 if (--sd->ag_cnt >= 0)
1179                         return;
1180                 sd->ag_cnt = AG_CNT_START;
1181 /* w1 w2 w3 */
1182 /* w4 w5 w6 */
1183 /* w7 w8 */
1184 /* w4 */
1185                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1186 /* w6 */
1187                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1188 /* w2 */
1189                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1190 /* w8 */
1191                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1192 /* w5 */
1193                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1194                 avg_lum >>= 4;
1195                 sd->avg_lum = avg_lum;
1196                 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1197                 setautogain(gspca_dev);
1198                 return;
1199         }
1200         if (gspca_dev->last_packet_type == LAST_PACKET) {
1201
1202                 /* put the JPEG 422 header */
1203                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1204         }
1205         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1206 }
1207
1208 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1209 {
1210         struct sd *sd = (struct sd *) gspca_dev;
1211         __u8 hexpo, mexpo, lexpo;
1212
1213         switch (sd->sensor) {
1214         case SENSOR_HV7131R:
1215                 /* read sensor exposure */
1216                 i2c_r5(gspca_dev, 0x25);
1217                 return (gspca_dev->usb_buf[0] << 16)
1218                         | (gspca_dev->usb_buf[1] << 8)
1219                         | gspca_dev->usb_buf[2];
1220         case SENSOR_MI0360:
1221                 /* read sensor exposure */
1222                 i2c_r5(gspca_dev, 0x09);
1223                 return (gspca_dev->usb_buf[0] << 8)
1224                         | gspca_dev->usb_buf[1];
1225         case SENSOR_MO4000:
1226                 i2c_r5(gspca_dev, 0x0e);
1227                 hexpo = 0;              /* gspca_dev->usb_buf[1] & 0x07; */
1228                 mexpo = 0x40;           /* gspca_dev->usb_buf[2] & 0xff; */
1229                 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1230                 PDEBUG(D_CONF, "exposure %d",
1231                         (hexpo << 10) | (mexpo << 2) | lexpo);
1232                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1233         default:
1234 /*      case SENSOR_OV7648:             * jfm: is it ok for 7648? */
1235 /*      case SENSOR_OV7660: */
1236                 /* read sensor exposure */
1237                 i2c_r5(gspca_dev, 0x04);
1238                 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1239                 lexpo = gspca_dev->usb_buf[0] & 0x02;
1240                 i2c_r5(gspca_dev, 0x08);
1241                 mexpo = gspca_dev->usb_buf[2];
1242                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1243         }
1244 }
1245
1246 static void getbrightness(struct gspca_dev *gspca_dev)
1247 {
1248         struct sd *sd = (struct sd *) gspca_dev;
1249
1250         /* hardcoded registers seem not readable */
1251         switch (sd->sensor) {
1252         case SENSOR_HV7131R:
1253                 sd->brightness = getexposure(gspca_dev) >> 4;
1254                 break;
1255         case SENSOR_MI0360:
1256                 sd->brightness = getexposure(gspca_dev) << 4;
1257                 break;
1258         case SENSOR_MO4000:
1259                 sd->brightness = getexposure(gspca_dev) << 4;
1260                 break;
1261         }
1262 }
1263
1264 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1265 {
1266         struct sd *sd = (struct sd *) gspca_dev;
1267
1268         sd->brightness = val;
1269         if (gspca_dev->streaming)
1270                 setbrightness(gspca_dev);
1271         return 0;
1272 }
1273
1274 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1275 {
1276         struct sd *sd = (struct sd *) gspca_dev;
1277
1278         getbrightness(gspca_dev);
1279         *val = sd->brightness;
1280         return 0;
1281 }
1282
1283 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1284 {
1285         struct sd *sd = (struct sd *) gspca_dev;
1286
1287         sd->contrast = val;
1288         if (gspca_dev->streaming)
1289                 setcontrast(gspca_dev);
1290         return 0;
1291 }
1292
1293 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1294 {
1295         struct sd *sd = (struct sd *) gspca_dev;
1296
1297         *val = sd->contrast;
1298         return 0;
1299 }
1300
1301 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1302 {
1303         struct sd *sd = (struct sd *) gspca_dev;
1304
1305         sd->colors = val;
1306         if (gspca_dev->streaming)
1307                 setcolors(gspca_dev);
1308         return 0;
1309 }
1310
1311 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1312 {
1313         struct sd *sd = (struct sd *) gspca_dev;
1314
1315         *val = sd->colors;
1316         return 0;
1317 }
1318
1319 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1320 {
1321         struct sd *sd = (struct sd *) gspca_dev;
1322
1323         sd->autogain = val;
1324         if (val)
1325                 sd->ag_cnt = AG_CNT_START;
1326         else
1327                 sd->ag_cnt = -1;
1328         return 0;
1329 }
1330
1331 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1332 {
1333         struct sd *sd = (struct sd *) gspca_dev;
1334
1335         *val = sd->autogain;
1336         return 0;
1337 }
1338
1339 /* sub-driver description */
1340 static const struct sd_desc sd_desc = {
1341         .name = MODULE_NAME,
1342         .ctrls = sd_ctrls,
1343         .nctrls = ARRAY_SIZE(sd_ctrls),
1344         .config = sd_config,
1345         .open = sd_open,
1346         .start = sd_start,
1347         .stopN = sd_stopN,
1348         .stop0 = sd_stop0,
1349         .close = sd_close,
1350         .pkt_scan = sd_pkt_scan,
1351 };
1352
1353 /* -- module initialisation -- */
1354 #define BSI(bridge, sensor, i2c_addr) \
1355         .driver_info = (BRIDGE_ ## bridge << 16) \
1356                         | (SENSOR_ ## sensor << 8) \
1357                         | (i2c_addr)
1358 static const __devinitdata struct usb_device_id device_table[] = {
1359 #ifndef CONFIG_USB_SN9C102
1360         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1361         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1362         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1363         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1364         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1365 #endif
1366         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1367         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1368 /* bw600.inf:
1369         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1370 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1371 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1372         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1373 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1374         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1375 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1376 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1377         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1378 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1379 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1380         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1381         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1382 /*      {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1383 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1384 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1385 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1386         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)},
1387 /* bw600.inf:
1388         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */
1389         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1390 /*      {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */
1391 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1392 #ifndef CONFIG_USB_SN9C102
1393         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1394         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1395 /*      {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1396         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1397         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1398 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1399 #endif
1400         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1401         {}
1402 };
1403 MODULE_DEVICE_TABLE(usb, device_table);
1404
1405 /* -- device connect -- */
1406 static int sd_probe(struct usb_interface *intf,
1407                     const struct usb_device_id *id)
1408 {
1409         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1410                                 THIS_MODULE);
1411 }
1412
1413 static struct usb_driver sd_driver = {
1414         .name = MODULE_NAME,
1415         .id_table = device_table,
1416         .probe = sd_probe,
1417         .disconnect = gspca_disconnect,
1418 };
1419
1420 /* -- module insert / remove -- */
1421 static int __init sd_mod_init(void)
1422 {
1423         if (usb_register(&sd_driver) < 0)
1424                 return -1;
1425         info("registered");
1426         return 0;
1427 }
1428 static void __exit sd_mod_exit(void)
1429 {
1430         usb_deregister(&sd_driver);
1431         info("deregistered");
1432 }
1433
1434 module_init(sd_mod_init);
1435 module_exit(sd_mod_exit);