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