]> err.no Git - linux-2.6/blob - drivers/media/video/gspca/sonixj.c
V4L/DVB (8822): gspca: Change some subdriver functions for suspend/resume.
[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         default:
815                 reg_w1(gspca_dev, 0x01, 0x43);
816                 reg_w1(gspca_dev, 0x17, 0x61);
817                 reg_w1(gspca_dev, 0x01, 0x42);
818                 if (sd->sensor == SENSOR_HV7131R) {
819                         if (probesensor(gspca_dev) < 0)
820                                 return -ENODEV;
821                 }
822                 break;
823         }
824         return 0;
825 }
826
827 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
828 {
829         int i = 0;
830         static const __u8 SetSensorClk[] =      /* 0x08 Mclk */
831                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
832
833         while (hv7131r_sensor_init[i][0]) {
834                 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
835                 i++;
836         }
837         i2c_w8(gspca_dev, SetSensorClk);
838 }
839
840 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
841 {
842         int i = 0;
843
844         while (mi0360_sensor_init[i][0]) {
845                 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
846                 i++;
847         }
848 }
849
850 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
851 {
852         int i = 0;
853
854         while (mo4000_sensor_init[i][0]) {
855                 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
856                 i++;
857         }
858 }
859
860 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
861 {
862         int i = 0;
863
864         while (om6802_sensor_init[i][0]) {
865                 i2c_w8(gspca_dev, om6802_sensor_init[i]);
866                 i++;
867         }
868 }
869
870 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
871 {
872         int i = 0;
873
874         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 76 01 */
875         i++;
876         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 (RGB+SRST) */
877         i++;
878         msleep(20);
879         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
880         i++;
881         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 */
882         i++;
883         msleep(20);
884         i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
885         i++;
886 /*jfm:win i2c_r from 00 to 80*/
887
888         while (ov7630_sensor_init[i][0]) {
889                 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
890                 i++;
891         }
892 }
893
894 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
895 {
896         int i = 0;
897
898         while (ov7648_sensor_init[i][0]) {
899                 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
900                 i++;
901         }
902 }
903
904 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
905 {
906         int i = 0;
907
908         i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
909         i++;
910         msleep(20);
911         while (ov7660_sensor_init[i][0]) {
912                 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
913                 i++;
914         }
915 }
916
917 /* this function is called at probe time */
918 static int sd_config(struct gspca_dev *gspca_dev,
919                         const struct usb_device_id *id)
920 {
921         struct sd *sd = (struct sd *) gspca_dev;
922         struct cam *cam;
923
924         cam = &gspca_dev->cam;
925         cam->epaddr = 0x01;
926         cam->cam_mode = vga_mode;
927         cam->nmodes = ARRAY_SIZE(vga_mode);
928
929         sd->bridge = id->driver_info >> 16;
930         sd->sensor = id->driver_info >> 8;
931         sd->i2c_base = id->driver_info;
932
933         sd->qindex = 4;                 /* set the quantization table */
934         sd->brightness = BRIGHTNESS_DEF;
935         sd->contrast = CONTRAST_DEF;
936         sd->colors = COLOR_DEF;
937         sd->autogain = AUTOGAIN_DEF;
938         sd->ag_cnt = -1;
939
940         switch (sd->sensor) {
941         case SENSOR_OV7630:
942         case SENSOR_OV7648:
943         case SENSOR_OV7660:
944                 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
945                 break;
946         }
947
948         return 0;
949 }
950
951 /* this function is called at probe and resume time */
952 static int sd_init(struct gspca_dev *gspca_dev)
953 {
954         struct sd *sd = (struct sd *) gspca_dev;
955 /*      const __u8 *sn9c1xx; */
956         __u8 regGpio[] = { 0x29, 0x74 };
957         __u8 regF1;
958
959         /* setup a selector by bridge */
960         reg_w1(gspca_dev, 0xf1, 0x01);
961         reg_r(gspca_dev, 0x00, 1);
962         reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
963         reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
964         regF1 = gspca_dev->usb_buf[0];
965         PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
966         switch (sd->bridge) {
967         case BRIDGE_SN9C102P:
968                 if (regF1 != 0x11)
969                         return -ENODEV;
970                 reg_w1(gspca_dev, 0x02, regGpio[1]);
971                 break;
972         case BRIDGE_SN9C105:
973                 if (regF1 != 0x11)
974                         return -ENODEV;
975                 reg_w(gspca_dev, 0x02, regGpio, 2);
976                 break;
977         case BRIDGE_SN9C120:
978                 if (regF1 != 0x12)
979                         return -ENODEV;
980                 regGpio[1] = 0x70;
981                 reg_w(gspca_dev, 0x02, regGpio, 2);
982                 break;
983         default:
984 /*      case BRIDGE_SN9C110: */
985 /*      case BRIDGE_SN9C325: */
986                 if (regF1 != 0x12)
987                         return -ENODEV;
988                 reg_w1(gspca_dev, 0x02, 0x62);
989                 break;
990         }
991
992         reg_w1(gspca_dev, 0xf1, 0x01);
993
994         return 0;
995 }
996
997 static unsigned int setexposure(struct gspca_dev *gspca_dev,
998                                 unsigned int expo)
999 {
1000         struct sd *sd = (struct sd *) gspca_dev;
1001         static const __u8 doit[] =              /* update sensor */
1002                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1003         static const __u8 sensorgo[] =          /* sensor on */
1004                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1005         static const __u8 gainMo[] =
1006                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1007
1008         switch (sd->sensor) {
1009         case SENSOR_HV7131R: {
1010                 __u8 Expodoit[] =
1011                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1012
1013                 Expodoit[3] = expo >> 16;
1014                 Expodoit[4] = expo >> 8;
1015                 Expodoit[5] = expo;
1016                 i2c_w8(gspca_dev, Expodoit);
1017                 break;
1018             }
1019         case SENSOR_MI0360: {
1020                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
1021                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1022
1023                 if (expo > 0x0635)
1024                         expo = 0x0635;
1025                 else if (expo < 0x0001)
1026                         expo = 0x0001;
1027                 expoMi[3] = expo >> 8;
1028                 expoMi[4] = expo;
1029                 i2c_w8(gspca_dev, expoMi);
1030                 i2c_w8(gspca_dev, doit);
1031                 i2c_w8(gspca_dev, sensorgo);
1032                 break;
1033             }
1034         case SENSOR_MO4000: {
1035                 __u8 expoMof[] =
1036                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1037                 __u8 expoMo10[] =
1038                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1039
1040                 if (expo > 0x1fff)
1041                         expo = 0x1fff;
1042                 else if (expo < 0x0001)
1043                         expo = 0x0001;
1044                 expoMof[3] = (expo & 0x03fc) >> 2;
1045                 i2c_w8(gspca_dev, expoMof);
1046                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1047                                 | ((expo & 0x0003) << 4);
1048                 i2c_w8(gspca_dev, expoMo10);
1049                 i2c_w8(gspca_dev, gainMo);
1050                 PDEBUG(D_CONF, "set exposure %d",
1051                         ((expoMo10[3] & 0x07) << 10)
1052                         | (expoMof[3] << 2)
1053                         | ((expoMo10[3] & 0x30) >> 4));
1054                 break;
1055             }
1056         case SENSOR_OM6802: {
1057                 __u8 gainOm[] =
1058                         { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1059
1060                 if (expo > 0x03ff)
1061                         expo = 0x03ff;
1062                  if (expo < 0x0001)
1063                         expo = 0x0001;
1064                 gainOm[3] = expo >> 2;
1065                 i2c_w8(gspca_dev, gainOm);
1066                 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1067                 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1068                 break;
1069             }
1070         }
1071         return expo;
1072 }
1073
1074 /* this function is used for sensors o76xx only */
1075 static void setbrightcont(struct gspca_dev *gspca_dev)
1076 {
1077         struct sd *sd = (struct sd *) gspca_dev;
1078         unsigned val;
1079         __u8 reg84_full[13];
1080
1081         memset(reg84_full, 0, sizeof reg84_full);
1082         val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10;        /* 10..30 */
1083         reg84_full[2] = val;
1084         reg84_full[0] = (val + 1) / 2;
1085         reg84_full[4] = (val + 1) / 5;
1086         if (val > BRIGHTNESS_DEF)
1087                 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1088                         / BRIGHTNESS_MAX;
1089         else
1090                 val = 0;
1091         reg84_full[10] = val;                   /* 00..1f */
1092         reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1093 }
1094
1095 /* sensor != ov76xx */
1096 static void setbrightness(struct gspca_dev *gspca_dev)
1097 {
1098         struct sd *sd = (struct sd *) gspca_dev;
1099         unsigned int expo;
1100         __u8 k2;
1101
1102         k2 = sd->brightness >> 10;
1103         switch (sd->sensor) {
1104         case SENSOR_HV7131R:
1105                 expo = sd->brightness << 4;
1106                 if (expo > 0x002dc6c0)
1107                         expo = 0x002dc6c0;
1108                 else if (expo < 0x02a0)
1109                         expo = 0x02a0;
1110                 sd->exposure = setexposure(gspca_dev, expo);
1111                 break;
1112         case SENSOR_MI0360:
1113         case SENSOR_MO4000:
1114                 expo = sd->brightness >> 4;
1115                 sd->exposure = setexposure(gspca_dev, expo);
1116                 break;
1117         case SENSOR_OM6802:
1118                 expo = sd->brightness >> 6;
1119                 sd->exposure = setexposure(gspca_dev, expo);
1120                 k2 = sd->brightness >> 11;
1121                 break;
1122         }
1123
1124         reg_w1(gspca_dev, 0x96, k2);
1125 }
1126
1127 /* sensor != ov76xx */
1128 static void setcontrast(struct gspca_dev *gspca_dev)
1129 {
1130         struct sd *sd = (struct sd *) gspca_dev;
1131         __u8 k2;
1132         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1133
1134         k2 = sd->contrast;
1135         contrast[2] = k2;
1136         contrast[0] = (k2 + 1) >> 1;
1137         contrast[4] = (k2 + 1) / 5;
1138         reg_w(gspca_dev, 0x84, contrast, 6);
1139 }
1140
1141 static void setcolors(struct gspca_dev *gspca_dev)
1142 {
1143         struct sd *sd = (struct sd *) gspca_dev;
1144         __u8 blue, red;
1145
1146         if (sd->colors >= 32) {
1147                 red = 32 + (sd->colors - 32) / 2;
1148                 blue = 64 - sd->colors;
1149         } else {
1150                 red = sd->colors;
1151                 blue = 32 + (32 - sd->colors) / 2;
1152         }
1153         reg_w1(gspca_dev, 0x05, red);
1154 /*      reg_w1(gspca_dev, 0x07, 32); */
1155         reg_w1(gspca_dev, 0x06, blue);
1156 }
1157
1158 static void setautogain(struct gspca_dev *gspca_dev)
1159 {
1160         struct sd *sd = (struct sd *) gspca_dev;
1161
1162         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1163                 return;
1164         if (sd->autogain)
1165                 sd->ag_cnt = AG_CNT_START;
1166         else
1167                 sd->ag_cnt = -1;
1168 }
1169
1170 /* -- start the camera -- */
1171 static void sd_start(struct gspca_dev *gspca_dev)
1172 {
1173         struct sd *sd = (struct sd *) gspca_dev;
1174         int i;
1175         __u8 reg1, reg17, reg18;
1176         const __u8 *sn9c1xx;
1177         int mode;
1178         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1179         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1180         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
1181         static const __u8 CE_ov76xx[] =
1182                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7630/48 */
1183
1184         sn9c1xx = sn_tb[(int) sd->sensor];
1185         configure_gpio(gspca_dev, sn9c1xx);
1186
1187 /*      reg_w1(gspca_dev, 0x01, 0x44);          jfm from win trace*/
1188         reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1189         reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1190         reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1191         reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1192         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1193         reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1194         reg_w1(gspca_dev, 0xd3, 0x50);
1195         reg_w1(gspca_dev, 0xc6, 0x00);
1196         reg_w1(gspca_dev, 0xc7, 0x00);
1197         reg_w1(gspca_dev, 0xc8, 0x50);
1198         reg_w1(gspca_dev, 0xc9, 0x3c);
1199         reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1200         switch (sd->sensor) {
1201         case SENSOR_OV7630:
1202                 reg17 = 0xe2;
1203                 break;
1204         case SENSOR_OV7648:
1205                 reg17 = 0xae;
1206                 break;
1207 /*jfm: from win trace */
1208         case SENSOR_OV7660:
1209                 reg17 = 0xa0;
1210                 break;
1211         default:
1212                 reg17 = 0x60;
1213                 break;
1214         }
1215         reg_w1(gspca_dev, 0x17, reg17);
1216         reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1217         reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1218         reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1219         reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1220         reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1221         for (i = 0; i < 8; i++)
1222                 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1223                 reg_w1(gspca_dev, 0x9a, 0x08);
1224                 reg_w1(gspca_dev, 0x99, 0x59);
1225
1226         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1227         if (mode)
1228                 reg1 = 0x46;    /* 320 clk 48Mhz */
1229         else
1230                 reg1 = 0x06;    /* 640 clk 24Mz */
1231         reg17 = 0x61;
1232         switch (sd->sensor) {
1233         case SENSOR_HV7131R:
1234                 hv7131R_InitSensor(gspca_dev);
1235                 break;
1236         case SENSOR_MI0360:
1237                 mi0360_InitSensor(gspca_dev);
1238                 break;
1239         case SENSOR_MO4000:
1240                 mo4000_InitSensor(gspca_dev);
1241                 if (mode) {
1242 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1243                         reg1 = 0x06;    /* clk 24Mz */
1244                 } else {
1245                         reg17 = 0x22;   /* 640 MCKSIZE */
1246 /*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1247                 }
1248                 break;
1249         case SENSOR_OM6802:
1250                 om6802_InitSensor(gspca_dev);
1251                 reg17 = 0x64;           /* 640 MCKSIZE */
1252                 break;
1253         case SENSOR_OV7630:
1254                 ov7630_InitSensor(gspca_dev);
1255                 reg17 = 0xe2;
1256                 reg1 = 0x44;
1257                 break;
1258         case SENSOR_OV7648:
1259                 ov7648_InitSensor(gspca_dev);
1260                 reg17 = 0xa2;
1261                 reg1 = 0x44;
1262 /*              if (mode)
1263                         ;                * 320x2...
1264                 else
1265                         ;                * 640x... */
1266                 break;
1267         default:
1268 /*      case SENSOR_OV7660: */
1269                 ov7660_InitSensor(gspca_dev);
1270                 if (mode) {
1271 /*                      reg17 = 0x21;    * 320 */
1272 /*                      reg1 = 0x44; */
1273 /*                      reg1 = 0x46;    (done) */
1274                 } else {
1275                         reg17 = 0x22;   /* 640 MCKSIZE */
1276                         reg1 = 0x06;
1277                 }
1278                 break;
1279         }
1280         reg_w(gspca_dev, 0xc0, C0, 6);
1281         reg_w(gspca_dev, 0xca, CA, 4);
1282         switch (sd->sensor) {
1283         case SENSOR_OV7630:
1284         case SENSOR_OV7648:
1285                 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1286                 break;
1287         default:
1288                 reg_w(gspca_dev, 0xce, CE, 4);
1289                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1290                 break;
1291         }
1292
1293         /* here change size mode 0 -> VGA; 1 -> CIF */
1294         reg18 = sn9c1xx[0x18] | (mode << 4);
1295         reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1296
1297         reg_w(gspca_dev, 0x100, qtable4, 0x40);
1298         reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1299
1300         reg_w1(gspca_dev, 0x18, reg18);
1301
1302         reg_w1(gspca_dev, 0x17, reg17);
1303         reg_w1(gspca_dev, 0x01, reg1);
1304         switch (sd->sensor) {
1305         case SENSOR_HV7131R:
1306         case SENSOR_MI0360:
1307         case SENSOR_MO4000:
1308         case SENSOR_OM6802:
1309                 setbrightness(gspca_dev);
1310                 setcontrast(gspca_dev);
1311                 break;
1312         default:                        /* OV76xx */
1313                 setbrightcont(gspca_dev);
1314                 break;
1315         }
1316         setautogain(gspca_dev);
1317 }
1318
1319 static void sd_stopN(struct gspca_dev *gspca_dev)
1320 {
1321         struct sd *sd = (struct sd *) gspca_dev;
1322         static const __u8 stophv7131[] =
1323                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1324         static const __u8 stopmi0360[] =
1325                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1326         __u8 data;
1327         const __u8 *sn9c1xx;
1328
1329         data = 0x0b;
1330         switch (sd->sensor) {
1331         case SENSOR_HV7131R:
1332                 i2c_w8(gspca_dev, stophv7131);
1333                 data = 0x2b;
1334                 break;
1335         case SENSOR_MI0360:
1336                 i2c_w8(gspca_dev, stopmi0360);
1337                 data = 0x29;
1338                 break;
1339         case SENSOR_OV7630:
1340         case SENSOR_OV7648:
1341                 data = 0x29;
1342                 break;
1343         default:
1344 /*      case SENSOR_MO4000: */
1345 /*      case SENSOR_OV7660: */
1346                 break;
1347         }
1348         sn9c1xx = sn_tb[(int) sd->sensor];
1349         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1350         reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1351         reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1352         reg_w1(gspca_dev, 0x01, data);
1353         reg_w1(gspca_dev, 0xf1, 0x00);
1354 }
1355
1356 static void do_autogain(struct gspca_dev *gspca_dev)
1357 {
1358         struct sd *sd = (struct sd *) gspca_dev;
1359         int delta;
1360         int expotimes;
1361         __u8 luma_mean = 130;
1362         __u8 luma_delta = 20;
1363
1364         /* Thanks S., without your advice, autobright should not work :) */
1365         if (sd->ag_cnt < 0)
1366                 return;
1367         if (--sd->ag_cnt >= 0)
1368                 return;
1369         sd->ag_cnt = AG_CNT_START;
1370
1371         delta = atomic_read(&sd->avg_lum);
1372         PDEBUG(D_FRAM, "mean lum %d", delta);
1373         if (delta < luma_mean - luma_delta ||
1374             delta > luma_mean + luma_delta) {
1375                 switch (sd->sensor) {
1376                 case SENSOR_HV7131R:
1377                         expotimes = sd->exposure >> 8;
1378                         expotimes += (luma_mean - delta) >> 4;
1379                         if (expotimes < 0)
1380                                 expotimes = 0;
1381                         sd->exposure = setexposure(gspca_dev,
1382                                         (unsigned int) (expotimes << 8));
1383                         break;
1384                 default:
1385 /*              case SENSOR_MO4000: */
1386 /*              case SENSOR_MI0360: */
1387 /*              case SENSOR_OM6802: */
1388                         expotimes = sd->exposure;
1389                         expotimes += (luma_mean - delta) >> 6;
1390                         if (expotimes < 0)
1391                                 expotimes = 0;
1392                         sd->exposure = setexposure(gspca_dev,
1393                                                    (unsigned int) expotimes);
1394                         setcolors(gspca_dev);
1395                         break;
1396                 }
1397         }
1398 }
1399
1400 /* scan the URB packets */
1401 /* This function is run at interrupt level. */
1402 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1403                         struct gspca_frame *frame,      /* target */
1404                         __u8 *data,                     /* isoc packet */
1405                         int len)                        /* iso packet length */
1406 {
1407         struct sd *sd = (struct sd *) gspca_dev;
1408         int sof, avg_lum;
1409
1410         sof = len - 64;
1411         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1412
1413                 /* end of frame */
1414                 gspca_frame_add(gspca_dev, LAST_PACKET,
1415                                 frame, data, sof + 2);
1416                 if (sd->ag_cnt < 0)
1417                         return;
1418 /* w1 w2 w3 */
1419 /* w4 w5 w6 */
1420 /* w7 w8 */
1421 /* w4 */
1422                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1423 /* w6 */
1424                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1425 /* w2 */
1426                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1427 /* w8 */
1428                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1429 /* w5 */
1430                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1431                 avg_lum >>= 4;
1432                 atomic_set(&sd->avg_lum, avg_lum);
1433                 return;
1434         }
1435         if (gspca_dev->last_packet_type == LAST_PACKET) {
1436
1437                 /* put the JPEG 422 header */
1438                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1439         }
1440         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1441 }
1442
1443 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1444 {
1445         struct sd *sd = (struct sd *) gspca_dev;
1446
1447         sd->brightness = val;
1448         if (gspca_dev->streaming) {
1449                 switch (sd->sensor) {
1450                 case SENSOR_HV7131R:
1451                 case SENSOR_MI0360:
1452                 case SENSOR_MO4000:
1453                 case SENSOR_OM6802:
1454                         setbrightness(gspca_dev);
1455                         break;
1456                 default:                        /* OV76xx */
1457                         setbrightcont(gspca_dev);
1458                         break;
1459                 }
1460         }
1461         return 0;
1462 }
1463
1464 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1465 {
1466         struct sd *sd = (struct sd *) gspca_dev;
1467
1468         *val = sd->brightness;
1469         return 0;
1470 }
1471
1472 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1473 {
1474         struct sd *sd = (struct sd *) gspca_dev;
1475
1476         sd->contrast = val;
1477         if (gspca_dev->streaming) {
1478                 switch (sd->sensor) {
1479                 case SENSOR_HV7131R:
1480                 case SENSOR_MI0360:
1481                 case SENSOR_MO4000:
1482                 case SENSOR_OM6802:
1483                         setcontrast(gspca_dev);
1484                         break;
1485                 default:                        /* OV76xx */
1486                         setbrightcont(gspca_dev);
1487                         break;
1488                 }
1489         }
1490         return 0;
1491 }
1492
1493 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1494 {
1495         struct sd *sd = (struct sd *) gspca_dev;
1496
1497         *val = sd->contrast;
1498         return 0;
1499 }
1500
1501 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1502 {
1503         struct sd *sd = (struct sd *) gspca_dev;
1504
1505         sd->colors = val;
1506         if (gspca_dev->streaming)
1507                 setcolors(gspca_dev);
1508         return 0;
1509 }
1510
1511 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1512 {
1513         struct sd *sd = (struct sd *) gspca_dev;
1514
1515         *val = sd->colors;
1516         return 0;
1517 }
1518
1519 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1520 {
1521         struct sd *sd = (struct sd *) gspca_dev;
1522
1523         sd->autogain = val;
1524         if (gspca_dev->streaming)
1525                 setautogain(gspca_dev);
1526         return 0;
1527 }
1528
1529 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1530 {
1531         struct sd *sd = (struct sd *) gspca_dev;
1532
1533         *val = sd->autogain;
1534         return 0;
1535 }
1536
1537 /* sub-driver description */
1538 static const struct sd_desc sd_desc = {
1539         .name = MODULE_NAME,
1540         .ctrls = sd_ctrls,
1541         .nctrls = ARRAY_SIZE(sd_ctrls),
1542         .config = sd_config,
1543         .init = sd_init,
1544         .start = sd_start,
1545         .stopN = sd_stopN,
1546         .pkt_scan = sd_pkt_scan,
1547         .dq_callback = do_autogain,
1548 };
1549
1550 /* -- module initialisation -- */
1551 #define BSI(bridge, sensor, i2c_addr) \
1552         .driver_info = (BRIDGE_ ## bridge << 16) \
1553                         | (SENSOR_ ## sensor << 8) \
1554                         | (i2c_addr)
1555 static const __devinitdata struct usb_device_id device_table[] = {
1556 #ifndef CONFIG_USB_SN9C102
1557         {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1558         {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1559         {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1560         {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1561         {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1562 #endif
1563         {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1564         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1565 /* bw600.inf:
1566         {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1567 /*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1568 /*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1569         {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1570 /*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1571         {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1572 /*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1573 /*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1574         {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1575 /*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1576 /*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1577         {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1578         {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1579 /*      {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1580 /*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1581 /*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1582 /*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1583         {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1584 /*bw600.inf:*/
1585         {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1586         {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1587         {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1588 /*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1589 #ifndef CONFIG_USB_SN9C102
1590         {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1591         {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1592 /*      {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1593         {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1594         {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1595 /*      {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1596 #endif
1597         {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1598         {}
1599 };
1600 MODULE_DEVICE_TABLE(usb, device_table);
1601
1602 /* -- device connect -- */
1603 static int sd_probe(struct usb_interface *intf,
1604                     const struct usb_device_id *id)
1605 {
1606         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1607                                 THIS_MODULE);
1608 }
1609
1610 static struct usb_driver sd_driver = {
1611         .name = MODULE_NAME,
1612         .id_table = device_table,
1613         .probe = sd_probe,
1614         .disconnect = gspca_disconnect,
1615 #ifdef CONFIG_PM
1616         .suspend = gspca_suspend,
1617         .resume = gspca_resume,
1618 #endif
1619 };
1620
1621 /* -- module insert / remove -- */
1622 static int __init sd_mod_init(void)
1623 {
1624         if (usb_register(&sd_driver) < 0)
1625                 return -1;
1626         info("registered");
1627         return 0;
1628 }
1629 static void __exit sd_mod_exit(void)
1630 {
1631         usb_deregister(&sd_driver);
1632         info("deregistered");
1633 }
1634
1635 module_init(sd_mod_init);
1636 module_exit(sd_mod_exit);