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