]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixj.c
ide: workaround for bogus gcc warning in ide_sysfs_register_port()
[linux-2.6-omap-h63xx.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 #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 to gspca_dev->usb_buf */
617 static void reg_r(struct gspca_dev *gspca_dev,
618                   __u16 value, int len)
619 {
620 #ifdef GSPCA_DEBUG
621         if (len > USB_BUF_SZ) {
622                 err("reg_r: buffer overflow");
623                 return;
624         }
625 #endif
626         usb_control_msg(gspca_dev->dev,
627                         usb_rcvctrlpipe(gspca_dev->dev, 0),
628                         0,
629                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
630                         value, 0,
631                         gspca_dev->usb_buf, len,
632                         500);
633         PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
634 }
635
636 static void reg_w1(struct gspca_dev *gspca_dev,
637                    __u16 value,
638                    __u8 data)
639 {
640         PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
641         gspca_dev->usb_buf[0] = data;
642         usb_control_msg(gspca_dev->dev,
643                         usb_sndctrlpipe(gspca_dev->dev, 0),
644                         0x08,
645                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
646                         value,
647                         0,
648                         gspca_dev->usb_buf, 1,
649                         500);
650 }
651 static void reg_w(struct gspca_dev *gspca_dev,
652                           __u16 value,
653                           const __u8 *buffer,
654                           int len)
655 {
656         PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
657                 value, buffer[0], buffer[1]);
658 #ifdef GSPCA_DEBUG
659         if (len > USB_BUF_SZ) {
660                 err("reg_w: buffer overflow");
661                 return;
662         }
663 #endif
664         memcpy(gspca_dev->usb_buf, 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                         gspca_dev->usb_buf, len,
671                         500);
672 }
673
674 /* I2C write 1 byte */
675 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
676 {
677         struct sd *sd = (struct sd *) gspca_dev;
678
679         PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
680         gspca_dev->usb_buf[0] = 0x81 | (2 << 4);        /* = a1 */
681         gspca_dev->usb_buf[1] = sd->i2c_base;
682         gspca_dev->usb_buf[2] = reg;
683         gspca_dev->usb_buf[3] = val;
684         gspca_dev->usb_buf[4] = 0;
685         gspca_dev->usb_buf[5] = 0;
686         gspca_dev->usb_buf[6] = 0;
687         gspca_dev->usb_buf[7] = 0x10;
688         usb_control_msg(gspca_dev->dev,
689                         usb_sndctrlpipe(gspca_dev->dev, 0),
690                         0x08,
691                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
692                         0x08,                   /* value = i2c */
693                         0,
694                         gspca_dev->usb_buf, 8,
695                         500);
696 }
697
698 /* I2C write 8 bytes */
699 static void i2c_w8(struct gspca_dev *gspca_dev,
700                    const __u8 *buffer)
701 {
702         memcpy(gspca_dev->usb_buf, buffer, 8);
703         usb_control_msg(gspca_dev->dev,
704                         usb_sndctrlpipe(gspca_dev->dev, 0),
705                         0x08,
706                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
707                         0x08, 0,                /* value, index */
708                         gspca_dev->usb_buf, 8,
709                         500);
710 }
711
712 /* read 5 bytes in gspca_dev->usb_buf */
713 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
714 {
715         struct sd *sd = (struct sd *) gspca_dev;
716         __u8 mode[8];
717
718         mode[0] = 0x81 | 0x10;
719         mode[1] = sd->i2c_base;
720         mode[2] = reg;
721         mode[3] = 0;
722         mode[4] = 0;
723         mode[5] = 0;
724         mode[6] = 0;
725         mode[7] = 0x10;
726         i2c_w8(gspca_dev, mode);
727         msleep(2);
728         mode[0] = 0x81 | (5 << 4) | 0x02;
729         mode[2] = 0;
730         i2c_w8(gspca_dev, mode);
731         msleep(2);
732         reg_r(gspca_dev, 0x0a, 5);
733 }
734
735 static int probesensor(struct gspca_dev *gspca_dev)
736 {
737         struct sd *sd = (struct sd *) gspca_dev;
738
739         i2c_w1(gspca_dev, 0x02, 0);                     /* sensor wakeup */
740         msleep(10);
741         reg_w1(gspca_dev, 0x02, 0x66);                  /* Gpio on */
742         msleep(10);
743         i2c_r5(gspca_dev, 0);                           /* read sensor id */
744         if (gspca_dev->usb_buf[0] == 0x02
745             && gspca_dev->usb_buf[1] == 0x09
746             && gspca_dev->usb_buf[2] == 0x01
747             && gspca_dev->usb_buf[3] == 0x00
748             && gspca_dev->usb_buf[4] == 0x00) {
749                 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
750                 sd->sensor = SENSOR_HV7131R;
751                 return SENSOR_HV7131R;
752         }
753         PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
754                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
755                 gspca_dev->usb_buf[2]);
756         PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
757         return -ENODEV;
758 }
759
760 static int configure_gpio(struct gspca_dev *gspca_dev,
761                           const __u8 *sn9c1xx)
762 {
763         struct sd *sd = (struct sd *) gspca_dev;
764         const __u8 *reg9a;
765         static const __u8 reg9a_def[] =
766                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
767         static const __u8 reg9a_sn9c325[] =
768                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
769         static const __u8 regd4[] = {0x60, 0x00, 0x00};
770
771         reg_w1(gspca_dev, 0xf1, 0x00);
772         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
773
774         /* configure gpio */
775         reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
776         reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
777         reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
778         switch (sd->bridge) {
779         case BRIDGE_SN9C325:
780                 reg9a = reg9a_sn9c325;
781                 break;
782         default:
783                 reg9a = reg9a_def;
784                 break;
785         }
786         reg_w(gspca_dev, 0x9a, reg9a, 6);
787
788         reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
789
790         reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
791
792         switch (sd->sensor) {
793         case SENSOR_OM6802:
794                 reg_w1(gspca_dev, 0x02, 0x71);
795                 reg_w1(gspca_dev, 0x01, 0x42);
796                 reg_w1(gspca_dev, 0x17, 0x64);
797                 reg_w1(gspca_dev, 0x01, 0x42);
798                 break;
799 /*jfm: from win trace */
800         case SENSOR_OV7630:
801                 reg_w1(gspca_dev, 0x01, 0x61);
802                 reg_w1(gspca_dev, 0x17, 0xe2);
803                 reg_w1(gspca_dev, 0x01, 0x60);
804                 reg_w1(gspca_dev, 0x01, 0x40);
805                 break;
806         case SENSOR_OV7648:
807                 reg_w1(gspca_dev, 0x01, 0x43);
808                 reg_w1(gspca_dev, 0x17, 0xae);
809                 reg_w1(gspca_dev, 0x01, 0x42);
810                 break;
811 /*jfm: from win trace */
812         case SENSOR_OV7660:
813                 reg_w1(gspca_dev, 0x01, 0x61);
814                 reg_w1(gspca_dev, 0x17, 0x20);
815                 reg_w1(gspca_dev, 0x01, 0x60);
816                 reg_w1(gspca_dev, 0x01, 0x40);
817                 break;
818         default:
819                 reg_w1(gspca_dev, 0x01, 0x43);
820                 reg_w1(gspca_dev, 0x17, 0x61);
821                 reg_w1(gspca_dev, 0x01, 0x42);
822                 if (sd->sensor == SENSOR_HV7131R) {
823                         if (probesensor(gspca_dev) < 0)
824                                 return -ENODEV;
825                 }
826                 break;
827         }
828         return 0;
829 }
830
831 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
832 {
833         int i = 0;
834         static const __u8 SetSensorClk[] =      /* 0x08 Mclk */
835                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
836
837         while (hv7131r_sensor_init[i][0]) {
838                 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
839                 i++;
840         }
841         i2c_w8(gspca_dev, SetSensorClk);
842 }
843
844 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
845 {
846         int i = 0;
847
848         while (mi0360_sensor_init[i][0]) {
849                 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
850                 i++;
851         }
852 }
853
854 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
855 {
856         int i = 0;
857
858         while (mo4000_sensor_init[i][0]) {
859                 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
860                 i++;
861         }
862 }
863
864 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
865 {
866         int i = 0;
867
868         while (om6802_sensor_init[i][0]) {
869                 i2c_w8(gspca_dev, om6802_sensor_init[i]);
870                 i++;
871         }
872 }
873
874 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
875 {
876         int i = 0;
877
878         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 76 01 */
879         i++;
880         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 (RGB+SRST) */
881         i++;
882         msleep(20);
883         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
884         i++;
885         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 */
886         i++;
887         msleep(20);
888         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
889         i++;
890 /*jfm:win i2c_r from 00 to 80*/
891
892         while (ov7630_sensor_init[i][0]) {
893                 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
894                 i++;
895         }
896 }
897
898 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
899 {
900         int i = 0;
901
902         while (ov7648_sensor_init[i][0]) {
903                 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
904                 i++;
905         }
906 }
907
908 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
909 {
910         int i = 0;
911
912         i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
913         i++;
914         msleep(20);
915         while (ov7660_sensor_init[i][0]) {
916                 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
917                 i++;
918         }
919 }
920
921 /* this function is called at probe time */
922 static int sd_config(struct gspca_dev *gspca_dev,
923                         const struct usb_device_id *id)
924 {
925         struct sd *sd = (struct sd *) gspca_dev;
926         struct cam *cam;
927
928         cam = &gspca_dev->cam;
929         cam->epaddr = 0x01;
930         cam->cam_mode = vga_mode;
931         cam->nmodes = ARRAY_SIZE(vga_mode);
932
933         sd->bridge = id->driver_info >> 16;
934         sd->sensor = id->driver_info >> 8;
935         sd->i2c_base = id->driver_info;
936
937         sd->qindex = 4;                 /* set the quantization table */
938         sd->brightness = BRIGHTNESS_DEF;
939         sd->contrast = CONTRAST_DEF;
940         sd->colors = COLOR_DEF;
941         sd->autogain = AUTOGAIN_DEF;
942         sd->ag_cnt = -1;
943
944         switch (sd->sensor) {
945         case SENSOR_OV7630:
946         case SENSOR_OV7648:
947         case SENSOR_OV7660:
948                 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
949                 break;
950         }
951
952         return 0;
953 }
954
955 /* this function is called at probe and resume time */
956 static int sd_init(struct gspca_dev *gspca_dev)
957 {
958         struct sd *sd = (struct sd *) gspca_dev;
959 /*      const __u8 *sn9c1xx; */
960         __u8 regGpio[] = { 0x29, 0x74 };
961         __u8 regF1;
962
963         /* setup a selector by bridge */
964         reg_w1(gspca_dev, 0xf1, 0x01);
965         reg_r(gspca_dev, 0x00, 1);
966         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
967         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
968         regF1 = gspca_dev->usb_buf[0];
969         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
970         switch (sd->bridge) {
971         case BRIDGE_SN9C102P:
972                 if (regF1 != 0x11)
973                         return -ENODEV;
974                 reg_w1(gspca_dev, 0x02, regGpio[1]);
975                 break;
976         case BRIDGE_SN9C105:
977                 if (regF1 != 0x11)
978                         return -ENODEV;
979                 reg_w(gspca_dev, 0x02, regGpio, 2);
980                 break;
981         case BRIDGE_SN9C120:
982                 if (regF1 != 0x12)
983                         return -ENODEV;
984                 regGpio[1] = 0x70;
985                 reg_w(gspca_dev, 0x02, regGpio, 2);
986                 break;
987         default:
988 /*      case BRIDGE_SN9C110: */
989 /*      case BRIDGE_SN9C325: */
990                 if (regF1 != 0x12)
991                         return -ENODEV;
992                 reg_w1(gspca_dev, 0x02, 0x62);
993                 break;
994         }
995
996         reg_w1(gspca_dev, 0xf1, 0x01);
997
998         return 0;
999 }
1000
1001 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1002                                 unsigned int expo)
1003 {
1004         struct sd *sd = (struct sd *) gspca_dev;
1005         static const __u8 doit[] =              /* update sensor */
1006                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1007         static const __u8 sensorgo[] =          /* sensor on */
1008                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1009         static const __u8 gainMo[] =
1010                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1011
1012         switch (sd->sensor) {
1013         case SENSOR_HV7131R: {
1014                 __u8 Expodoit[] =
1015                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1016
1017                 Expodoit[3] = expo >> 16;
1018                 Expodoit[4] = expo >> 8;
1019                 Expodoit[5] = expo;
1020                 i2c_w8(gspca_dev, Expodoit);
1021                 break;
1022             }
1023         case SENSOR_MI0360: {
1024                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
1025                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1026
1027                 if (expo > 0x0635)
1028                         expo = 0x0635;
1029                 else if (expo < 0x0001)
1030                         expo = 0x0001;
1031                 expoMi[3] = expo >> 8;
1032                 expoMi[4] = expo;
1033                 i2c_w8(gspca_dev, expoMi);
1034                 i2c_w8(gspca_dev, doit);
1035                 i2c_w8(gspca_dev, sensorgo);
1036                 break;
1037             }
1038         case SENSOR_MO4000: {
1039                 __u8 expoMof[] =
1040                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1041                 __u8 expoMo10[] =
1042                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1043
1044                 if (expo > 0x1fff)
1045                         expo = 0x1fff;
1046                 else if (expo < 0x0001)
1047                         expo = 0x0001;
1048                 expoMof[3] = (expo & 0x03fc) >> 2;
1049                 i2c_w8(gspca_dev, expoMof);
1050                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1051                                 | ((expo & 0x0003) << 4);
1052                 i2c_w8(gspca_dev, expoMo10);
1053                 i2c_w8(gspca_dev, gainMo);
1054                 PDEBUG(D_CONF, "set exposure %d",
1055                         ((expoMo10[3] & 0x07) << 10)
1056                         | (expoMof[3] << 2)
1057                         | ((expoMo10[3] & 0x30) >> 4));
1058                 break;
1059             }
1060         case SENSOR_OM6802: {
1061                 __u8 gainOm[] =
1062                         { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1063
1064                 if (expo > 0x03ff)
1065                         expo = 0x03ff;
1066                  if (expo < 0x0001)
1067                         expo = 0x0001;
1068                 gainOm[3] = expo >> 2;
1069                 i2c_w8(gspca_dev, gainOm);
1070                 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1071                 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1072                 break;
1073             }
1074         }
1075         return expo;
1076 }
1077
1078 /* this function is used for sensors o76xx only */
1079 static void setbrightcont(struct gspca_dev *gspca_dev)
1080 {
1081         struct sd *sd = (struct sd *) gspca_dev;
1082         unsigned val;
1083         __u8 reg84_full[0x15];
1084
1085         memset(reg84_full, 0, sizeof reg84_full);
1086         val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10;        /* 10..30 */
1087         reg84_full[2] = val;
1088         reg84_full[0] = (val + 1) / 2;
1089         reg84_full[4] = (val + 1) / 5;
1090         if (val > BRIGHTNESS_DEF)
1091                 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1092                         / BRIGHTNESS_MAX;
1093         else
1094                 val = 0;
1095         reg84_full[0x12] = val;                 /* 00..1f */
1096         reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1097 }
1098
1099 /* sensor != ov76xx */
1100 static void setbrightness(struct gspca_dev *gspca_dev)
1101 {
1102         struct sd *sd = (struct sd *) gspca_dev;
1103         unsigned int expo;
1104         __u8 k2;
1105
1106         k2 = sd->brightness >> 10;
1107         switch (sd->sensor) {
1108         case SENSOR_HV7131R:
1109                 expo = sd->brightness << 4;
1110                 if (expo > 0x002dc6c0)
1111                         expo = 0x002dc6c0;
1112                 else if (expo < 0x02a0)
1113                         expo = 0x02a0;
1114                 sd->exposure = setexposure(gspca_dev, expo);
1115                 break;
1116         case SENSOR_MI0360:
1117         case SENSOR_MO4000:
1118                 expo = sd->brightness >> 4;
1119                 sd->exposure = setexposure(gspca_dev, expo);
1120                 break;
1121         case SENSOR_OM6802:
1122                 expo = sd->brightness >> 6;
1123                 sd->exposure = setexposure(gspca_dev, expo);
1124                 k2 = sd->brightness >> 11;
1125                 break;
1126         }
1127
1128         reg_w1(gspca_dev, 0x96, k2);
1129 }
1130
1131 /* sensor != ov76xx */
1132 static void setcontrast(struct gspca_dev *gspca_dev)
1133 {
1134         struct sd *sd = (struct sd *) gspca_dev;
1135         __u8 k2;
1136         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1137
1138         k2 = sd->contrast;
1139         contrast[2] = k2;
1140         contrast[0] = (k2 + 1) >> 1;
1141         contrast[4] = (k2 + 1) / 5;
1142         reg_w(gspca_dev, 0x84, contrast, 6);
1143 }
1144
1145 static void setcolors(struct gspca_dev *gspca_dev)
1146 {
1147         struct sd *sd = (struct sd *) gspca_dev;
1148         __u8 blue, red;
1149
1150         if (sd->colors >= 32) {
1151                 red = 32 + (sd->colors - 32) / 2;
1152                 blue = 64 - sd->colors;
1153         } else {
1154                 red = sd->colors;
1155                 blue = 32 + (32 - sd->colors) / 2;
1156         }
1157         reg_w1(gspca_dev, 0x05, red);
1158 /*      reg_w1(gspca_dev, 0x07, 32); */
1159         reg_w1(gspca_dev, 0x06, blue);
1160 }
1161
1162 static void setautogain(struct gspca_dev *gspca_dev)
1163 {
1164         struct sd *sd = (struct sd *) gspca_dev;
1165
1166         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1167                 return;
1168         if (sd->autogain)
1169                 sd->ag_cnt = AG_CNT_START;
1170         else
1171                 sd->ag_cnt = -1;
1172 }
1173
1174 /* -- start the camera -- */
1175 static void sd_start(struct gspca_dev *gspca_dev)
1176 {
1177         struct sd *sd = (struct sd *) gspca_dev;
1178         int i;
1179         __u8 reg1, reg17, reg18;
1180         const __u8 *sn9c1xx;
1181         int mode;
1182         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1183         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1184         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
1185         static const __u8 CE_ov76xx[] =
1186                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7630/48 */
1187
1188         sn9c1xx = sn_tb[(int) sd->sensor];
1189         configure_gpio(gspca_dev, sn9c1xx);
1190
1191         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1192         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1193         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1194         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1195         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1196         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1197         reg_w1(gspca_dev, 0xd3, 0x50);
1198         reg_w1(gspca_dev, 0xc6, 0x00);
1199         reg_w1(gspca_dev, 0xc7, 0x00);
1200         reg_w1(gspca_dev, 0xc8, 0x50);
1201         reg_w1(gspca_dev, 0xc9, 0x3c);
1202         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1203         switch (sd->sensor) {
1204         case SENSOR_OV7630:
1205                 reg17 = 0xe2;
1206                 break;
1207         case SENSOR_OV7648:
1208                 reg17 = 0xae;
1209                 break;
1210 /*jfm: from win trace */
1211         case SENSOR_OV7660:
1212                 reg17 = 0xa0;
1213                 break;
1214         default:
1215                 reg17 = 0x60;
1216                 break;
1217         }
1218         reg_w1(gspca_dev, 0x17, reg17);
1219         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1220         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1221         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1222         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1223         reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1224         for (i = 0; i < 8; i++)
1225                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1226                 reg_w1(gspca_dev, 0x9a, 0x08);
1227                 reg_w1(gspca_dev, 0x99, 0x59);
1228
1229         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1230         if (mode)
1231                 reg1 = 0x46;    /* 320 clk 48Mhz */
1232         else
1233                 reg1 = 0x06;    /* 640 clk 24Mz */
1234         reg17 = 0x61;
1235         switch (sd->sensor) {
1236         case SENSOR_HV7131R:
1237                 hv7131R_InitSensor(gspca_dev);
1238                 break;
1239         case SENSOR_MI0360:
1240                 mi0360_InitSensor(gspca_dev);
1241                 break;
1242         case SENSOR_MO4000:
1243                 mo4000_InitSensor(gspca_dev);
1244                 if (mode) {
1245 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1246                         reg1 = 0x06;    /* clk 24Mz */
1247                 } else {
1248                         reg17 = 0x22;   /* 640 MCKSIZE */
1249 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1250                 }
1251                 break;
1252         case SENSOR_OM6802:
1253                 om6802_InitSensor(gspca_dev);
1254                 reg17 = 0x64;           /* 640 MCKSIZE */
1255                 break;
1256         case SENSOR_OV7630:
1257                 ov7630_InitSensor(gspca_dev);
1258                 reg17 = 0xe2;
1259                 reg1 = 0x44;
1260                 break;
1261         case SENSOR_OV7648:
1262                 ov7648_InitSensor(gspca_dev);
1263                 reg17 = 0xa2;
1264                 reg1 = 0x44;
1265 /*              if (mode)
1266                         ;                * 320x2...
1267                 else
1268                         ;                * 640x... */
1269                 break;
1270         default:
1271 /*      case SENSOR_OV7660: */
1272                 ov7660_InitSensor(gspca_dev);
1273                 if (mode) {
1274 /*                      reg17 = 0x21;    * 320 */
1275 /*                      reg1 = 0x44; */
1276 /*                      reg1 = 0x46;    (done) */
1277                 } else {
1278                         reg17 = 0x22;   /* 640 MCKSIZE */
1279                         reg1 = 0x06;
1280                 }
1281                 break;
1282         }
1283         reg_w(gspca_dev, 0xc0, C0, 6);
1284         reg_w(gspca_dev, 0xca, CA, 4);
1285         switch (sd->sensor) {
1286         case SENSOR_OV7630:
1287         case SENSOR_OV7648:
1288                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1289                 break;
1290         default:
1291                 reg_w(gspca_dev, 0xce, CE, 4);
1292                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1293                 break;
1294         }
1295
1296         /* here change size mode 0 -> VGA; 1 -> CIF */
1297         reg18 = sn9c1xx[0x18] | (mode << 4);
1298         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1299
1300         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1301         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1302
1303         reg_w1(gspca_dev, 0x18, reg18);
1304
1305         reg_w1(gspca_dev, 0x17, reg17);
1306         switch (sd->sensor) {
1307         case SENSOR_HV7131R:
1308         case SENSOR_MI0360:
1309         case SENSOR_MO4000:
1310         case SENSOR_OM6802:
1311                 setbrightness(gspca_dev);
1312                 setcontrast(gspca_dev);
1313                 break;
1314         default:                        /* OV76xx */
1315                 setbrightcont(gspca_dev);
1316                 break;
1317         }
1318         setautogain(gspca_dev);
1319         reg_w1(gspca_dev, 0x01, reg1);
1320 }
1321
1322 static void sd_stopN(struct gspca_dev *gspca_dev)
1323 {
1324         struct sd *sd = (struct sd *) gspca_dev;
1325         static const __u8 stophv7131[] =
1326                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1327         static const __u8 stopmi0360[] =
1328                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1329         __u8 data;
1330         const __u8 *sn9c1xx;
1331
1332         data = 0x0b;
1333         switch (sd->sensor) {
1334         case SENSOR_HV7131R:
1335                 i2c_w8(gspca_dev, stophv7131);
1336                 data = 0x2b;
1337                 break;
1338         case SENSOR_MI0360:
1339                 i2c_w8(gspca_dev, stopmi0360);
1340                 data = 0x29;
1341                 break;
1342         case SENSOR_OV7630:
1343         case SENSOR_OV7648:
1344                 data = 0x29;
1345                 break;
1346         default:
1347 /*      case SENSOR_MO4000: */
1348 /*      case SENSOR_OV7660: */
1349                 break;
1350         }
1351         sn9c1xx = sn_tb[(int) sd->sensor];
1352         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1353         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1354         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1355         reg_w1(gspca_dev, 0x01, data);
1356         reg_w1(gspca_dev, 0xf1, 0x00);
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         .init = sd_init,
1547         .start = sd_start,
1548         .stopN = sd_stopN,
1549         .pkt_scan = sd_pkt_scan,
1550         .dq_callback = do_autogain,
1551 };
1552
1553 /* -- module initialisation -- */
1554 #define BSI(bridge, sensor, i2c_addr) \
1555         .driver_info = (BRIDGE_ ## bridge << 16) \
1556                         | (SENSOR_ ## sensor << 8) \
1557                         | (i2c_addr)
1558 static const __devinitdata struct usb_device_id device_table[] = {
1559 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1560         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1561         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1562         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1563         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1564         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1565 #endif
1566         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1567         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1568 /* bw600.inf:
1569         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1570 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1571 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1572         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1573 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1574         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1575 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1576 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1577         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1578 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1579 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1580         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1581         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1582 /*      {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1583 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1584 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1585 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1586         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1587 /*bw600.inf:*/
1588         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1589         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1590         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1591 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1592 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1593         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1594 #endif
1595         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1596 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
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 #ifdef CONFIG_PM
1621         .suspend = gspca_suspend,
1622         .resume = gspca_resume,
1623 #endif
1624 };
1625
1626 /* -- module insert / remove -- */
1627 static int __init sd_mod_init(void)
1628 {
1629         if (usb_register(&sd_driver) < 0)
1630                 return -1;
1631         info("registered");
1632         return 0;
1633 }
1634 static void __exit sd_mod_exit(void)
1635 {
1636         usb_deregister(&sd_driver);
1637         info("deregistered");
1638 }
1639
1640 module_init(sd_mod_init);
1641 module_exit(sd_mod_exit);