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