]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixj.c
v4l-dvb: remove legacy checks to allow support for kernels < 2.6.10
[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, 5)
28 static const char version[] = "2.1.5";
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 static void reg_r(struct usb_device *dev,
516                   __u16 value,
517                   __u8 *buffer, int len)
518 {
519         usb_control_msg(dev,
520                         usb_rcvctrlpipe(dev, 0),
521                         0,
522                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
523                         value, 0,
524                         buffer, len,
525                         500);
526 }
527
528 static void reg_w(struct usb_device *dev,
529                           __u16 value,
530                           const __u8 *buffer,
531                           int len)
532 {
533         if (len < 16) {
534                 __u8 tmpbuf[16];
535
536                 memcpy(tmpbuf, buffer, len);
537                 usb_control_msg(dev,
538                                 usb_sndctrlpipe(dev, 0),
539                                 0x08,
540                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
541                                 value, 0,
542                                 tmpbuf, len,
543                                 500);
544         } else {
545                 __u8 *tmpbuf;
546
547                 tmpbuf = kmalloc(len, GFP_KERNEL);
548                 memcpy(tmpbuf, buffer, len);
549                 usb_control_msg(dev,
550                                 usb_sndctrlpipe(dev, 0),
551                                 0x08,
552                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
553                                 value, 0,
554                                 tmpbuf, len,
555                                 500);
556                 kfree(tmpbuf);
557         }
558 }
559
560 /* write 2 bytes */
561 static void i2c_w2(struct gspca_dev *gspca_dev,
562                    const __u8 *buffer)
563 {
564         struct sd *sd = (struct sd *) gspca_dev;
565         struct usb_device *dev = gspca_dev->dev;
566         __u8 mode[8];
567
568         /* is i2c ready */
569         mode[0] = sd->i2c_ctrl_reg | (2 << 4);
570         mode[1] = sd->i2c_base;
571         mode[2] = buffer[0];
572         mode[3] = buffer[1];
573         mode[4] = 0;
574         mode[5] = 0;
575         mode[6] = 0;
576         mode[7] = 0x10;
577         reg_w(dev, 0x08, mode, 8);
578 }
579
580 /* write 8 bytes */
581 static void i2c_w8(struct usb_device *dev, const __u8 *buffer)
582 {
583         reg_w(dev, 0x08, buffer, 8);
584         msleep(1);
585 }
586
587 /* read 5 bytes */
588 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg,
589                    __u8 *buffer)
590 {
591         struct sd *sd = (struct sd *) gspca_dev;
592         struct usb_device *dev = gspca_dev->dev;
593         __u8 mode[8];
594
595         mode[0] = sd->i2c_ctrl_reg | 0x10;
596         mode[1] = sd->i2c_base;
597         mode[2] = reg;
598         mode[3] = 0;
599         mode[4] = 0;
600         mode[5] = 0;
601         mode[6] = 0;
602         mode[7] = 0x10;
603         i2c_w8(dev, mode);
604         mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02;
605         mode[2] = 0;
606         i2c_w8(dev, mode);
607         reg_r(dev, 0x0a, buffer, 5);
608 }
609
610 static int probesensor(struct gspca_dev *gspca_dev)
611 {
612         struct sd *sd = (struct sd *) gspca_dev;
613         struct usb_device *dev = gspca_dev->dev;
614         __u8 reg02;
615         static const __u8 datasend[] = { 2, 0 };
616         /* reg val1 val2 val3 val4 */
617         __u8 datarecd[6];
618
619         i2c_w2(gspca_dev, datasend);
620 /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
621         msleep(10);
622         reg02 = 0x66;
623         reg_w(dev, 0x02, &reg02, 1);            /* Gpio on */
624         msleep(10);
625         i2c_r5(gspca_dev, 0, datarecd);         /* read sensor id */
626         if (datarecd[0] == 0x02
627             && datarecd[1] == 0x09
628             && datarecd[2] == 0x01
629             && datarecd[3] == 0x00
630             && datarecd[4] == 0x00) {
631                 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
632                 sd->sensor = SENSOR_HV7131R;
633                 return SENSOR_HV7131R;
634         }
635         PDEBUG(D_PROBE, "Find Sensor %d %d %d",
636                 datarecd[0], datarecd[1], datarecd[2]);
637         PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
638         return -ENODEV;
639 }
640
641 static int configure_gpio(struct gspca_dev *gspca_dev,
642                           const __u8 *sn9c1xx)
643 {
644         struct sd *sd = (struct sd *) gspca_dev;
645         struct usb_device *dev = gspca_dev->dev;
646         __u8 data;
647         __u8 regF1;
648         const __u8 *reg9a;
649         static const __u8 reg9a_def[] =
650                 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
651         static const __u8 reg9a_sn9c120[] =             /* from win trace */
652                 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
653         static const __u8 reg9a_sn9c325[] =
654                 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
655
656
657         regF1 = 0x00;
658         reg_w(dev, 0xf1, &regF1, 1);
659
660         reg_w(dev, 0x01, &sn9c1xx[0], 1);       /*fixme:jfm was [1] en v1*/
661
662         /* configure gpio */
663         reg_w(dev, 0x01, &sn9c1xx[1], 2);
664         reg_w(dev, 0x08, &sn9c1xx[8], 2);
665         reg_w(dev, 0x17, &sn9c1xx[0x17], 3);
666         switch (sd->customid) {
667         case SN9C325:
668                 reg9a = reg9a_sn9c325;
669                 break;
670         case SN9C120:
671                 reg9a = reg9a_sn9c120;
672                 break;
673         default:
674                 reg9a = reg9a_def;
675                 break;
676         }
677         reg_w(dev, 0x9a, reg9a, 6);
678
679         data = 0x60;                            /*fixme:jfm 60 00 00 (3) */
680         reg_w(dev, 0xd4, &data, 1);
681
682         reg_w(dev, 0x03, &sn9c1xx[3], 0x0f);
683
684         switch (sd->customid) {
685         case SN9C120:                           /* from win trace */
686                 data = 0x61;
687                 reg_w(dev, 0x01, &data, 1);
688                 data = 0x20;
689                 reg_w(dev, 0x17, &data, 1);
690                 data = 0x60;
691                 reg_w(dev, 0x01, &data, 1);
692                 break;
693         case SN9C325:
694                 data = 0x43;
695                 reg_w(dev, 0x01, &data, 1);
696                 data = 0xae;
697                 reg_w(dev, 0x17, &data, 1);
698                 data = 0x42;
699                 reg_w(dev, 0x01, &data, 1);
700                 break;
701         default:
702                 data = 0x43;
703                 reg_w(dev, 0x01, &data, 1);
704                 data = 0x61;
705                 reg_w(dev, 0x17, &data, 1);
706                 data = 0x42;
707                 reg_w(dev, 0x01, &data, 1);
708         }
709
710         if (sd->sensor == SENSOR_HV7131R) {
711                 if (probesensor(gspca_dev) < 0)
712                         return -ENODEV;
713         }
714         return 0;
715 }
716
717 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
718 {
719         int i = 0;
720         struct usb_device *dev = gspca_dev->dev;
721         static const __u8 SetSensorClk[] =      /* 0x08 Mclk */
722                 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
723
724         while (hv7131r_sensor_init[i][0]) {
725                 i2c_w8(dev, hv7131r_sensor_init[i]);
726                 i++;
727         }
728         i2c_w8(dev, SetSensorClk);
729 }
730
731 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
732 {
733         int i = 0;
734         struct usb_device *dev = gspca_dev->dev;
735
736         while (mi0360_sensor_init[i][0]) {
737                 i2c_w8(dev, mi0360_sensor_init[i]);
738                 i++;
739         }
740 }
741
742 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
743 {
744         int i = 0;
745         struct usb_device *dev = gspca_dev->dev;
746
747         while (mo4000_sensor_init[i][0]) {
748                 i2c_w8(dev, mo4000_sensor_init[i]);
749                 i++;
750         }
751 }
752
753 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
754 {
755         struct usb_device *dev = gspca_dev->dev;
756         int i = 0;
757
758         while (ov7648_sensor_init[i][0]) {
759                 i2c_w8(dev, ov7648_sensor_init[i]);
760                 i++;
761         }
762 }
763
764 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
765 {
766         int i = 0;
767         struct usb_device *dev = gspca_dev->dev;
768
769         while (ov7660_sensor_init[i][0]) {
770                 i2c_w8(dev, ov7660_sensor_init[i]);
771                 i++;
772         }
773 }
774
775 /* this function is called at probe time */
776 static int sd_config(struct gspca_dev *gspca_dev,
777                         const struct usb_device_id *id)
778 {
779         struct sd *sd = (struct sd *) gspca_dev;
780         struct cam *cam;
781         __u16 vendor;
782         __u16 product;
783
784         vendor = id->idVendor;
785         product = id->idProduct;
786         sd->sensor = -1;
787         switch (vendor) {
788         case 0x0458:                            /* Genius */
789 /*              switch (product) {
790                 case 0x7025: */
791                         sd->customid = SN9C120;
792                         sd->sensor = SENSOR_MI0360;
793                         sd->i2c_ctrl_reg = 0x81;
794                         sd->i2c_base = 0x5d;
795 /*                      break;
796                 } */
797                 break;
798         case 0x045e:
799 /*              switch (product) {
800                 case 0x00f5:
801                 case 0x00f7: */
802                         sd->customid = SN9C105;
803                         sd->sensor = SENSOR_OV7660;
804                         sd->i2c_ctrl_reg = 0x81;
805                         sd->i2c_base = 0x21;
806 /*                      break;
807                 } */
808                 break;
809         case 0x0471:                            /* Philips */
810 /*              switch (product) {
811                 case 0x0327:
812                 case 0x0328:
813                 case 0x0330: */
814                         sd->customid = SN9C105;
815                         sd->sensor = SENSOR_MI0360;
816                         sd->i2c_ctrl_reg = 0x81;
817                         sd->i2c_base = 0x5d;
818 /*                      break;
819                 } */
820                 break;
821         case 0x0c45:                            /* Sonix */
822                 switch (product) {
823                 case 0x6040:
824                         sd->customid = SN9C102P;
825                         sd->sensor = SENSOR_MI0360;     /* from BW600.inf */
826 /*                      sd->sensor = SENSOR_HV7131R;     * gspcav1 value */
827                         sd->i2c_ctrl_reg = 0x81;
828                         sd->i2c_base = 0x11;
829                         break;
830 /*              case 0x607a:                            * from BW600.inf
831                         sd->customid = SN9C102P;
832                         sd->sensor = SENSOR_OV7648;
833                         sd->i2c_ctrl_reg = 0x??;
834                         sd->i2c_base = 0x??;
835                         break; */
836                 case 0x607c:
837                         sd->customid = SN9C102P;
838                         sd->sensor = SENSOR_HV7131R;
839                         sd->i2c_ctrl_reg = 0x81;
840                         sd->i2c_base = 0x11;
841                         break;
842 /*              case 0x607e:                            * from BW600.inf
843                         sd->customid = SN9C102P;
844                         sd->sensor = SENSOR_OV7630;
845                         sd->i2c_ctrl_reg = 0x??;
846                         sd->i2c_base = 0x??;
847                         break; */
848                 case 0x60c0:
849                         sd->customid = SN9C105;
850                         sd->sensor = SENSOR_MI0360;
851                         sd->i2c_ctrl_reg = 0x81;
852                         sd->i2c_base = 0x5d;
853                         break;
854 /*              case 0x60c8:                            * from BW600.inf
855                         sd->customid = SN9C105;
856                         sd->sensor = SENSOR_OM6801;
857                         sd->i2c_ctrl_reg = 0x??;
858                         sd->i2c_base = 0x??;
859                         break; */
860 /*              case 0x60cc:                            * from BW600.inf
861                         sd->customid = SN9C105;
862                         sd->sensor = SENSOR_HV7131GP;
863                         sd->i2c_ctrl_reg = 0x??;
864                         sd->i2c_base = 0x??;
865                         break; */
866                 case 0x60ec:
867                         sd->customid = SN9C105;
868                         sd->sensor = SENSOR_MO4000;
869                         sd->i2c_ctrl_reg = 0x81;
870                         sd->i2c_base = 0x21;
871                         break;
872 /*              case 0x60ef:                            * from BW600.inf
873                         sd->customid = SN9C105;
874                         sd->sensor = SENSOR_ICM105C;
875                         sd->i2c_ctrl_reg = 0x??;
876                         sd->i2c_base = 0x??;
877                         break; */
878 /*              case 0x60fa:                            * from BW600.inf
879                         sd->customid = SN9C105;
880                         sd->sensor = SENSOR_OV7648;
881                         sd->i2c_ctrl_reg = 0x??;
882                         sd->i2c_base = 0x??;
883                         break; */
884                 case 0x60fb:
885                         sd->customid = SN9C105;
886                         sd->sensor = SENSOR_OV7660;
887                         sd->i2c_ctrl_reg = 0x81;
888                         sd->i2c_base = 0x21;
889                         break;
890                 case 0x60fc:
891                         sd->customid = SN9C105;
892                         sd->sensor = SENSOR_HV7131R;
893                         sd->i2c_ctrl_reg = 0x81;
894                         sd->i2c_base = 0x11;
895                         break;
896 /*              case 0x60fe:                            * from BW600.inf
897                         sd->customid = SN9C105;
898                         sd->sensor = SENSOR_OV7630;
899                         sd->i2c_ctrl_reg = 0x??;
900                         sd->i2c_base = 0x??;
901                         break; */
902 /*              case 0x6108:                            * from BW600.inf
903                         sd->customid = SN9C120;
904                         sd->sensor = SENSOR_OM6801;
905                         sd->i2c_ctrl_reg = 0x??;
906                         sd->i2c_base = 0x??;
907                         break; */
908 /*              case 0x6122:                            * from BW600.inf
909                         sd->customid = SN9C110;
910                         sd->sensor = SENSOR_ICM105C;
911                         sd->i2c_ctrl_reg = 0x??;
912                         sd->i2c_base = 0x??;
913                         break; */
914                 case 0x612a:
915 /*                      sd->customid = SN9C110;          * in BW600.inf */
916                         sd->customid = SN9C325;
917                         sd->sensor = SENSOR_OV7648;
918                         sd->i2c_ctrl_reg = 0x81;
919                         sd->i2c_base = 0x21;
920                         break;
921 /*              case 0x6123:                            * from BW600.inf
922                         sd->customid = SN9C110;
923                         sd->sensor = SENSOR_SanyoCCD;
924                         sd->i2c_ctrl_reg = 0x??;
925                         sd->i2c_base = 0x??;
926                         break; */
927                 case 0x612c:
928                         sd->customid = SN9C110;
929                         sd->sensor = SENSOR_MO4000;
930                         sd->i2c_ctrl_reg = 0x81;
931                         sd->i2c_base = 0x21;
932                         break;
933 /*              case 0x612e:                            * from BW600.inf
934                         sd->customid = SN9C110;
935                         sd->sensor = SENSOR_OV7630;
936                         sd->i2c_ctrl_reg = 0x??;
937                         sd->i2c_base = 0x??;
938                         break; */
939 /*              case 0x612f:                            * from BW600.inf
940                         sd->customid = SN9C110;
941                         sd->sensor = SENSOR_ICM105C;
942                         sd->i2c_ctrl_reg = 0x??;
943                         sd->i2c_base = 0x??;
944                         break; */
945                 case 0x6130:
946                         sd->customid = SN9C120;
947                         sd->sensor = SENSOR_MI0360;
948                         sd->i2c_ctrl_reg = 0x81;
949                         sd->i2c_base = 0x5d;
950                         break;
951                 case 0x6138:
952                         sd->customid = SN9C120;
953                         sd->sensor = SENSOR_MO4000;
954                         sd->i2c_ctrl_reg = 0x81;
955                         sd->i2c_base = 0x21;
956                         break;
957 /*              case 0x613a:                            * from BW600.inf
958                         sd->customid = SN9C120;
959                         sd->sensor = SENSOR_OV7648;
960                         sd->i2c_ctrl_reg = 0x??;
961                         sd->i2c_base = 0x??;
962                         break; */
963                 case 0x613b:
964                         sd->customid = SN9C120;
965                         sd->sensor = SENSOR_OV7660;
966                         sd->i2c_ctrl_reg = 0x81;
967                         sd->i2c_base = 0x21;
968                         break;
969                 case 0x613c:
970                         sd->customid = SN9C120;
971                         sd->sensor = SENSOR_HV7131R;
972                         sd->i2c_ctrl_reg = 0x81;
973                         sd->i2c_base = 0x11;
974                         break;
975 /*              case 0x613e:                            * from BW600.inf
976                         sd->customid = SN9C120;
977                         sd->sensor = SENSOR_OV7630;
978                         sd->i2c_ctrl_reg = 0x??;
979                         sd->i2c_base = 0x??;
980                         break; */
981                 }
982                 break;
983         }
984         if (sd->sensor < 0) {
985                 PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
986                         vendor, product);
987                 return -EINVAL;
988         }
989
990         cam = &gspca_dev->cam;
991         cam->dev_name = (char *) id->driver_info;
992         cam->epaddr = 0x01;
993         cam->cam_mode = vga_mode;
994         cam->nmodes = ARRAY_SIZE(vga_mode);
995
996         sd->qindex = 4;                 /* set the quantization table */
997         sd->brightness = BRIGHTNESS_DEF;
998         sd->contrast = CONTRAST_DEF;
999         sd->colors = COLOR_DEF;
1000         sd->autogain = AUTOGAIN_DEF;
1001         return 0;
1002 }
1003
1004 /* this function is called at open time */
1005 static int sd_open(struct gspca_dev *gspca_dev)
1006 {
1007         struct sd *sd = (struct sd *) gspca_dev;
1008         struct usb_device *dev = gspca_dev->dev;
1009 /*      const __u8 *sn9c1xx; */
1010         __u8 regF1;
1011         __u8 regGpio[] = { 0x29, 0x74 };
1012
1013         /* setup a selector by customid */
1014         regF1 = 0x01;
1015         reg_w(dev, 0xf1, &regF1, 1);
1016         reg_r(dev, 0x00, &regF1, 1);    /* -> regF1 = 0x00 */
1017         reg_w(dev, 0xf1, &regF1, 1);
1018         reg_r(dev, 0x00, &regF1, 1);
1019         switch (sd->customid) {
1020         case SN9C102P:
1021                 if (regF1 != 0x11)
1022                         return -ENODEV;
1023                 reg_w(dev, 0x02, &regGpio[1], 1);
1024                 break;
1025         case SN9C105:
1026                 if (regF1 != 0x11)
1027                         return -ENODEV;
1028                 reg_w(dev, 0x02, regGpio, 2);
1029                 break;
1030         case SN9C110:
1031                 if (regF1 != 0x12)
1032                         return -ENODEV;
1033                 regGpio[1] = 0x62;
1034                 reg_w(dev, 0x02, &regGpio[1], 1);
1035                 break;
1036         case SN9C120:
1037                 if (regF1 != 0x12)
1038                         return -ENODEV;
1039                 regGpio[1] = 0x70;
1040                 reg_w(dev, 0x02, regGpio, 2);
1041                 break;
1042         default:
1043 /*      case SN9C325: */
1044                 if (regF1 != 0x12)
1045                         return -ENODEV;
1046                 regGpio[1] = 0x62;
1047                 reg_w(dev, 0x02, &regGpio[1], 1);
1048                 break;
1049         }
1050
1051         regF1 = 0x01;
1052         reg_w(dev, 0xf1, &regF1, 1);
1053
1054         return 0;
1055 }
1056
1057 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1058                                 unsigned int expo)
1059 {
1060         struct sd *sd = (struct sd *) gspca_dev;
1061         static const __u8 doit[] =              /* update sensor */
1062                 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1063         static const __u8 sensorgo[] =          /* sensor on */
1064                 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1065         static const __u8 gainMo[] =
1066                 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1067
1068         switch (sd->sensor) {
1069         case SENSOR_HV7131R: {
1070                 __u8 Expodoit[] =
1071                         { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1072
1073                 Expodoit[3] = expo >> 16;
1074                 Expodoit[4] = expo >> 8;
1075                 Expodoit[5] = expo;
1076                 i2c_w8(gspca_dev->dev, Expodoit);
1077                 break;
1078             }
1079         case SENSOR_MI0360: {
1080                 __u8 expoMi[] =  /* exposure 0x0635 -> 4 fp/s 0x10 */
1081                         { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1082
1083                 if (expo > 0x0635)
1084                         expo = 0x0635;
1085                 else if (expo < 0x0001)
1086                         expo = 0x0001;
1087                 expoMi[3] = expo >> 8;
1088                 expoMi[4] = expo;
1089                 i2c_w8(gspca_dev->dev, expoMi);
1090                 i2c_w8(gspca_dev->dev, doit);
1091                 i2c_w8(gspca_dev->dev, sensorgo);
1092                 break;
1093             }
1094         case SENSOR_MO4000: {
1095                 __u8 expoMof[] =
1096                         { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1097                 __u8 expoMo10[] =
1098                         { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1099
1100                 if (expo > 0x1fff)
1101                         expo = 0x1fff;
1102                 else if (expo < 0x0001)
1103                         expo = 0x0001;
1104                 expoMof[3] = (expo & 0x03fc) >> 2;
1105                 i2c_w8(gspca_dev->dev, expoMof);
1106                 expoMo10[3] = ((expo & 0x1c00) >> 10)
1107                                 | ((expo & 0x0003) << 4);
1108                 i2c_w8(gspca_dev->dev, expoMo10);
1109                 i2c_w8(gspca_dev->dev, gainMo);
1110                 PDEBUG(D_CONF, "set exposure %d",
1111                         ((expoMo10[3] & 0x07) << 10)
1112                         | (expoMof[3] << 2)
1113                         | ((expoMo10[3] & 0x30) >> 4));
1114                 break;
1115             }
1116         }
1117         return expo;
1118 }
1119
1120 static void setbrightness(struct gspca_dev *gspca_dev)
1121 {
1122         struct sd *sd = (struct sd *) gspca_dev;
1123         unsigned int expo;
1124         __u8 k2;
1125
1126         switch (sd->sensor) {
1127         case SENSOR_HV7131R:
1128                 expo = sd->brightness << 4;
1129                 if (expo > 0x002dc6c0)
1130                         expo = 0x002dc6c0;
1131                 else if (expo < 0x02a0)
1132                         expo = 0x02a0;
1133                 sd->exposure = setexposure(gspca_dev, expo);
1134                 break;
1135         case SENSOR_MI0360:
1136                 expo = sd->brightness >> 4;
1137                 sd->exposure = setexposure(gspca_dev, expo);
1138                 break;
1139         case SENSOR_MO4000:
1140                 expo = sd->brightness >> 4;
1141                 sd->exposure = setexposure(gspca_dev, expo);
1142                 break;
1143         case SENSOR_OV7660:
1144                 return;                         /*jfm??*/
1145         }
1146
1147         k2 = sd->brightness >> 10;
1148         reg_w(gspca_dev->dev, 0x96, &k2, 1);
1149 }
1150
1151 static void setcontrast(struct gspca_dev *gspca_dev)
1152 {
1153         struct sd *sd = (struct sd *) gspca_dev;
1154         __u8 k2;
1155         __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1156
1157         if (sd->sensor == SENSOR_OV7660)
1158                 return;                         /*jfm??*/
1159         k2 = sd->contrast;
1160         contrast[2] = k2;
1161         contrast[0] = (k2 + 1) >> 1;
1162         contrast[4] = (k2 + 1) / 5;
1163         reg_w(gspca_dev->dev, 0x84, contrast, 6);
1164 }
1165
1166 static void setcolors(struct gspca_dev *gspca_dev)
1167 {
1168         struct sd *sd = (struct sd *) gspca_dev;
1169         __u8 data;
1170         int colour;
1171
1172         colour = sd->colors - 128;
1173         if (colour > 0)
1174                 data = (colour + 32) & 0x7f;    /* blue */
1175         else
1176                 data = (-colour + 32) & 0x7f;   /* red */
1177         reg_w(gspca_dev->dev, 0x05, &data, 1);
1178 }
1179
1180 /* -- start the camera -- */
1181 static void sd_start(struct gspca_dev *gspca_dev)
1182 {
1183         struct sd *sd = (struct sd *) gspca_dev;
1184         struct usb_device *dev = gspca_dev->dev;
1185         int i;
1186         __u8 data;
1187         __u8 reg1;
1188         __u8 reg17;
1189         const __u8 *sn9c1xx;
1190         int mode;
1191         static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
1192         static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1193         static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1194         static const __u8 CA_sn9c120[] =
1195                                  { 0x14, 0xec, 0x0a, 0xf6 };    /* SN9C120 */
1196         static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };    /* MI0360 */
1197         static const __u8 CE_sn9c325[] =
1198                         { 0x32, 0xdd, 0x32, 0xdd };     /* OV7648 - SN9C325 */
1199
1200         sn9c1xx = sn_tb[(int) sd->sensor];
1201         configure_gpio(gspca_dev, sn9c1xx);
1202
1203 /*fixme:jfm this sequence should appear at end of sd_start */
1204 /* with
1205         data = 0x44;
1206         reg_w(dev, 0x01, &data, 1); */
1207         reg_w(dev, 0x15, &sn9c1xx[0x15], 1);
1208         reg_w(dev, 0x16, &sn9c1xx[0x16], 1);
1209         reg_w(dev, 0x12, &sn9c1xx[0x12], 1);
1210         reg_w(dev, 0x13, &sn9c1xx[0x13], 1);
1211         reg_w(dev, 0x18, &sn9c1xx[0x18], 1);
1212         reg_w(dev, 0xd2, &DC29[0], 1);
1213         reg_w(dev, 0xd3, &DC29[1], 1);
1214         reg_w(dev, 0xc6, &DC29[2], 1);
1215         reg_w(dev, 0xc7, &DC29[3], 1);
1216         reg_w(dev, 0xc8, &DC29[4], 1);
1217         reg_w(dev, 0xc9, &DC29[5], 1);
1218 /*fixme:jfm end of ending sequence */
1219         reg_w(dev, 0x18, &sn9c1xx[0x18], 1);
1220         if (sd->customid == SN9C325)
1221                 data = 0xae;
1222         else
1223                 data = 0x60;
1224         reg_w(dev, 0x17, &data, 1);
1225         reg_w(dev, 0x05, &sn9c1xx[5], 1);
1226         reg_w(dev, 0x07, &sn9c1xx[7], 1);
1227         reg_w(dev, 0x06, &sn9c1xx[6], 1);
1228         reg_w(dev, 0x14, &sn9c1xx[0x14], 1);
1229         if (sd->customid == SN9C325) {
1230                 reg_w(dev, 0x20, regsn20_sn9c325, 0x11);
1231                 for (i = 0; i < 8; i++)
1232                         reg_w(dev, 0x84, reg84_sn9c325, 0x15);
1233                 data = 0x0a;
1234                 reg_w(dev, 0x9a, &data, 1);
1235                 data = 0x60;
1236                 reg_w(dev, 0x99, &data, 1);
1237         } else {
1238                 reg_w(dev, 0x20, regsn20, 0x11);
1239                 for (i = 0; i < 8; i++)
1240                         reg_w(dev, 0x84, reg84, 0x15);
1241                 data = 0x08;
1242                 reg_w(dev, 0x9a, &data, 1);
1243                 data = 0x59;
1244                 reg_w(dev, 0x99, &data, 1);
1245         }
1246
1247         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1248         reg1 = 0x02;
1249         reg17 = 0x61;
1250         switch (sd->sensor) {
1251         case SENSOR_HV7131R:
1252                 hv7131R_InitSensor(gspca_dev);
1253                 if (mode)
1254                         reg1 = 0x46;    /* 320 clk 48Mhz */
1255                 else
1256                         reg1 = 0x06;    /* 640 clk 24Mz */
1257                 break;
1258         case SENSOR_MI0360:
1259                 mi0360_InitSensor(gspca_dev);
1260                 if (mode)
1261                         reg1 = 0x46;    /* 320 clk 48Mhz */
1262                 else
1263                         reg1 = 0x06;    /* 640 clk 24Mz */
1264                 break;
1265         case SENSOR_MO4000:
1266                 mo4000_InitSensor(gspca_dev);
1267                 if (mode) {
1268 /*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1269                         reg1 = 0x06;    /* clk 24Mz */
1270                 } else {
1271                         reg17 = 0x22;   /* 640 MCKSIZE */
1272                         reg1 = 0x06;    /* 640 clk 24Mz */
1273                 }
1274                 break;
1275         case SENSOR_OV7648:
1276                 reg17 = 0xa2;
1277                 reg1 = 0x44;
1278                 ov7648_InitSensor(gspca_dev);
1279 /*              if (mode)
1280                         ;                * 320x2...
1281                 else
1282                         ;                * 640x... */
1283                 break;
1284         default:
1285 /*      case SENSOR_OV7660: */
1286                 ov7660_InitSensor(gspca_dev);
1287                 if (mode) {
1288 /*                      reg17 = 0x21;    * 320 */
1289 /*                      reg1 = 0x44; */
1290                         reg1 = 0x46;
1291                 } else {
1292                         reg17 = 0xa2;   /* 640 */
1293                         reg1 = 0x40;
1294                 }
1295                 break;
1296         }
1297         reg_w(dev, 0xc0, C0, 6);
1298         switch (sd->customid) {
1299         case SN9C120:                   /*jfm ?? */
1300                 reg_w(dev, 0xca, CA_sn9c120, 4);
1301                 break;
1302         default:
1303                 reg_w(dev, 0xca, CA, 4);
1304                 break;
1305         }
1306         switch (sd->customid) {
1307         case SN9C120:                   /*jfm ?? */
1308         case SN9C325:
1309                 reg_w(dev, 0xce, CE_sn9c325, 4);
1310                 break;
1311         default:
1312                 reg_w(dev, 0xce, CE, 4);
1313                                         /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1314                 break;
1315         }
1316
1317         /* here change size mode 0 -> VGA; 1 -> CIF */
1318         data = 0x40 | sn9c1xx[0x18] | (mode << 4);
1319         reg_w(dev, 0x18, &data, 1);
1320
1321         reg_w(dev, 0x100, qtable4, 0x40);
1322         reg_w(dev, 0x140, qtable4 + 0x40, 0x40);
1323
1324         data = sn9c1xx[0x18] | (mode << 4);
1325         reg_w(dev, 0x18, &data, 1);
1326
1327         reg_w(dev, 0x17, &reg17, 1);
1328         reg_w(dev, 0x01, &reg1, 1);
1329         setbrightness(gspca_dev);
1330         setcontrast(gspca_dev);
1331 }
1332
1333 static void sd_stopN(struct gspca_dev *gspca_dev)
1334 {
1335         struct sd *sd = (struct sd *) gspca_dev;
1336         struct usb_device *dev = gspca_dev->dev;
1337         static const __u8 stophv7131[] =
1338                 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1339         static const __u8 stopmi0360[] =
1340                 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1341         __u8 regF1;
1342         __u8 data;
1343         const __u8 *sn9c1xx;
1344
1345         data = 0x0b;
1346         switch (sd->sensor) {
1347         case SENSOR_HV7131R:
1348                 i2c_w8(dev, stophv7131);
1349                 data = 0x2b;
1350                 break;
1351         case SENSOR_MI0360:
1352                 i2c_w8(dev, stopmi0360);
1353                 data = 0x29;
1354                 break;
1355         case SENSOR_MO4000:
1356                 break;
1357         case SENSOR_OV7648:
1358                 data = 0x29;
1359                 break;
1360         default:
1361 /*      case SENSOR_OV7660: */
1362                 break;
1363         }
1364         sn9c1xx = sn_tb[(int) sd->sensor];
1365         reg_w(dev, 0x01, &sn9c1xx[1], 1);
1366         reg_w(dev, 0x17, &sn9c1xx[0x17], 1);
1367         reg_w(dev, 0x01, &sn9c1xx[1], 1);
1368         reg_w(dev, 0x01, &data, 1);
1369         regF1 = 0x01;
1370         reg_w(dev, 0xf1, &regF1, 1);
1371 }
1372
1373 static void sd_stop0(struct gspca_dev *gspca_dev)
1374 {
1375 }
1376
1377 static void sd_close(struct gspca_dev *gspca_dev)
1378 {
1379 }
1380
1381 static void setautogain(struct gspca_dev *gspca_dev)
1382 {
1383         struct sd *sd = (struct sd *) gspca_dev;
1384         /* Thanks S., without your advice, autobright should not work :) */
1385         int delta;
1386         int expotimes = 0;
1387         __u8 luma_mean = 130;
1388         __u8 luma_delta = 20;
1389
1390         delta = sd->avg_lum;
1391         if (delta < luma_mean - luma_delta ||
1392             delta > luma_mean + luma_delta) {
1393                 switch (sd->sensor) {
1394                 case SENSOR_HV7131R:
1395                         expotimes = sd->exposure >> 8;
1396                         expotimes += (luma_mean - delta) >> 4;
1397                         if (expotimes < 0)
1398                                 expotimes = 0;
1399                         sd->exposure = setexposure(gspca_dev,
1400                                         (unsigned int) (expotimes << 8));
1401                         break;
1402                 case SENSOR_MO4000:
1403                 case SENSOR_MI0360:
1404                         expotimes = sd->exposure;
1405                         expotimes += (luma_mean - delta) >> 6;
1406                         if (expotimes < 0)
1407                                 expotimes = 0;
1408                         sd->exposure = setexposure(gspca_dev,
1409                                                    (unsigned int) expotimes);
1410                         setcolors(gspca_dev);
1411                         break;
1412                 }
1413         }
1414 }
1415
1416 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1417                         struct gspca_frame *frame,      /* target */
1418                         __u8 *data,                     /* isoc packet */
1419                         int len)                        /* iso packet length */
1420 {
1421         struct sd *sd = (struct sd *) gspca_dev;
1422         int sof, avg_lum;
1423
1424         sof = len - 64;
1425         if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1426
1427                 /* end of frame */
1428                 gspca_frame_add(gspca_dev, LAST_PACKET,
1429                                 frame, data, sof + 2);
1430                 if (sd->ag_cnt < 0)
1431                         return;
1432                 if (--sd->ag_cnt >= 0)
1433                         return;
1434                 sd->ag_cnt = AG_CNT_START;
1435 /* w1 w2 w3 */
1436 /* w4 w5 w6 */
1437 /* w7 w8 */
1438 /* w4 */
1439                 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1440 /* w6 */
1441                 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1442 /* w2 */
1443                 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1444 /* w8 */
1445                 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1446 /* w5 */
1447                 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1448                 avg_lum >>= 4;
1449                 sd->avg_lum = avg_lum;
1450                 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1451                 setautogain(gspca_dev);
1452                 return;
1453         }
1454         if (gspca_dev->last_packet_type == LAST_PACKET) {
1455
1456                 /* put the JPEG 422 header */
1457                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1458         }
1459         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1460 }
1461
1462 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1463 {
1464         struct sd *sd = (struct sd *) gspca_dev;
1465         __u8 hexpo, mexpo, lexpo;
1466         __u8 expo[6];
1467
1468         switch (sd->sensor) {
1469         case SENSOR_HV7131R:
1470                 /* read sensor exposure */
1471                 i2c_r5(gspca_dev, 0x25, expo);
1472                 return (expo[0] << 16) | (expo[1] << 8) | expo[2];
1473         case SENSOR_MI0360:
1474                 /* read sensor exposure */
1475                 i2c_r5(gspca_dev, 0x09, expo);
1476                 return (expo[0] << 8) | expo[1];
1477         case SENSOR_MO4000:
1478                 i2c_r5(gspca_dev, 0x0e, expo);
1479                 hexpo = 0;              /* expo[1] & 0x07; */
1480                 mexpo = 0x40;           /* expo[2] &0xff; */
1481                 lexpo = (expo[1] & 0x30) >> 4;
1482                 PDEBUG(D_CONF, "exposure %d",
1483                         (hexpo << 10) | (mexpo << 2) | lexpo);
1484                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1485         default:
1486 /*      case SENSOR_OV7660: */
1487                 /* read sensor exposure */
1488                 i2c_r5(gspca_dev, 0x04, expo);
1489                 hexpo = expo[3] & 0x2f;
1490                 lexpo = expo[0] & 0x02;
1491                 i2c_r5(gspca_dev, 0x08, expo);
1492                 mexpo = expo[2];
1493                 return (hexpo << 10) | (mexpo << 2) | lexpo;
1494         }
1495 }
1496
1497 static void getbrightness(struct gspca_dev *gspca_dev)
1498 {
1499         struct sd *sd = (struct sd *) gspca_dev;
1500
1501         /* hardcoded registers seem not readable */
1502         switch (sd->sensor) {
1503         case SENSOR_HV7131R:
1504 /*              sd->brightness = 0x7fff; */
1505                 sd->brightness = getexposure(gspca_dev) >> 4;
1506                 break;
1507         case SENSOR_MI0360:
1508                 sd->brightness = getexposure(gspca_dev) << 4;
1509                 break;
1510         case SENSOR_MO4000:
1511 /*              sd->brightness = 0x1fff; */
1512                 sd->brightness = getexposure(gspca_dev) << 4;
1513                 break;
1514         }
1515 }
1516
1517 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1518 {
1519         struct sd *sd = (struct sd *) gspca_dev;
1520
1521         sd->brightness = val;
1522         if (gspca_dev->streaming)
1523                 setbrightness(gspca_dev);
1524         return 0;
1525 }
1526
1527 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1528 {
1529         struct sd *sd = (struct sd *) gspca_dev;
1530
1531         getbrightness(gspca_dev);
1532         *val = sd->brightness;
1533         return 0;
1534 }
1535
1536 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1537 {
1538         struct sd *sd = (struct sd *) gspca_dev;
1539
1540         sd->contrast = val;
1541         if (gspca_dev->streaming)
1542                 setcontrast(gspca_dev);
1543         return 0;
1544 }
1545
1546 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1547 {
1548         struct sd *sd = (struct sd *) gspca_dev;
1549
1550         *val = sd->contrast;
1551         return 0;
1552 }
1553
1554 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1555 {
1556         struct sd *sd = (struct sd *) gspca_dev;
1557
1558         sd->colors = val;
1559         if (gspca_dev->streaming)
1560                 setcolors(gspca_dev);
1561         return 0;
1562 }
1563
1564 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1565 {
1566         struct sd *sd = (struct sd *) gspca_dev;
1567
1568         *val = sd->colors;
1569         return 0;
1570 }
1571
1572 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1573 {
1574         struct sd *sd = (struct sd *) gspca_dev;
1575
1576         sd->autogain = val;
1577         if (val)
1578                 sd->ag_cnt = AG_CNT_START;
1579         else
1580                 sd->ag_cnt = -1;
1581         return 0;
1582 }
1583
1584 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1585 {
1586         struct sd *sd = (struct sd *) gspca_dev;
1587
1588         *val = sd->autogain;
1589         return 0;
1590 }
1591
1592 /* sub-driver description */
1593 static const struct sd_desc sd_desc = {
1594         .name = MODULE_NAME,
1595         .ctrls = sd_ctrls,
1596         .nctrls = ARRAY_SIZE(sd_ctrls),
1597         .config = sd_config,
1598         .open = sd_open,
1599         .start = sd_start,
1600         .stopN = sd_stopN,
1601         .stop0 = sd_stop0,
1602         .close = sd_close,
1603         .pkt_scan = sd_pkt_scan,
1604 };
1605
1606 /* -- module initialisation -- */
1607 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1608 static const __devinitdata struct usb_device_id device_table[] = {
1609         {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
1610         {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
1611         {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
1612         {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
1613         {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
1614         {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
1615         {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
1616         {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
1617         {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
1618         {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
1619         {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
1620         {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
1621         {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
1622         {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
1623         {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
1624         {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
1625         {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
1626         {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
1627         {}
1628 };
1629 MODULE_DEVICE_TABLE(usb, device_table);
1630
1631 /* -- device connect -- */
1632 static int sd_probe(struct usb_interface *intf,
1633                     const struct usb_device_id *id)
1634 {
1635         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1636                                 THIS_MODULE);
1637 }
1638
1639 static struct usb_driver sd_driver = {
1640         .name = MODULE_NAME,
1641         .id_table = device_table,
1642         .probe = sd_probe,
1643         .disconnect = gspca_disconnect,
1644 };
1645
1646 /* -- module insert / remove -- */
1647 static int __init sd_mod_init(void)
1648 {
1649         if (usb_register(&sd_driver) < 0)
1650                 return -1;
1651         info("v%s registered", version);
1652         return 0;
1653 }
1654 static void __exit sd_mod_exit(void)
1655 {
1656         usb_deregister(&sd_driver);
1657         info("deregistered");
1658 }
1659
1660 module_init(sd_mod_init);
1661 module_exit(sd_mod_exit);