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