V4L/DVB (8193): gspca: Input buffer may be changed on reg write.
[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, 3)
28 static const char version[] = "2.1.3";
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 #define SD_BRIGHTNESS 0
78         {
79             {
80                 .id      = V4L2_CID_BRIGHTNESS,
81                 .type    = V4L2_CTRL_TYPE_INTEGER,
82                 .name    = "Brightness",
83                 .minimum = 0,
84                 .maximum = 0xffff,
85                 .step    = 1,
86                 .default_value = 0x7fff,
87             },
88             .set = sd_setbrightness,
89             .get = sd_getbrightness,
90         },
91 #define SD_CONTRAST 1
92         {
93             {
94                 .id      = V4L2_CID_CONTRAST,
95                 .type    = V4L2_CTRL_TYPE_INTEGER,
96                 .name    = "Contrast",
97                 .minimum = 0,
98                 .maximum = 127,
99                 .step    = 1,
100                 .default_value = 63,
101             },
102             .set = sd_setcontrast,
103             .get = sd_getcontrast,
104         },
105 #define SD_COLOR 2
106         {
107             {
108                 .id      = V4L2_CID_SATURATION,
109                 .type    = V4L2_CTRL_TYPE_INTEGER,
110                 .name    = "Color",
111                 .minimum = 0,
112                 .maximum = 255,
113                 .step    = 1,
114                 .default_value = 127,
115             },
116             .set = sd_setcolors,
117             .get = sd_getcolors,
118         },
119 #define SD_AUTOGAIN 3
120         {
121             {
122                 .id      = V4L2_CID_AUTOGAIN,
123                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
124                 .name    = "Auto Gain",
125                 .minimum = 0,
126                 .maximum = 1,
127                 .step    = 1,
128                 .default_value = 1,
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 __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 __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 __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 __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 __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 __u8 *sn_tb[] = {
196         sn_hv7131,
197         sn_mi0360,
198         sn_mo4000,
199         sn_ov7648,
200         sn_ov7660
201 };
202
203 static __u8 regsn20[] = {
204         0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
205         0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
206 };
207 static __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 __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 __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 __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         {0, 0, 0, 0, 0, 0, 0, 0}
254 };
255 static __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         {0, 0, 0, 0, 0, 0, 0, 0}
308 };
309 static __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         {0, 0, 0, 0, 0, 0, 0, 0}
331 };
332 static __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         {0, 0, 0, 0, 0, 0, 0, 0}
424 };
425 /* reg0x04              reg0x07         reg 0x10 */
426 /* expo  = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
427
428 static __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         {0, 0, 0, 0, 0, 0, 0, 0}
482 };
483
484 static __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         __u8 tmpbuf[64];
522
523 #ifdef CONFIG_VIDEO_ADV_DEBUG
524         if (len > sizeof tmpbuf) {
525                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
526                 return;
527         }
528 #endif
529         memcpy(tmpbuf, buffer, len);
530         usb_control_msg(dev,
531                         usb_sndctrlpipe(dev, 0),
532                         0x08,
533                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
534                         value, 0,
535                         tmpbuf, len,
536                         500);
537 }
538
539 /* write 2 bytes */
540 static void i2c_w2(struct gspca_dev *gspca_dev,
541                    __u8 *buffer)
542 {
543         struct sd *sd = (struct sd *) gspca_dev;
544         struct usb_device *dev = gspca_dev->dev;
545         __u8 mode[8];
546
547         /* is i2c ready */
548         mode[0] = sd->i2c_ctrl_reg | (2 << 4);
549         mode[1] = sd->i2c_base;
550         mode[2] = buffer[0];
551         mode[3] = buffer[1];
552         mode[4] = 0;
553         mode[5] = 0;
554         mode[6] = 0;
555         mode[7] = 0x10;
556         reg_w(dev, 0x08, mode, 8);
557 }
558
559 /* write 8 bytes */
560 static void i2c_w8(struct usb_device *dev, __u8 *buffer)
561 {
562         reg_w(dev, 0x08, buffer, 8);
563         msleep(1);
564 }
565
566 /* read 5 bytes */
567 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg,
568                              __u8 *buffer)
569 {
570         struct sd *sd = (struct sd *) gspca_dev;
571         struct usb_device *dev = gspca_dev->dev;
572         __u8 mode[8];
573
574         mode[0] = sd->i2c_ctrl_reg | 0x10;
575         mode[1] = sd->i2c_base;
576         mode[2] = reg;
577         mode[3] = 0;
578         mode[4] = 0;
579         mode[5] = 0;
580         mode[6] = 0;
581         mode[7] = 0x10;
582         i2c_w8(dev, mode);
583         mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02;
584         mode[2] = 0;
585         i2c_w8(dev, mode);
586         reg_r(dev, 0x0a, buffer, 5);
587 }
588
589 static int probesensor(struct gspca_dev *gspca_dev)
590 {
591         struct sd *sd = (struct sd *) gspca_dev;
592         struct usb_device *dev = gspca_dev->dev;
593         __u8 reg02;
594         static __u8 datasend[] = { 2, 0 };
595         /* reg val1 val2 val3 val4 */
596         __u8 datarecd[6];
597
598         i2c_w2(gspca_dev, datasend);
599 /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
600         msleep(10);
601         reg02 = 0x66;
602         reg_w(dev, 0x02, &reg02, 1);            /* Gpio on */
603         msleep(10);
604         i2c_r5(gspca_dev, 0, datarecd);         /* read sensor id */
605         if (datarecd[0] == 0x02
606             && datarecd[1] == 0x09
607             && datarecd[2] == 0x01
608             && datarecd[3] == 0x00
609             && datarecd[4] == 0x00) {
610                 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
611                 sd->sensor = SENSOR_HV7131R;
612                 return SENSOR_HV7131R;
613         }
614         PDEBUG(D_PROBE, "Find Sensor %d %d %d",
615                 datarecd[0], datarecd[1], datarecd[2]);
616         PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
617         return -ENODEV;
618 }
619
620 static int configure_gpio(struct gspca_dev *gspca_dev,
621                           __u8 *sn9c1xx)
622 {
623         struct sd *sd = (struct sd *) gspca_dev;
624         struct usb_device *dev = gspca_dev->dev;
625         __u8 data;
626         __u8 regF1;
627         __u8 *reg9a;
628         static __u8 reg9a_def[] =
629                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
630         static __u8 reg9a_sn9c120[] =                   /* from win trace */
631                 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
632         static __u8 reg9a_sn9c325[] =
633                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
634
635
636         regF1 = 0x00;
637         reg_w(dev, 0xf1, &regF1, 1);
638
639         reg_w(dev, 0x01, &sn9c1xx[0], 1);       /*fixme:jfm was [1] en v1*/
640
641         /* configure gpio */
642         reg_w(dev, 0x01, &sn9c1xx[1], 2);
643         reg_w(dev, 0x08, &sn9c1xx[8], 2);
644         reg_w(dev, 0x17, &sn9c1xx[0x17], 3);
645         switch (sd->customid) {
646         case SN9C325:
647                 reg9a = reg9a_sn9c325;
648                 break;
649         case SN9C120:
650                 reg9a = reg9a_sn9c120;
651                 break;
652         default:
653                 reg9a = reg9a_def;
654                 break;
655         }
656         reg_w(dev, 0x9a, reg9a, 6);
657
658         data = 0x60;                            /*fixme:jfm 60 00 00 (3) */
659         reg_w(dev, 0xd4, &data, 1);
660
661         reg_w(dev, 0x03, &sn9c1xx[3], 0x0f);
662
663         switch (sd->customid) {
664         case SN9C120:                           /* from win trace */
665                 data = 0x61;
666                 reg_w(dev, 0x01, &data, 1);
667                 data = 0x20;
668                 reg_w(dev, 0x17, &data, 1);
669                 data = 0x60;
670                 reg_w(dev, 0x01, &data, 1);
671                 break;
672         case SN9C325:
673                 data = 0x43;
674                 reg_w(dev, 0x01, &data, 1);
675                 data = 0xae;
676                 reg_w(dev, 0x17, &data, 1);
677                 data = 0x42;
678                 reg_w(dev, 0x01, &data, 1);
679                 break;
680         default:
681                 data = 0x43;
682                 reg_w(dev, 0x01, &data, 1);
683                 data = 0x61;
684                 reg_w(dev, 0x17, &data, 1);
685                 data = 0x42;
686                 reg_w(dev, 0x01, &data, 1);
687         }
688
689         if (sd->sensor == SENSOR_HV7131R) {
690                 if (probesensor(gspca_dev) < 0)
691                         return -ENODEV;
692         }
693         return 0;
694 }
695
696 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
697 {
698         int i = 0;
699         struct usb_device *dev = gspca_dev->dev;
700         static __u8 SetSensorClk[] =            /* 0x08 Mclk */
701                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
702
703         while (hv7131r_sensor_init[i][0]) {
704                 i2c_w8(dev, hv7131r_sensor_init[i]);
705                 i++;
706         }
707         i2c_w8(dev, SetSensorClk);
708 }
709
710 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
711 {
712         int i = 0;
713         struct usb_device *dev = gspca_dev->dev;
714
715         while (mi0360_sensor_init[i][0]) {
716                 i2c_w8(dev, mi0360_sensor_init[i]);
717                 i++;
718         }
719 }
720
721 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
722 {
723         int i = 0;
724         struct usb_device *dev = gspca_dev->dev;
725
726         while (mo4000_sensor_init[i][0]) {
727                 i2c_w8(dev, mo4000_sensor_init[i]);
728                 i++;
729         }
730 }
731
732 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
733 {
734         struct usb_device *dev = gspca_dev->dev;
735         int i = 0;
736
737         while (ov7648_sensor_init[i][0]) {
738                 i2c_w8(dev, ov7648_sensor_init[i]);
739                 i++;
740         }
741 }
742
743 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
744 {
745         int i = 0;
746         struct usb_device *dev = gspca_dev->dev;
747
748         while (ov7660_sensor_init[i][0]) {
749                 i2c_w8(dev, ov7660_sensor_init[i]);
750                 i++;
751         }
752 }
753
754 /* this function is called at probe time */
755 static int sd_config(struct gspca_dev *gspca_dev,
756                         const struct usb_device_id *id)
757 {
758         struct sd *sd = (struct sd *) gspca_dev;
759         struct cam *cam;
760         __u16 vendor;
761         __u16 product;
762
763         vendor = id->idVendor;
764         product = id->idProduct;
765         sd->sensor = -1;
766         switch (vendor) {
767         case 0x0458:                            /* Genius */
768 /*              switch (product) {
769                 case 0x7025: */
770                         sd->customid = SN9C120;
771                         sd->sensor = SENSOR_MI0360;
772                         sd->i2c_ctrl_reg = 0x81;
773                         sd->i2c_base = 0x5d;
774 /*                      break;
775                 } */
776                 break;
777         case 0x045e:
778 /*              switch (product) {
779                 case 0x00f5:
780                 case 0x00f7: */
781                         sd->customid = SN9C105;
782                         sd->sensor = SENSOR_OV7660;
783                         sd->i2c_ctrl_reg = 0x81;
784                         sd->i2c_base = 0x21;
785 /*                      break;
786                 } */
787                 break;
788         case 0x0471:                            /* Philips */
789 /*              switch (product) {
790                 case 0x0327:
791                 case 0x0328:
792                 case 0x0330: */
793                         sd->customid = SN9C105;
794                         sd->sensor = SENSOR_MI0360;
795                         sd->i2c_ctrl_reg = 0x81;
796                         sd->i2c_base = 0x5d;
797 /*                      break;
798                 } */
799                 break;
800         case 0x0c45:                            /* Sonix */
801                 switch (product) {
802                 case 0x6040:
803                         sd->customid = SN9C102P;
804                         sd->sensor = SENSOR_MI0360;     /* from BW600.inf */
805 /*                      sd->sensor = SENSOR_HV7131R;     * gspcav1 value */
806                         sd->i2c_ctrl_reg = 0x81;
807                         sd->i2c_base = 0x11;
808                         break;
809 /*              case 0x607a:                            * from BW600.inf
810                         sd->customid = SN9C102P;
811                         sd->sensor = SENSOR_OV7648;
812                         sd->i2c_ctrl_reg = 0x??;
813                         sd->i2c_base = 0x??;
814                         break; */
815                 case 0x607c:
816                         sd->customid = SN9C102P;
817                         sd->sensor = SENSOR_HV7131R;
818                         sd->i2c_ctrl_reg = 0x81;
819                         sd->i2c_base = 0x11;
820                         break;
821 /*              case 0x607e:                            * from BW600.inf
822                         sd->customid = SN9C102P;
823                         sd->sensor = SENSOR_OV7630;
824                         sd->i2c_ctrl_reg = 0x??;
825                         sd->i2c_base = 0x??;
826                         break; */
827                 case 0x60c0:
828                         sd->customid = SN9C105;
829                         sd->sensor = SENSOR_MI0360;
830                         sd->i2c_ctrl_reg = 0x81;
831                         sd->i2c_base = 0x5d;
832                         break;
833 /*              case 0x60c8:                            * from BW600.inf
834                         sd->customid = SN9C105;
835                         sd->sensor = SENSOR_OM6801;
836                         sd->i2c_ctrl_reg = 0x??;
837                         sd->i2c_base = 0x??;
838                         break; */
839 /*              case 0x60cc:                            * from BW600.inf
840                         sd->customid = SN9C105;
841                         sd->sensor = SENSOR_HV7131GP;
842                         sd->i2c_ctrl_reg = 0x??;
843                         sd->i2c_base = 0x??;
844                         break; */
845                 case 0x60ec:
846                         sd->customid = SN9C105;
847                         sd->sensor = SENSOR_MO4000;
848                         sd->i2c_ctrl_reg = 0x81;
849                         sd->i2c_base = 0x21;
850                         break;
851 /*              case 0x60ef:                            * from BW600.inf
852                         sd->customid = SN9C105;
853                         sd->sensor = SENSOR_ICM105C;
854                         sd->i2c_ctrl_reg = 0x??;
855                         sd->i2c_base = 0x??;
856                         break; */
857 /*              case 0x60fa:                            * from BW600.inf
858                         sd->customid = SN9C105;
859                         sd->sensor = SENSOR_OV7648;
860                         sd->i2c_ctrl_reg = 0x??;
861                         sd->i2c_base = 0x??;
862                         break; */
863                 case 0x60fb:
864                         sd->customid = SN9C105;
865                         sd->sensor = SENSOR_OV7660;
866                         sd->i2c_ctrl_reg = 0x81;
867                         sd->i2c_base = 0x21;
868                         break;
869                 case 0x60fc:
870                         sd->customid = SN9C105;
871                         sd->sensor = SENSOR_HV7131R;
872                         sd->i2c_ctrl_reg = 0x81;
873                         sd->i2c_base = 0x11;
874                         break;
875 /*              case 0x60fe:                            * from BW600.inf
876                         sd->customid = SN9C105;
877                         sd->sensor = SENSOR_OV7630;
878                         sd->i2c_ctrl_reg = 0x??;
879                         sd->i2c_base = 0x??;
880                         break; */
881 /*              case 0x6108:                            * from BW600.inf
882                         sd->customid = SN9C120;
883                         sd->sensor = SENSOR_OM6801;
884                         sd->i2c_ctrl_reg = 0x??;
885                         sd->i2c_base = 0x??;
886                         break; */
887 /*              case 0x6122:                            * from BW600.inf
888                         sd->customid = SN9C110;
889                         sd->sensor = SENSOR_ICM105C;
890                         sd->i2c_ctrl_reg = 0x??;
891                         sd->i2c_base = 0x??;
892                         break; */
893                 case 0x612a:
894 /*                      sd->customid = SN9C110;          * in BW600.inf */
895                         sd->customid = SN9C325;
896                         sd->sensor = SENSOR_OV7648;
897                         sd->i2c_ctrl_reg = 0x81;
898                         sd->i2c_base = 0x21;
899                         break;
900 /*              case 0x6123:                            * from BW600.inf
901                         sd->customid = SN9C110;
902                         sd->sensor = SENSOR_SanyoCCD;
903                         sd->i2c_ctrl_reg = 0x??;
904                         sd->i2c_base = 0x??;
905                         break; */
906                 case 0x612c:
907                         sd->customid = SN9C110;
908                         sd->sensor = SENSOR_MO4000;
909                         sd->i2c_ctrl_reg = 0x81;
910                         sd->i2c_base = 0x21;
911                         break;
912 /*              case 0x612e:                            * from BW600.inf
913                         sd->customid = SN9C110;
914                         sd->sensor = SENSOR_OV7630;
915                         sd->i2c_ctrl_reg = 0x??;
916                         sd->i2c_base = 0x??;
917                         break; */
918 /*              case 0x612f:                            * from BW600.inf
919                         sd->customid = SN9C110;
920                         sd->sensor = SENSOR_ICM105C;
921                         sd->i2c_ctrl_reg = 0x??;
922                         sd->i2c_base = 0x??;
923                         break; */
924                 case 0x6130:
925                         sd->customid = SN9C120;
926                         sd->sensor = SENSOR_MI0360;
927                         sd->i2c_ctrl_reg = 0x81;
928                         sd->i2c_base = 0x5d;
929                         break;
930                 case 0x6138:
931                         sd->customid = SN9C120;
932                         sd->sensor = SENSOR_MO4000;
933                         sd->i2c_ctrl_reg = 0x81;
934                         sd->i2c_base = 0x21;
935                         break;
936 /*              case 0x613a:                            * from BW600.inf
937                         sd->customid = SN9C120;
938                         sd->sensor = SENSOR_OV7648;
939                         sd->i2c_ctrl_reg = 0x??;
940                         sd->i2c_base = 0x??;
941                         break; */
942                 case 0x613b:
943                         sd->customid = SN9C120;
944                         sd->sensor = SENSOR_OV7660;
945                         sd->i2c_ctrl_reg = 0x81;
946                         sd->i2c_base = 0x21;
947                         break;
948                 case 0x613c:
949                         sd->customid = SN9C120;
950                         sd->sensor = SENSOR_HV7131R;
951                         sd->i2c_ctrl_reg = 0x81;
952                         sd->i2c_base = 0x11;
953                         break;
954 /*              case 0x613e:                            * from BW600.inf
955                         sd->customid = SN9C120;
956                         sd->sensor = SENSOR_OV7630;
957                         sd->i2c_ctrl_reg = 0x??;
958                         sd->i2c_base = 0x??;
959                         break; */
960                 }
961                 break;
962         }
963         if (sd->sensor < 0) {
964                 PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
965                         vendor, product);
966                 return -EINVAL;
967         }
968
969         cam = &gspca_dev->cam;
970         cam->dev_name = (char *) id->driver_info;
971         cam->epaddr = 0x01;
972         cam->cam_mode = vga_mode;
973         cam->nmodes = ARRAY_SIZE(vga_mode);
974         sd->qindex = 4;                 /* set the quantization table */
975         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
976         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
977         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
978         sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
979         return 0;
980 }
981
982 /* this function is called at open time */
983 static int sd_open(struct gspca_dev *gspca_dev)
984 {
985         struct sd *sd = (struct sd *) gspca_dev;
986         struct usb_device *dev = gspca_dev->dev;
987 /*      __u8 *sn9c1xx; */
988         __u8 regF1;
989         __u8 regGpio[] = { 0x29, 0x74 };
990
991         /* setup a selector by customid */
992         regF1 = 0x01;
993         reg_w(dev, 0xf1, &regF1, 1);
994         reg_r(dev, 0x00, &regF1, 1);    /* -> regF1 = 0x00 */
995         reg_w(dev, 0xf1, &regF1, 1);
996         reg_r(dev, 0x00, &regF1, 1);
997         switch (sd->customid) {
998         case SN9C102P:
999                 if (regF1 != 0x11)
1000                         return -ENODEV;
1001                 reg_w(dev, 0x02, &regGpio[1], 1);
1002                 break;
1003         case SN9C105:
1004                 if (regF1 != 0x11)
1005                         return -ENODEV;
1006                 reg_w(dev, 0x02, regGpio, 2);
1007                 break;
1008         case SN9C110:
1009                 if (regF1 != 0x12)
1010                         return -ENODEV;
1011                 regGpio[1] = 0x62;
1012                 reg_w(dev, 0x02, &regGpio[1], 1);
1013                 break;
1014         case SN9C120:
1015                 if (regF1 != 0x12)
1016                         return -ENODEV;
1017                 regGpio[1] = 0x70;
1018                 reg_w(dev, 0x02, regGpio, 2);
1019                 break;
1020         default:
1021 /*      case SN9C325: */
1022                 if (regF1 != 0x12)
1023                         return -ENODEV;
1024                 regGpio[1] = 0x62;
1025                 reg_w(dev, 0x02, &regGpio[1], 1);
1026                 break;
1027         }
1028
1029         regF1 = 0x01;
1030         reg_w(dev, 0xf1, &regF1, 1);
1031
1032         return 0;
1033 }
1034
1035 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1036                                 unsigned int expo)
1037 {
1038         struct sd *sd = (struct sd *) gspca_dev;
1039         static __u8 doit[] =                    /* update sensor */
1040                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1041         static __u8 sensorgo[] =                /* sensor on */
1042                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1043         static __u8 gainMo[] =
1044                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1045
1046         switch (sd->sensor) {
1047         case SENSOR_HV7131R: {
1048                 __u8 Expodoit[] =
1049                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1050
1051                 Expodoit[3] = expo >> 16;
1052                 Expodoit[4] = expo >> 8;
1053                 Expodoit[5] = expo;
1054                 i2c_w8(gspca_dev->dev, Expodoit);
1055                 break;
1056             }
1057         case SENSOR_MI0360: {
1058                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
1059                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1060
1061                 if (expo > 0x0635)
1062                         expo = 0x0635;
1063                 else if (expo < 0x0001)
1064                         expo = 0x0001;
1065                 expoMi[3] = expo >> 8;
1066                 expoMi[4] = expo;
1067                 i2c_w8(gspca_dev->dev, expoMi);
1068                 i2c_w8(gspca_dev->dev, doit);
1069                 i2c_w8(gspca_dev->dev, sensorgo);
1070                 break;
1071             }
1072         case SENSOR_MO4000: {
1073                 __u8 expoMof[] =
1074                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1075                 __u8 expoMo10[] =
1076                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1077
1078                 if (expo > 0x1fff)
1079                         expo = 0x1fff;
1080                 else if (expo < 0x0001)
1081                         expo = 0x0001;
1082                 expoMof[3] = (expo & 0x03fc) >> 2;
1083                 i2c_w8(gspca_dev->dev, expoMof);
1084                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1085                                 | ((expo & 0x0003) << 4);
1086                 i2c_w8(gspca_dev->dev, expoMo10);
1087                 i2c_w8(gspca_dev->dev, gainMo);
1088                 PDEBUG(D_CONF, "set exposure %d",
1089                         ((expoMo10[3] & 0x07) << 10)
1090                         | (expoMof[3] << 2)
1091                         | ((expoMo10[3] & 0x30) >> 4));
1092                 break;
1093             }
1094         }
1095         return expo;
1096 }
1097
1098 static void setbrightness(struct gspca_dev *gspca_dev)
1099 {
1100         struct sd *sd = (struct sd *) gspca_dev;
1101         unsigned int expo;
1102         __u8 k2;
1103
1104         switch (sd->sensor) {
1105         case SENSOR_HV7131R:
1106                 expo = sd->brightness << 4;
1107                 if (expo > 0x002dc6c0)
1108                         expo = 0x002dc6c0;
1109                 else if (expo < 0x02a0)
1110                         expo = 0x02a0;
1111                 sd->exposure = setexposure(gspca_dev, expo);
1112                 break;
1113         case SENSOR_MI0360:
1114                 expo = sd->brightness >> 4;
1115                 sd->exposure = setexposure(gspca_dev, expo);
1116                 break;
1117         case SENSOR_MO4000:
1118                 expo = sd->brightness >> 4;
1119                 sd->exposure = setexposure(gspca_dev, expo);
1120                 break;
1121         case SENSOR_OV7660:
1122                 return;                         /*jfm??*/
1123         }
1124
1125         k2 = sd->brightness >> 10;
1126         reg_w(gspca_dev->dev, 0x96, &k2, 1);
1127 }
1128
1129 static void setcontrast(struct gspca_dev *gspca_dev)
1130 {
1131         struct sd *sd = (struct sd *) gspca_dev;
1132         __u8 k2;
1133         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1134
1135         if (sd->sensor == SENSOR_OV7660)
1136                 return;                         /*jfm??*/
1137         k2 = sd->contrast;
1138         contrast[2] = k2;
1139         contrast[0] = (k2 + 1) >> 1;
1140         contrast[4] = (k2 + 1) / 5;
1141         reg_w(gspca_dev->dev, 0x84, contrast, 6);
1142 }
1143
1144 static void setcolors(struct gspca_dev *gspca_dev)
1145 {
1146         struct sd *sd = (struct sd *) gspca_dev;
1147         __u8 data;
1148         int colour;
1149
1150         colour = sd->colors - 128;
1151         if (colour > 0)
1152                 data = (colour + 32) & 0x7f;    /* blue */
1153         else
1154                 data = (-colour + 32) & 0x7f;   /* red */
1155         reg_w(gspca_dev->dev, 0x05, &data, 1);
1156 }
1157
1158 /* -- start the camera -- */
1159 static void sd_start(struct gspca_dev *gspca_dev)
1160 {
1161         struct sd *sd = (struct sd *) gspca_dev;
1162         struct usb_device *dev = gspca_dev->dev;
1163         int i;
1164         __u8 data;
1165         __u8 reg1;
1166         __u8 reg17;
1167         __u8 *sn9c1xx;
1168         int mode;
1169         static __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
1170         static __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1171         static __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1172         static __u8 CA_sn9c120[] = { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
1173         static __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };  /* MI0360 */
1174         static __u8 CE_sn9c325[] =
1175                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7648 - SN9C325 */
1176
1177         sn9c1xx = sn_tb[(int) sd->sensor];
1178         configure_gpio(gspca_dev, sn9c1xx);
1179
1180 /*fixme:jfm this sequence should appear at end of sd_start */
1181 /* with
1182         data = 0x44;
1183         reg_w(dev, 0x01, &data, 1); */
1184         reg_w(dev, 0x15, &sn9c1xx[0x15], 1);
1185         reg_w(dev, 0x16, &sn9c1xx[0x16], 1);
1186         reg_w(dev, 0x12, &sn9c1xx[0x12], 1);
1187         reg_w(dev, 0x13, &sn9c1xx[0x13], 1);
1188         reg_w(dev, 0x18, &sn9c1xx[0x18], 1);
1189         reg_w(dev, 0xd2, &DC29[0], 1);
1190         reg_w(dev, 0xd3, &DC29[1], 1);
1191         reg_w(dev, 0xc6, &DC29[2], 1);
1192         reg_w(dev, 0xc7, &DC29[3], 1);
1193         reg_w(dev, 0xc8, &DC29[4], 1);
1194         reg_w(dev, 0xc9, &DC29[5], 1);
1195 /*fixme:jfm end of ending sequence */
1196         reg_w(dev, 0x18, &sn9c1xx[0x18], 1);
1197         if (sd->customid == SN9C325)
1198                 data = 0xae;
1199         else
1200                 data = 0x60;
1201         reg_w(dev, 0x17, &data, 1);
1202         reg_w(dev, 0x05, &sn9c1xx[5], 1);
1203         reg_w(dev, 0x07, &sn9c1xx[7], 1);
1204         reg_w(dev, 0x06, &sn9c1xx[6], 1);
1205         reg_w(dev, 0x14, &sn9c1xx[0x14], 1);
1206         if (sd->customid == SN9C325) {
1207                 reg_w(dev, 0x20, regsn20_sn9c325, 0x11);
1208                 for (i = 0; i < 8; i++)
1209                         reg_w(dev, 0x84, reg84_sn9c325, 0x15);
1210                 data = 0x0a;
1211                 reg_w(dev, 0x9a, &data, 1);
1212                 data = 0x60;
1213                 reg_w(dev, 0x99, &data, 1);
1214         } else {
1215                 reg_w(dev, 0x20, regsn20, 0x11);
1216                 for (i = 0; i < 8; i++)
1217                         reg_w(dev, 0x84, reg84, 0x15);
1218                 data = 0x08;
1219                 reg_w(dev, 0x9a, &data, 1);
1220                 data = 0x59;
1221                 reg_w(dev, 0x99, &data, 1);
1222         }
1223
1224         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
1225         reg1 = 0x02;
1226         reg17 = 0x61;
1227         switch (sd->sensor) {
1228         case SENSOR_HV7131R:
1229                 hv7131R_InitSensor(gspca_dev);
1230                 if (mode)
1231                         reg1 = 0x46;    /* 320 clk 48Mhz */
1232                 else
1233                         reg1 = 0x06;    /* 640 clk 24Mz */
1234                 break;
1235         case SENSOR_MI0360:
1236                 mi0360_InitSensor(gspca_dev);
1237                 if (mode)
1238                         reg1 = 0x46;    /* 320 clk 48Mhz */
1239                 else
1240                         reg1 = 0x06;    /* 640 clk 24Mz */
1241                 break;
1242         case SENSOR_MO4000:
1243                 mo4000_InitSensor(gspca_dev);
1244                 if (mode) {
1245 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1246                         reg1 = 0x06;    /* clk 24Mz */
1247                 } else {
1248                         reg17 = 0x22;   /* 640 MCKSIZE */
1249                         reg1 = 0x06;    /* 640 clk 24Mz */
1250                 }
1251                 break;
1252         case SENSOR_OV7648:
1253                 reg17 = 0xa2;
1254                 reg1 = 0x44;
1255                 ov7648_InitSensor(gspca_dev);
1256 /*              if (mode)
1257                         ;                * 320x2...
1258                 else
1259                         ;                * 640x... */
1260                 break;
1261         default:
1262 /*      case SENSOR_OV7660: */
1263                 ov7660_InitSensor(gspca_dev);
1264                 if (mode) {
1265 /*                      reg17 = 0x21;    * 320 */
1266 /*                      reg1 = 0x44; */
1267                         reg1 = 0x46;
1268                 } else {
1269                         reg17 = 0xa2;   /* 640 */
1270                         reg1 = 0x40;
1271                 }
1272                 break;
1273         }
1274         reg_w(dev, 0xc0, C0, 6);
1275         switch (sd->customid) {
1276         case SN9C120:                   /*jfm ?? */
1277                 reg_w(dev, 0xca, CA_sn9c120, 4);
1278                 break;
1279         default:
1280                 reg_w(dev, 0xca, CA, 4);
1281                 break;
1282         }
1283         switch (sd->customid) {
1284         case SN9C120:                   /*jfm ?? */
1285         case SN9C325:
1286                 reg_w(dev, 0xce, CE_sn9c325, 4);
1287                 break;
1288         default:
1289                 reg_w(dev, 0xce, CE, 4);
1290                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1291                 break;
1292         }
1293
1294         /* here change size mode 0 -> VGA; 1 -> CIF */
1295         data = 0x40 | sn9c1xx[0x18] | (mode << 4);
1296         reg_w(dev, 0x18, &data, 1);
1297
1298         reg_w(dev, 0x100, qtable4, 0x40);
1299         reg_w(dev, 0x140, qtable4 + 0x40, 0x40);
1300
1301         data = sn9c1xx[0x18] | (mode << 4);
1302         reg_w(dev, 0x18, &data, 1);
1303
1304         reg_w(dev, 0x17, &reg17, 1);
1305         reg_w(dev, 0x01, &reg1, 1);
1306         setbrightness(gspca_dev);
1307         setcontrast(gspca_dev);
1308 }
1309
1310 static void sd_stopN(struct gspca_dev *gspca_dev)
1311 {
1312         struct sd *sd = (struct sd *) gspca_dev;
1313         struct usb_device *dev = gspca_dev->dev;
1314         static __u8 stophv7131[] =
1315                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1316         static __u8 stopmi0360[] =
1317                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1318         __u8 regF1;
1319         __u8 data;
1320         __u8 *sn9c1xx;
1321
1322         data = 0x0b;
1323         switch (sd->sensor) {
1324         case SENSOR_HV7131R:
1325                 i2c_w8(dev, stophv7131);
1326                 data = 0x2b;
1327                 break;
1328         case SENSOR_MI0360:
1329                 i2c_w8(dev, stopmi0360);
1330                 data = 0x29;
1331                 break;
1332         case SENSOR_MO4000:
1333                 break;
1334         case SENSOR_OV7648:
1335                 data = 0x29;
1336                 break;
1337         default:
1338 /*      case SENSOR_OV7660: */
1339                 break;
1340         }
1341         sn9c1xx = sn_tb[(int) sd->sensor];
1342         reg_w(dev, 0x01, &sn9c1xx[1], 1);
1343         reg_w(dev, 0x17, &sn9c1xx[0x17], 1);
1344         reg_w(dev, 0x01, &sn9c1xx[1], 1);
1345         reg_w(dev, 0x01, &data, 1);
1346         regF1 = 0x01;
1347         reg_w(dev, 0xf1, &regF1, 1);
1348 }
1349
1350 static void sd_stop0(struct gspca_dev *gspca_dev)
1351 {
1352 }
1353
1354 static void sd_close(struct gspca_dev *gspca_dev)
1355 {
1356 }
1357
1358 static void setautogain(struct gspca_dev *gspca_dev)
1359 {
1360         struct sd *sd = (struct sd *) gspca_dev;
1361         /* Thanks S., without your advice, autobright should not work :) */
1362         int delta;
1363         int expotimes = 0;
1364         __u8 luma_mean = 130;
1365         __u8 luma_delta = 20;
1366
1367         delta = sd->avg_lum;
1368         if (delta < luma_mean - luma_delta ||
1369             delta > luma_mean + luma_delta) {
1370                 switch (sd->sensor) {
1371                 case SENSOR_HV7131R:
1372                         expotimes = sd->exposure >> 8;
1373                         expotimes += (luma_mean - delta) >> 4;
1374                         if (expotimes < 0)
1375                                 expotimes = 0;
1376                         sd->exposure = setexposure(gspca_dev,
1377                                         (unsigned int) (expotimes << 8));
1378                         break;
1379                 case SENSOR_MO4000:
1380                 case SENSOR_MI0360:
1381                         expotimes = sd->exposure;
1382                         expotimes += (luma_mean - delta) >> 6;
1383                         if (expotimes < 0)
1384                                 expotimes = 0;
1385                         sd->exposure = setexposure(gspca_dev,
1386                                                    (unsigned int) expotimes);
1387                         setcolors(gspca_dev);
1388                         break;
1389                 }
1390         }
1391 }
1392
1393 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1394                         struct gspca_frame *frame,      /* target */
1395                         unsigned char *data,            /* isoc packet */
1396                         int len)                        /* iso packet length */
1397 {
1398         struct sd *sd = (struct sd *) gspca_dev;
1399         int sof, avg_lum;
1400
1401         sof = len - 64;
1402         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1403
1404                 /* end of frame */
1405                 gspca_frame_add(gspca_dev, LAST_PACKET,
1406                                 frame, data, sof + 2);
1407                 if (sd->ag_cnt < 0)
1408                         return;
1409                 if (--sd->ag_cnt >= 0)
1410                         return;
1411                 sd->ag_cnt = AG_CNT_START;
1412 /* w1 w2 w3 */
1413 /* w4 w5 w6 */
1414 /* w7 w8 */
1415 /* w4 */
1416                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1417 /* w6 */
1418                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1419 /* w2 */
1420                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1421 /* w8 */
1422                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1423 /* w5 */
1424                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1425                 avg_lum >>= 4;
1426                 sd->avg_lum = avg_lum;
1427                 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1428                 setautogain(gspca_dev);
1429                 return;
1430         }
1431         if (gspca_dev->last_packet_type == LAST_PACKET) {
1432
1433                 /* put the JPEG 422 header */
1434                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1435         }
1436         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1437 }
1438
1439 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1440 {
1441         struct sd *sd = (struct sd *) gspca_dev;
1442         __u8 hexpo, mexpo, lexpo;
1443         __u8 expo[6];
1444
1445         switch (sd->sensor) {
1446         case SENSOR_HV7131R:
1447                 /* read sensor exposure */
1448                 i2c_r5(gspca_dev, 0x25, expo);
1449                 return (expo[0] << 16) | (expo[1] << 8) | expo[2];
1450         case SENSOR_MI0360:
1451                 /* read sensor exposure */
1452                 i2c_r5(gspca_dev, 0x09, expo);
1453                 return (expo[0] << 8) | expo[1];
1454         case SENSOR_MO4000:
1455                 i2c_r5(gspca_dev, 0x0e, expo);
1456                 hexpo = 0;              /* expo[1] & 0x07; */
1457                 mexpo = 0x40;           /* expo[2] &0xff; */
1458                 lexpo = (expo[1] & 0x30) >> 4;
1459                 PDEBUG(D_CONF, "exposure %d",
1460                         (hexpo << 10) | (mexpo << 2) | lexpo);
1461                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1462         default:
1463 /*      case SENSOR_OV7660: */
1464                 /* read sensor exposure */
1465                 i2c_r5(gspca_dev, 0x04, expo);
1466                 hexpo = expo[3] & 0x2f;
1467                 lexpo = expo[0] & 0x02;
1468                 i2c_r5(gspca_dev, 0x08, expo);
1469                 mexpo = expo[2];
1470                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1471         }
1472 }
1473
1474 static void getbrightness(struct gspca_dev *gspca_dev)
1475 {
1476         struct sd *sd = (struct sd *) gspca_dev;
1477
1478         /* hardcoded registers seem not readable */
1479         switch (sd->sensor) {
1480         case SENSOR_HV7131R:
1481 /*              sd->brightness = 0x7fff; */
1482                 sd->brightness = getexposure(gspca_dev) >> 4;
1483                 break;
1484         case SENSOR_MI0360:
1485                 sd->brightness = getexposure(gspca_dev) << 4;
1486                 break;
1487         case SENSOR_MO4000:
1488 /*              sd->brightness = 0x1fff; */
1489                 sd->brightness = getexposure(gspca_dev) << 4;
1490                 break;
1491         }
1492 }
1493
1494 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1495 {
1496         struct sd *sd = (struct sd *) gspca_dev;
1497
1498         sd->brightness = val;
1499         if (gspca_dev->streaming)
1500                 setbrightness(gspca_dev);
1501         return 0;
1502 }
1503
1504 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1505 {
1506         struct sd *sd = (struct sd *) gspca_dev;
1507
1508         getbrightness(gspca_dev);
1509         *val = sd->brightness;
1510         return 0;
1511 }
1512
1513 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1514 {
1515         struct sd *sd = (struct sd *) gspca_dev;
1516
1517         sd->contrast = val;
1518         if (gspca_dev->streaming)
1519                 setcontrast(gspca_dev);
1520         return 0;
1521 }
1522
1523 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1524 {
1525         struct sd *sd = (struct sd *) gspca_dev;
1526
1527         *val = sd->contrast;
1528         return 0;
1529 }
1530
1531 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1532 {
1533         struct sd *sd = (struct sd *) gspca_dev;
1534
1535         sd->colors = val;
1536         if (gspca_dev->streaming)
1537                 setcolors(gspca_dev);
1538         return 0;
1539 }
1540
1541 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1542 {
1543         struct sd *sd = (struct sd *) gspca_dev;
1544
1545         *val = sd->colors;
1546         return 0;
1547 }
1548
1549 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1550 {
1551         struct sd *sd = (struct sd *) gspca_dev;
1552
1553         sd->autogain = val;
1554         if (val)
1555                 sd->ag_cnt = AG_CNT_START;
1556         else
1557                 sd->ag_cnt = -1;
1558         return 0;
1559 }
1560
1561 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1562 {
1563         struct sd *sd = (struct sd *) gspca_dev;
1564
1565         *val = sd->autogain;
1566         return 0;
1567 }
1568
1569 /* sub-driver description */
1570 static struct sd_desc sd_desc = {
1571         .name = MODULE_NAME,
1572         .ctrls = sd_ctrls,
1573         .nctrls = ARRAY_SIZE(sd_ctrls),
1574         .config = sd_config,
1575         .open = sd_open,
1576         .start = sd_start,
1577         .stopN = sd_stopN,
1578         .stop0 = sd_stop0,
1579         .close = sd_close,
1580         .pkt_scan = sd_pkt_scan,
1581 };
1582
1583 /* -- module initialisation -- */
1584 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1585 static __devinitdata struct usb_device_id device_table[] = {
1586         {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
1587         {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
1588         {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
1589         {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
1590         {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
1591         {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
1592         {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
1593         {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
1594         {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
1595         {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
1596         {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
1597         {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
1598         {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
1599         {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
1600         {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
1601         {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
1602         {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
1603         {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
1604         {}
1605 };
1606 MODULE_DEVICE_TABLE(usb, device_table);
1607
1608 /* -- device connect -- */
1609 static int sd_probe(struct usb_interface *intf,
1610                     const struct usb_device_id *id)
1611 {
1612         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1613                                 THIS_MODULE);
1614 }
1615
1616 static struct usb_driver sd_driver = {
1617         .name = MODULE_NAME,
1618         .id_table = device_table,
1619         .probe = sd_probe,
1620         .disconnect = gspca_disconnect,
1621 };
1622
1623 /* -- module insert / remove -- */
1624 static int __init sd_mod_init(void)
1625 {
1626         if (usb_register(&sd_driver) < 0)
1627                 return -1;
1628         info("v%s registered", version);
1629         return 0;
1630 }
1631 static void __exit sd_mod_exit(void)
1632 {
1633         usb_deregister(&sd_driver);
1634         info("deregistered");
1635 }
1636
1637 module_init(sd_mod_init);
1638 module_exit(sd_mod_exit);