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