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