]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixj.c
Merge branch 'linus' into sched/clock
[linux-2.6-omap-h63xx.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         atomic_t 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         sd->ag_cnt = -1;
785
786         return 0;
787 }
788
789 /* this function is called at open time */
790 static int sd_open(struct gspca_dev *gspca_dev)
791 {
792         struct sd *sd = (struct sd *) gspca_dev;
793 /*      const __u8 *sn9c1xx; */
794         __u8 regGpio[] = { 0x29, 0x74 };
795         __u8 regF1;
796
797         /* setup a selector by bridge */
798         reg_w1(gspca_dev, 0xf1, 0x01);
799         reg_r(gspca_dev, 0x00, 1);
800         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
801         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
802         regF1 = gspca_dev->usb_buf[0];
803         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
804         switch (sd->bridge) {
805         case BRIDGE_SN9C102P:
806                 if (regF1 != 0x11)
807                         return -ENODEV;
808                 reg_w1(gspca_dev, 0x02, regGpio[1]);
809                 break;
810         case BRIDGE_SN9C105:
811                 if (regF1 != 0x11)
812                         return -ENODEV;
813                 reg_w(gspca_dev, 0x02, regGpio, 2);
814                 break;
815         case BRIDGE_SN9C120:
816                 if (regF1 != 0x12)
817                         return -ENODEV;
818                 regGpio[1] = 0x70;
819                 reg_w(gspca_dev, 0x02, regGpio, 2);
820                 break;
821         default:
822 /*      case BRIDGE_SN9C110: */
823 /*      case BRIDGE_SN9C325: */
824                 if (regF1 != 0x12)
825                         return -ENODEV;
826                 reg_w1(gspca_dev, 0x02, 0x62);
827                 break;
828         }
829
830         reg_w1(gspca_dev, 0xf1, 0x01);
831
832         return 0;
833 }
834
835 static unsigned int setexposure(struct gspca_dev *gspca_dev,
836                                 unsigned int expo)
837 {
838         struct sd *sd = (struct sd *) gspca_dev;
839         static const __u8 doit[] =              /* update sensor */
840                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
841         static const __u8 sensorgo[] =          /* sensor on */
842                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
843         static const __u8 gainMo[] =
844                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
845
846         switch (sd->sensor) {
847         case SENSOR_HV7131R: {
848                 __u8 Expodoit[] =
849                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
850
851                 Expodoit[3] = expo >> 16;
852                 Expodoit[4] = expo >> 8;
853                 Expodoit[5] = expo;
854                 i2c_w8(gspca_dev, Expodoit);
855                 break;
856             }
857         case SENSOR_MI0360: {
858                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
859                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
860
861                 if (expo > 0x0635)
862                         expo = 0x0635;
863                 else if (expo < 0x0001)
864                         expo = 0x0001;
865                 expoMi[3] = expo >> 8;
866                 expoMi[4] = expo;
867                 i2c_w8(gspca_dev, expoMi);
868                 i2c_w8(gspca_dev, doit);
869                 i2c_w8(gspca_dev, sensorgo);
870                 break;
871             }
872         case SENSOR_MO4000: {
873                 __u8 expoMof[] =
874                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
875                 __u8 expoMo10[] =
876                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
877
878                 if (expo > 0x1fff)
879                         expo = 0x1fff;
880                 else if (expo < 0x0001)
881                         expo = 0x0001;
882                 expoMof[3] = (expo & 0x03fc) >> 2;
883                 i2c_w8(gspca_dev, expoMof);
884                 expoMo10[3] = ((expo & 0x1c00) >> 10)
885                                 | ((expo & 0x0003) << 4);
886                 i2c_w8(gspca_dev, expoMo10);
887                 i2c_w8(gspca_dev, gainMo);
888                 PDEBUG(D_CONF, "set exposure %d",
889                         ((expoMo10[3] & 0x07) << 10)
890                         | (expoMof[3] << 2)
891                         | ((expoMo10[3] & 0x30) >> 4));
892                 break;
893             }
894         }
895         return expo;
896 }
897
898 static void setbrightness(struct gspca_dev *gspca_dev)
899 {
900         struct sd *sd = (struct sd *) gspca_dev;
901         unsigned int expo;
902         __u8 k2;
903
904         switch (sd->sensor) {
905         case SENSOR_HV7131R:
906                 expo = sd->brightness << 4;
907                 if (expo > 0x002dc6c0)
908                         expo = 0x002dc6c0;
909                 else if (expo < 0x02a0)
910                         expo = 0x02a0;
911                 sd->exposure = setexposure(gspca_dev, expo);
912                 break;
913         case SENSOR_MI0360:
914         case SENSOR_MO4000:
915                 expo = sd->brightness >> 4;
916                 sd->exposure = setexposure(gspca_dev, expo);
917                 break;
918         }
919
920         k2 = sd->brightness >> 10;
921         reg_w1(gspca_dev, 0x96, k2);
922 }
923
924 static void setcontrast(struct gspca_dev *gspca_dev)
925 {
926         struct sd *sd = (struct sd *) gspca_dev;
927         __u8 k2;
928         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
929
930         k2 = sd->contrast;
931         contrast[2] = k2;
932         contrast[0] = (k2 + 1) >> 1;
933         contrast[4] = (k2 + 1) / 5;
934         reg_w(gspca_dev, 0x84, contrast, 6);
935 }
936
937 static void setcolors(struct gspca_dev *gspca_dev)
938 {
939         struct sd *sd = (struct sd *) gspca_dev;
940         __u8 data;
941         int colour;
942
943         colour = sd->colors - 128;
944         if (colour > 0)
945                 data = (colour + 32) & 0x7f;    /* blue */
946         else
947                 data = (-colour + 32) & 0x7f;   /* red */
948         reg_w1(gspca_dev, 0x05, data);
949 }
950
951 static void setautogain(struct gspca_dev *gspca_dev)
952 {
953         struct sd *sd = (struct sd *) gspca_dev;
954
955         switch (sd->sensor) {
956         case SENSOR_HV7131R:
957         case SENSOR_MO4000:
958         case SENSOR_MI0360:
959                 if (sd->autogain)
960                         sd->ag_cnt = AG_CNT_START;
961                 else
962                         sd->ag_cnt = -1;
963                 break;
964         }
965 }
966
967 /* -- start the camera -- */
968 static void sd_start(struct gspca_dev *gspca_dev)
969 {
970         struct sd *sd = (struct sd *) gspca_dev;
971         int i;
972         __u8 reg1, reg17, reg18;
973         const __u8 *sn9c1xx;
974         int mode;
975         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
976         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
977         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
978         static const __u8 CE_sn9c325[] =
979                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7648 - SN9C325 */
980
981         sn9c1xx = sn_tb[(int) sd->sensor];
982         configure_gpio(gspca_dev, sn9c1xx);
983
984 /*      reg_w1(gspca_dev, 0x01, 0x44);          jfm from win trace*/
985         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
986         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
987         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
988         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
989         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
990         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
991         reg_w1(gspca_dev, 0xd3, 0x50);
992         reg_w1(gspca_dev, 0xc6, 0x00);
993         reg_w1(gspca_dev, 0xc7, 0x00);
994         reg_w1(gspca_dev, 0xc8, 0x50);
995         reg_w1(gspca_dev, 0xc9, 0x3c);
996         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
997         switch (sd->bridge) {
998         case BRIDGE_SN9C325:
999                 reg17 = 0xae;
1000                 break;
1001         default:
1002                 reg17 = 0x60;
1003                 break;
1004         }
1005         reg_w1(gspca_dev, 0x17, reg17);
1006         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1007         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1008         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1009         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1010         switch (sd->bridge) {
1011         case BRIDGE_SN9C325:
1012                 reg_w(gspca_dev, 0x20, regsn20_sn9c325,
1013                                 sizeof regsn20_sn9c325);
1014                 for (i = 0; i < 8; i++)
1015                         reg_w(gspca_dev, 0x84, reg84_sn9c325,
1016                                         sizeof reg84_sn9c325);
1017                 reg_w1(gspca_dev, 0x9a, 0x0a);
1018                 reg_w1(gspca_dev, 0x99, 0x60);
1019                 break;
1020         default:
1021                 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1022                 for (i = 0; i < 8; i++)
1023                         reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1024                 reg_w1(gspca_dev, 0x9a, 0x08);
1025                 reg_w1(gspca_dev, 0x99, 0x59);
1026                 break;
1027         }
1028
1029         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1030         if (mode)
1031                 reg1 = 0x46;    /* 320 clk 48Mhz */
1032         else
1033                 reg1 = 0x06;    /* 640 clk 24Mz */
1034         reg17 = 0x61;
1035         switch (sd->sensor) {
1036         case SENSOR_HV7131R:
1037                 hv7131R_InitSensor(gspca_dev);
1038                 break;
1039         case SENSOR_MI0360:
1040                 mi0360_InitSensor(gspca_dev);
1041                 break;
1042         case SENSOR_MO4000:
1043                 mo4000_InitSensor(gspca_dev);
1044                 if (mode) {
1045 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1046                         reg1 = 0x06;    /* clk 24Mz */
1047                 } else {
1048                         reg17 = 0x22;   /* 640 MCKSIZE */
1049 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1050                 }
1051                 break;
1052         case SENSOR_OV7648:
1053                 ov7648_InitSensor(gspca_dev);
1054                 reg17 = 0xa2;
1055                 reg1 = 0x44;
1056 /*              if (mode)
1057                         ;                * 320x2...
1058                 else
1059                         ;                * 640x... */
1060                 break;
1061         default:
1062 /*      case SENSOR_OV7660: */
1063                 ov7660_InitSensor(gspca_dev);
1064                 if (mode) {
1065 /*                      reg17 = 0x21;    * 320 */
1066 /*                      reg1 = 0x44; */
1067 /*                      reg1 = 0x46;    (done) */
1068                 } else {
1069                         reg17 = 0x22;   /* 640 MCKSIZE */
1070                         reg1 = 0x06;
1071                 }
1072                 break;
1073         }
1074         reg_w(gspca_dev, 0xc0, C0, 6);
1075         reg_w(gspca_dev, 0xca, CA, 4);
1076         switch (sd->bridge) {
1077         case BRIDGE_SN9C325:
1078                 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1079                 break;
1080         default:
1081                 reg_w(gspca_dev, 0xce, CE, 4);
1082                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1083                 break;
1084         }
1085
1086         /* here change size mode 0 -> VGA; 1 -> CIF */
1087         reg18 = sn9c1xx[0x18] | (mode << 4);
1088         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1089
1090         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1091         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1092
1093         reg_w1(gspca_dev, 0x18, reg18);
1094
1095         reg_w1(gspca_dev, 0x17, reg17);
1096         reg_w1(gspca_dev, 0x01, reg1);
1097         setbrightness(gspca_dev);
1098         setcontrast(gspca_dev);
1099         setautogain(gspca_dev);
1100 }
1101
1102 static void sd_stopN(struct gspca_dev *gspca_dev)
1103 {
1104         struct sd *sd = (struct sd *) gspca_dev;
1105         static const __u8 stophv7131[] =
1106                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1107         static const __u8 stopmi0360[] =
1108                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1109         __u8 data;
1110         const __u8 *sn9c1xx;
1111
1112         data = 0x0b;
1113         switch (sd->sensor) {
1114         case SENSOR_HV7131R:
1115                 i2c_w8(gspca_dev, stophv7131);
1116                 data = 0x2b;
1117                 break;
1118         case SENSOR_MI0360:
1119                 i2c_w8(gspca_dev, stopmi0360);
1120                 data = 0x29;
1121                 break;
1122         case SENSOR_OV7648:
1123                 data = 0x29;
1124                 break;
1125         default:
1126 /*      case SENSOR_MO4000: */
1127 /*      case SENSOR_OV7660: */
1128                 break;
1129         }
1130         sn9c1xx = sn_tb[(int) sd->sensor];
1131         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1132         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1133         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1134         reg_w1(gspca_dev, 0x01, data);
1135         reg_w1(gspca_dev, 0xf1, 0x01);
1136 }
1137
1138 static void sd_stop0(struct gspca_dev *gspca_dev)
1139 {
1140 }
1141
1142 static void sd_close(struct gspca_dev *gspca_dev)
1143 {
1144 }
1145
1146 static void do_autogain(struct gspca_dev *gspca_dev)
1147 {
1148         struct sd *sd = (struct sd *) gspca_dev;
1149         int delta;
1150         int expotimes;
1151         __u8 luma_mean = 130;
1152         __u8 luma_delta = 20;
1153
1154         /* Thanks S., without your advice, autobright should not work :) */
1155         if (sd->ag_cnt < 0)
1156                 return;
1157         if (--sd->ag_cnt >= 0)
1158                 return;
1159         sd->ag_cnt = AG_CNT_START;
1160
1161         delta = atomic_read(&sd->avg_lum);
1162         PDEBUG(D_FRAM, "mean lum %d", delta);
1163         if (delta < luma_mean - luma_delta ||
1164             delta > luma_mean + luma_delta) {
1165                 switch (sd->sensor) {
1166                 case SENSOR_HV7131R:
1167                         expotimes = sd->exposure >> 8;
1168                         expotimes += (luma_mean - delta) >> 4;
1169                         if (expotimes < 0)
1170                                 expotimes = 0;
1171                         sd->exposure = setexposure(gspca_dev,
1172                                         (unsigned int) (expotimes << 8));
1173                         break;
1174                 default:
1175 /*              case SENSOR_MO4000: */
1176 /*              case SENSOR_MI0360: */
1177                         expotimes = sd->exposure;
1178                         expotimes += (luma_mean - delta) >> 6;
1179                         if (expotimes < 0)
1180                                 expotimes = 0;
1181                         sd->exposure = setexposure(gspca_dev,
1182                                                    (unsigned int) expotimes);
1183                         setcolors(gspca_dev);
1184                         break;
1185                 }
1186         }
1187 }
1188
1189 /* scan the URB packets */
1190 /* This function is run at interrupt level. */
1191 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1192                         struct gspca_frame *frame,      /* target */
1193                         __u8 *data,                     /* isoc packet */
1194                         int len)                        /* iso packet length */
1195 {
1196         struct sd *sd = (struct sd *) gspca_dev;
1197         int sof, avg_lum;
1198
1199         sof = len - 64;
1200         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1201
1202                 /* end of frame */
1203                 gspca_frame_add(gspca_dev, LAST_PACKET,
1204                                 frame, data, sof + 2);
1205                 if (sd->ag_cnt < 0)
1206                         return;
1207 /* w1 w2 w3 */
1208 /* w4 w5 w6 */
1209 /* w7 w8 */
1210 /* w4 */
1211                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1212 /* w6 */
1213                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1214 /* w2 */
1215                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1216 /* w8 */
1217                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1218 /* w5 */
1219                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1220                 avg_lum >>= 4;
1221                 atomic_set(&sd->avg_lum, avg_lum);
1222                 return;
1223         }
1224         if (gspca_dev->last_packet_type == LAST_PACKET) {
1225
1226                 /* put the JPEG 422 header */
1227                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1228         }
1229         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1230 }
1231
1232 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1233 {
1234         struct sd *sd = (struct sd *) gspca_dev;
1235         __u8 hexpo, mexpo, lexpo;
1236
1237         switch (sd->sensor) {
1238         case SENSOR_HV7131R:
1239                 /* read sensor exposure */
1240                 i2c_r5(gspca_dev, 0x25);
1241                 return (gspca_dev->usb_buf[0] << 16)
1242                         | (gspca_dev->usb_buf[1] << 8)
1243                         | gspca_dev->usb_buf[2];
1244         case SENSOR_MI0360:
1245                 /* read sensor exposure */
1246                 i2c_r5(gspca_dev, 0x09);
1247                 return (gspca_dev->usb_buf[0] << 8)
1248                         | gspca_dev->usb_buf[1];
1249         case SENSOR_MO4000:
1250                 i2c_r5(gspca_dev, 0x0e);
1251                 hexpo = 0;              /* gspca_dev->usb_buf[1] & 0x07; */
1252                 mexpo = 0x40;           /* gspca_dev->usb_buf[2] & 0xff; */
1253                 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1254                 PDEBUG(D_CONF, "exposure %d",
1255                         (hexpo << 10) | (mexpo << 2) | lexpo);
1256                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1257         default:
1258 /*      case SENSOR_OV7648:             * jfm: is it ok for 7648? */
1259 /*      case SENSOR_OV7660: */
1260                 /* read sensor exposure */
1261                 i2c_r5(gspca_dev, 0x04);
1262                 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1263                 lexpo = gspca_dev->usb_buf[0] & 0x02;
1264                 i2c_r5(gspca_dev, 0x08);
1265                 mexpo = gspca_dev->usb_buf[2];
1266                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1267         }
1268 }
1269
1270 static void getbrightness(struct gspca_dev *gspca_dev)
1271 {
1272         struct sd *sd = (struct sd *) gspca_dev;
1273
1274         /* hardcoded registers seem not readable */
1275         switch (sd->sensor) {
1276         case SENSOR_HV7131R:
1277                 sd->brightness = getexposure(gspca_dev) >> 4;
1278                 break;
1279         case SENSOR_MI0360:
1280                 sd->brightness = getexposure(gspca_dev) << 4;
1281                 break;
1282         case SENSOR_MO4000:
1283                 sd->brightness = getexposure(gspca_dev) << 4;
1284                 break;
1285         }
1286 }
1287
1288 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1289 {
1290         struct sd *sd = (struct sd *) gspca_dev;
1291
1292         sd->brightness = val;
1293         if (gspca_dev->streaming)
1294                 setbrightness(gspca_dev);
1295         return 0;
1296 }
1297
1298 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1299 {
1300         struct sd *sd = (struct sd *) gspca_dev;
1301
1302         getbrightness(gspca_dev);
1303         *val = sd->brightness;
1304         return 0;
1305 }
1306
1307 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1308 {
1309         struct sd *sd = (struct sd *) gspca_dev;
1310
1311         sd->contrast = val;
1312         if (gspca_dev->streaming)
1313                 setcontrast(gspca_dev);
1314         return 0;
1315 }
1316
1317 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1318 {
1319         struct sd *sd = (struct sd *) gspca_dev;
1320
1321         *val = sd->contrast;
1322         return 0;
1323 }
1324
1325 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1326 {
1327         struct sd *sd = (struct sd *) gspca_dev;
1328
1329         sd->colors = val;
1330         if (gspca_dev->streaming)
1331                 setcolors(gspca_dev);
1332         return 0;
1333 }
1334
1335 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1336 {
1337         struct sd *sd = (struct sd *) gspca_dev;
1338
1339         *val = sd->colors;
1340         return 0;
1341 }
1342
1343 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1344 {
1345         struct sd *sd = (struct sd *) gspca_dev;
1346
1347         sd->autogain = val;
1348         if (gspca_dev->streaming)
1349                 setautogain(gspca_dev);
1350         return 0;
1351 }
1352
1353 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1354 {
1355         struct sd *sd = (struct sd *) gspca_dev;
1356
1357         *val = sd->autogain;
1358         return 0;
1359 }
1360
1361 /* sub-driver description */
1362 static const struct sd_desc sd_desc = {
1363         .name = MODULE_NAME,
1364         .ctrls = sd_ctrls,
1365         .nctrls = ARRAY_SIZE(sd_ctrls),
1366         .config = sd_config,
1367         .open = sd_open,
1368         .start = sd_start,
1369         .stopN = sd_stopN,
1370         .stop0 = sd_stop0,
1371         .close = sd_close,
1372         .pkt_scan = sd_pkt_scan,
1373         .dq_callback = do_autogain,
1374 };
1375
1376 /* -- module initialisation -- */
1377 #define BSI(bridge, sensor, i2c_addr) \
1378         .driver_info = (BRIDGE_ ## bridge << 16) \
1379                         | (SENSOR_ ## sensor << 8) \
1380                         | (i2c_addr)
1381 static const __devinitdata struct usb_device_id device_table[] = {
1382 #ifndef CONFIG_USB_SN9C102
1383         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1384         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1385         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1386         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1387         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1388 #endif
1389         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1390         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1391 /* bw600.inf:
1392         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1393 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1394 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1395         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1396 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1397         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1398 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1399 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1400         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1401 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1402 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1403         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1404         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1405 /*      {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1406 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1407 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1408 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1409         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)},
1410 /* bw600.inf:
1411         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */
1412         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1413 /*      {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */
1414 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1415 #ifndef CONFIG_USB_SN9C102
1416         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1417         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1418 /*      {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1419         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1420         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1421 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1422 #endif
1423         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1424         {}
1425 };
1426 MODULE_DEVICE_TABLE(usb, device_table);
1427
1428 /* -- device connect -- */
1429 static int sd_probe(struct usb_interface *intf,
1430                     const struct usb_device_id *id)
1431 {
1432         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1433                                 THIS_MODULE);
1434 }
1435
1436 static struct usb_driver sd_driver = {
1437         .name = MODULE_NAME,
1438         .id_table = device_table,
1439         .probe = sd_probe,
1440         .disconnect = gspca_disconnect,
1441 };
1442
1443 /* -- module insert / remove -- */
1444 static int __init sd_mod_init(void)
1445 {
1446         if (usb_register(&sd_driver) < 0)
1447                 return -1;
1448         info("registered");
1449         return 0;
1450 }
1451 static void __exit sd_mod_exit(void)
1452 {
1453         usb_deregister(&sd_driver);
1454         info("deregistered");
1455 }
1456
1457 module_init(sd_mod_init);
1458 module_exit(sd_mod_exit);