V4L/DVB (8360): gspca: Bad initialization of sn9c103 - ov7630.
[linux-2.6] / drivers / media / video / gspca / sonixb.c
1 /*
2  *              sonix sn9c102 (bayer) library
3  *              Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4  * Add Pas106 Stefano Mozzi (C) 2004
5  *
6  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22
23 #define MODULE_NAME "sonixb"
24
25 #include "gspca.h"
26
27 #define DRIVER_VERSION_NUMBER   KERNEL_VERSION(2, 1, 7)
28 static const char version[] = "2.1.7";
29
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SN9C102 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         struct sd_desc sd_desc;         /* our nctrls differ dependend upon the
39                                            sensor, so we use a per cam copy */
40         atomic_t avg_lum;
41
42         unsigned char gain;
43         unsigned char exposure;
44         unsigned char brightness;
45         unsigned char autogain;
46         unsigned char autogain_ignore_frames;
47
48         unsigned char fr_h_sz;          /* size of frame header */
49         char sensor;                    /* Type of image sensor chip */
50         char sensor_has_gain;
51 #define SENSOR_HV7131R 0
52 #define SENSOR_OV6650 1
53 #define SENSOR_OV7630 2
54 #define SENSOR_OV7630_3 3
55 #define SENSOR_PAS106 4
56 #define SENSOR_PAS202 5
57 #define SENSOR_TAS5110 6
58 #define SENSOR_TAS5130CXX 7
59 };
60
61 #define COMP2 0x8f
62 #define COMP 0xc7               /* 0x87 //0x07 */
63 #define COMP1 0xc9              /* 0x89 //0x09 */
64
65 #define MCK_INIT 0x63
66 #define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
67
68 #define SYS_CLK 0x04
69
70 /* We calculate the autogain at the end of the transfer of a frame, at this
71    moment a frame with the old settings is being transmitted, and a frame is
72    being captured with the old settings. So if we adjust the autogain we must
73    ignore atleast the 2 next frames for the new settings to come into effect
74    before doing any other adjustments */
75 #define AUTOGAIN_IGNORE_FRAMES 3
76 #define AUTOGAIN_DEADZONE 1000
77 #define DESIRED_AVG_LUM 7000
78
79 /* V4L2 controls supported by the driver */
80 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
81 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
82 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
88
89 static struct ctrl sd_ctrls[] = {
90         {
91             {
92                 .id      = V4L2_CID_BRIGHTNESS,
93                 .type    = V4L2_CTRL_TYPE_INTEGER,
94                 .name    = "Brightness",
95                 .minimum = 0,
96                 .maximum = 255,
97                 .step    = 1,
98 #define BRIGHTNESS_DEF 127
99                 .default_value = BRIGHTNESS_DEF,
100             },
101             .set = sd_setbrightness,
102             .get = sd_getbrightness,
103         },
104         {
105             {
106                 .id      = V4L2_CID_GAIN,
107                 .type    = V4L2_CTRL_TYPE_INTEGER,
108                 .name    = "Gain",
109                 .minimum = 0,
110                 .maximum = 255,
111                 .step    = 1,
112 #define GAIN_DEF 127
113 #define GAIN_KNEE 200
114                 .default_value = GAIN_DEF,
115             },
116             .set = sd_setgain,
117             .get = sd_getgain,
118         },
119         {
120                 {
121                         .id = V4L2_CID_EXPOSURE,
122                         .type = V4L2_CTRL_TYPE_INTEGER,
123                         .name = "Exposure",
124 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
125 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
126                         .minimum = 0,
127                         .maximum = 255,
128                         .step = 1,
129                         .default_value = EXPOSURE_DEF,
130                         .flags = 0,
131                 },
132                 .set = sd_setexposure,
133                 .get = sd_getexposure,
134         },
135         {
136                 {
137                         .id = V4L2_CID_AUTOGAIN,
138                         .type = V4L2_CTRL_TYPE_BOOLEAN,
139                         .name = "Automatic Gain (and Exposure)",
140                         .minimum = 0,
141                         .maximum = 1,
142                         .step = 1,
143 #define AUTOGAIN_DEF 1
144                         .default_value = AUTOGAIN_DEF,
145                         .flags = 0,
146                 },
147                 .set = sd_setautogain,
148                 .get = sd_getautogain,
149         },
150 };
151
152 static struct v4l2_pix_format vga_mode[] = {
153         {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
154                 .bytesperline = 160,
155                 .sizeimage = 160 * 120,
156                 .colorspace = V4L2_COLORSPACE_SRGB,
157                 .priv = 2},
158         {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
159                 .bytesperline = 320,
160                 .sizeimage = 320 * 240,
161                 .colorspace = V4L2_COLORSPACE_SRGB,
162                 .priv = 1},
163         {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
164                 .bytesperline = 640,
165                 .sizeimage = 640 * 480,
166                 .colorspace = V4L2_COLORSPACE_SRGB,
167                 .priv = 0},
168 };
169 static struct v4l2_pix_format sif_mode[] = {
170         {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
171                 .bytesperline = 176,
172                 .sizeimage = 176 * 144,
173                 .colorspace = V4L2_COLORSPACE_SRGB,
174                 .priv = 1},
175         {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176                 .bytesperline = 352,
177                 .sizeimage = 352 * 288,
178                 .colorspace = V4L2_COLORSPACE_SRGB,
179                 .priv = 0},
180 };
181
182 static const __u8 probe_ov7630[] = {0x08, 0x44};
183
184 static const __u8 initHv7131[] = {
185         0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
186         0x00, 0x00,
187         0x00, 0x00, 0x00, 0x03, 0x01, 0x00,     /* shift from 0x02 0x01 0x00 */
188         0x28, 0x1e, 0x60, 0x8a, 0x20,
189         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
190 };
191 static const __u8 hv7131_sensor_init[][8] = {
192         {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
193         {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
194         {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
195         {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
196         {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
197 };
198 static const __u8 initOv6650[] = {
199         0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
200         0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201         0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
202         0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
203 };
204 static const __u8 ov6650_sensor_init[][8] =
205 {
206         /* Bright, contrast, etc are set througth SCBB interface.
207          * AVCAP on win2 do not send any data on this   controls. */
208         /* Anyway, some registers appears to alter bright and constrat */
209
210         /* Reset sensor */
211         {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
212         /* Set clock register 0x11 low nibble is clock divider */
213         {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
214         /* Next some unknown stuff */
215         {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
216 /*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
217                  * THIS SET GREEN SCREEN
218                  * (pixels could be innverted in decode kind of "brg",
219                  * but blue wont be there. Avoid this data ... */
220         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
221         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
222         {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
223         /* Disable autobright ? */
224         {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10},
225         /* Some more unknown stuff */
226         {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
227         {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
228         {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16},
229         /* Framerate adjust register for artificial light 50 hz flicker
230            compensation, identical to ov6630 0x2b register, see 6630 datasheet.
231            0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
232         {0xa0, 0x60, 0x2b, 0x4f, 0x99, 0x04, 0x94, 0x15},
233 };
234
235 static const __u8 initOv7630[] = {
236         0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
237         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
238         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
239         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
240         0x68, COMP1, MCK_INIT1,                         /* r17 .. r19 */
241         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
242 };
243 static const __u8 initOv7630_3[] = {
244         0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
245         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
246         0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
247         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
248         0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
249         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,       /* r1a .. r20 */
250         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
251         0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
252 };
253 static const __u8 ov7630_sensor_init_com[][8] = {
254         {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
255         {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
256 /*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
257         {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
258         {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
259         {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
260         {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
261         {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
262         {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
263         {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
264         {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
265         {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
266 /*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
267         {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
268         {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
269         {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
270         {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
271         {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
272         {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
273 };
274 static const __u8 ov7630_sensor_init[][8] = {
275         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
276         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10},       /* jfm */
277         {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
278         {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
279         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
280 };
281 static const __u8 ov7630_sensor_init_3[][5][8] = {
282     {   {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16},      /* exposure */
283         {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16},
284         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16},
285         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
286         {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d},
287     },
288     {   {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16},      /* exposure */
289         {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16},
290         {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16},
291         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
292 /*      {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d},
293                 * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */
294 /*      {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d},        * from win */
295         {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d},
296     }
297 };
298
299 static const __u8 initPas106[] = {
300         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
301         0x00, 0x00,
302         0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
303         0x16, 0x12, 0x28, COMP1, MCK_INIT1,
304         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
305 };
306 /* compression 0x86 mckinit1 0x2b */
307 static const __u8 pas106_data[][2] = {
308         {0x02, 0x04},           /* Pixel Clock Divider 6 */
309         {0x03, 0x13},           /* Frame Time MSB */
310 /*      {0x03, 0x12},            * Frame Time MSB */
311         {0x04, 0x06},           /* Frame Time LSB */
312 /*      {0x04, 0x05},            * Frame Time LSB */
313         {0x05, 0x65},           /* Shutter Time Line Offset */
314 /*      {0x05, 0x6d},            * Shutter Time Line Offset */
315 /*      {0x06, 0xb1},            * Shutter Time Pixel Offset */
316         {0x06, 0xcd},           /* Shutter Time Pixel Offset */
317         {0x07, 0xc1},           /* Black Level Subtract Sign */
318 /*      {0x07, 0x00},            * Black Level Subtract Sign */
319         {0x08, 0x06},           /* Black Level Subtract Level */
320         {0x08, 0x06},           /* Black Level Subtract Level */
321 /*      {0x08, 0x01},            * Black Level Subtract Level */
322         {0x09, 0x05},           /* Color Gain B Pixel 5 a */
323         {0x0a, 0x04},           /* Color Gain G1 Pixel 1 5 */
324         {0x0b, 0x04},           /* Color Gain G2 Pixel 1 0 5 */
325         {0x0c, 0x05},           /* Color Gain R Pixel 3 1 */
326         {0x0d, 0x00},           /* Color GainH  Pixel */
327         {0x0e, 0x0e},           /* Global Gain */
328         {0x0f, 0x00},           /* Contrast */
329         {0x10, 0x06},           /* H&V synchro polarity */
330         {0x11, 0x06},           /* ?default */
331         {0x12, 0x06},           /* DAC scale */
332         {0x14, 0x02},           /* ?default */
333         {0x13, 0x01},           /* Validate Settings */
334 };
335 static const __u8 initPas202[] = {
336         0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
337         0x00, 0x00,
338         0x00, 0x00, 0x00, 0x07, 0x03, 0x0a,     /* 6 */
339         0x28, 0x1e, 0x28, 0x89, 0x30,
340         0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
341 };
342 static const __u8 pas202_sensor_init[][8] = {
343         {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
344         {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
345         {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
346         {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
347         {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
348         {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
349         {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
350         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
351         {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
352         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
353         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
354         {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
355
356         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
357         {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
358         {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
359         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
360         {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
361         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
362         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
363         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
364 };
365
366 static const __u8 initTas5110[] = {
367         0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
368         0x00, 0x00,
369         0x00, 0x01, 0x00, 0x46, 0x09, 0x0a,     /* shift from 0x45 0x09 0x0a */
370         0x16, 0x12, 0x60, 0x86, 0x2b,
371         0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
372 };
373 static const __u8 tas5110_sensor_init[][8] = {
374         {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
375         {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
376         {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
377 };
378
379 static const __u8 initTas5130[] = {
380         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
381         0x00, 0x00,
382         0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
383         0x28, 0x1e, 0x60, COMP, MCK_INIT,
384         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
385 };
386 static const __u8 tas5130_sensor_init[][8] = {
387 /*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
388                                         * shutter 0x47 short exposure? */
389         {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
390                                         /* shutter 0x01 long exposure */
391         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
392 };
393
394 /* get one byte in gspca_dev->usb_buf */
395 static void reg_r(struct gspca_dev *gspca_dev,
396                   __u16 value)
397 {
398         usb_control_msg(gspca_dev->dev,
399                         usb_rcvctrlpipe(gspca_dev->dev, 0),
400                         0,                      /* request */
401                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
402                         value,
403                         0,                      /* index */
404                         gspca_dev->usb_buf, 1,
405                         500);
406 }
407
408 static void reg_w(struct gspca_dev *gspca_dev,
409                   __u16 value,
410                   const __u8 *buffer,
411                   int len)
412 {
413 #ifdef CONFIG_VIDEO_ADV_DEBUG
414         if (len > sizeof gspca_dev->usb_buf) {
415                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
416                 return;
417         }
418 #endif
419         memcpy(gspca_dev->usb_buf, buffer, len);
420         usb_control_msg(gspca_dev->dev,
421                         usb_sndctrlpipe(gspca_dev->dev, 0),
422                         0x08,                   /* request */
423                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
424                         value,
425                         0,                      /* index */
426                         gspca_dev->usb_buf, len,
427                         500);
428 }
429
430 static void reg_w_big(struct gspca_dev *gspca_dev,
431                   __u16 value,
432                   const __u8 *buffer,
433                   int len)
434 {
435         __u8 *tmpbuf;
436
437         tmpbuf = kmalloc(len, GFP_KERNEL);
438         memcpy(tmpbuf, buffer, len);
439         usb_control_msg(gspca_dev->dev,
440                         usb_sndctrlpipe(gspca_dev->dev, 0),
441                         0x08,                   /* request */
442                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
443                         value,
444                         0,                      /* index */
445                         tmpbuf, len,
446                         500);
447         kfree(tmpbuf);
448 }
449
450 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
451 {
452         int retry = 60;
453
454         /* is i2c ready */
455         reg_w(gspca_dev, 0x08, buffer, 8);
456         while (retry--) {
457                 msleep(10);
458                 reg_r(gspca_dev, 0x08);
459                 if (gspca_dev->usb_buf[0] == 4)
460                         return 0;
461         }
462         return -1;
463 }
464
465 static void i2c_w_vector(struct gspca_dev *gspca_dev,
466                         const __u8 buffer[][8], int len)
467 {
468         for (;;) {
469                 reg_w(gspca_dev, 0x08, *buffer, 8);
470                 len -= 8;
471                 if (len <= 0)
472                         break;
473                 buffer++;
474         }
475 }
476
477 static void setbrightness(struct gspca_dev *gspca_dev)
478 {
479         struct sd *sd = (struct sd *) gspca_dev;
480         __u8 value;
481
482         switch (sd->sensor) {
483         case SENSOR_OV6650: {
484                 __u8 i2cOV6650[] =
485                         {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
486
487                 i2cOV6650[3] = sd->brightness;
488                 if (i2c_w(gspca_dev, i2cOV6650) < 0)
489                          goto err;
490                 break;
491             }
492         case  SENSOR_OV7630_3:
493         case  SENSOR_OV7630: {
494                 __u8 i2cOV[] =
495                         {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
496
497                 /* change reg 0x06 */
498                 i2cOV[3] = sd->brightness;
499                 if (i2c_w(gspca_dev, i2cOV) < 0)
500                         goto err;
501                 break;
502             }
503         case SENSOR_PAS106: {
504                 __u8 i2c1[] =
505                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
506
507                 i2c1[3] = sd->brightness >> 3;
508                 i2c1[2] = 0x0e;
509                 if (i2c_w(gspca_dev, i2c1) < 0)
510                         goto err;
511                 i2c1[3] = 0x01;
512                 i2c1[2] = 0x13;
513                 if (i2c_w(gspca_dev, i2c1) < 0)
514                         goto err;
515                 break;
516             }
517         case SENSOR_PAS202: {
518                 /* __u8 i2cpexpo1[] =
519                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
520                 __u8 i2cpexpo[] =
521                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
522                 __u8 i2cp202[] =
523                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
524                 static __u8 i2cpdoit[] =
525                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
526
527                 /* change reg 0x10 */
528                 i2cpexpo[4] = 0xff - sd->brightness;
529 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
530                         goto err; */
531 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
532                         goto err; */
533                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
534                         goto err;
535                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
536                         goto err;
537                 i2cp202[3] = sd->brightness >> 3;
538                 if (i2c_w(gspca_dev, i2cp202) < 0)
539                         goto err;
540                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
541                         goto err;
542                 break;
543             }
544         case SENSOR_TAS5130CXX: {
545                 __u8 i2c[] =
546                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
547
548                 value = 0xff - sd->brightness;
549                 i2c[4] = value;
550                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
551                 if (i2c_w(gspca_dev, i2c) < 0)
552                         goto err;
553                 break;
554             }
555         case SENSOR_TAS5110:
556                 /* FIXME figure out howto control brightness on TAS5110 */
557                 break;
558         }
559         return;
560 err:
561         PDEBUG(D_ERR, "i2c error brightness");
562 }
563
564 static void setsensorgain(struct gspca_dev *gspca_dev)
565 {
566         struct sd *sd = (struct sd *) gspca_dev;
567
568         switch (sd->sensor) {
569
570         case SENSOR_TAS5110: {
571                 __u8 i2c[] =
572                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
573
574                 i2c[4] = 255 - sd->gain;
575                 if (i2c_w(gspca_dev, i2c) < 0)
576                         goto err;
577                 break;
578             }
579         case SENSOR_OV6650: {
580                 __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
581
582                 i2c[3] = sd->gain >> 3;
583                 if (i2c_w(gspca_dev, i2c) < 0)
584                         goto err;
585                 break;
586             }
587         case SENSOR_OV7630_3: {
588                 __u8 i2c[] = {0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
589
590                 i2c[3] = sd->gain >> 2;
591                 if (i2c_w(gspca_dev, i2c) < 0)
592                         goto err;
593                 break;
594             }
595         }
596         return;
597 err:
598         PDEBUG(D_ERR, "i2c error gain");
599 }
600
601 static void setgain(struct gspca_dev *gspca_dev)
602 {
603         struct sd *sd = (struct sd *) gspca_dev;
604         __u8 gain;
605         __u8 rgb_value;
606
607         gain = sd->gain >> 4;
608
609         /* red and blue gain */
610         rgb_value = gain << 4 | gain;
611         reg_w(gspca_dev, 0x10, &rgb_value, 1);
612         /* green gain */
613         rgb_value = gain;
614         reg_w(gspca_dev, 0x11, &rgb_value, 1);
615
616         if (sd->sensor_has_gain)
617                 setsensorgain(gspca_dev);
618 }
619
620 static void setexposure(struct gspca_dev *gspca_dev)
621 {
622         struct sd *sd = (struct sd *) gspca_dev;
623
624         switch (sd->sensor) {
625         case SENSOR_TAS5110: {
626                 __u8 reg;
627
628                 /* register 19's high nibble contains the sn9c10x clock divider
629                    The high nibble configures the no fps according to the
630                    formula: 60 / high_nibble. With a maximum of 30 fps */
631                 reg = 120 * sd->exposure / 1000;
632                 if (reg < 2)
633                         reg = 2;
634                 else if (reg > 15)
635                         reg = 15;
636                 reg = (reg << 4) | 0x0b;
637                 reg_w(gspca_dev, 0x19, &reg, 1);
638                 break;
639             }
640         case SENSOR_OV6650: {
641                 /* The ov6650 has 2 registers which both influence exposure,
642                    first there is register 11, whose low nibble sets the no fps
643                    according to: fps = 30 / (low_nibble + 1)
644
645                    The fps configures the maximum exposure setting, but it is
646                    possible to use less exposure then what the fps maximum
647                    allows by setting register 10. register 10 configures the
648                    actual exposure as quotient of the full exposure, with 0
649                    being no exposure at all (not very usefull) and reg10_max
650                    being max exposure possible at that framerate.
651
652                    The code maps our 0 - 510 ms exposure ctrl to these 2
653                    registers, trying to keep fps as high as possible.
654                 */
655                 __u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
656                 int reg10, reg11;
657                 /* No clear idea why, but setting reg10 above this value
658                    results in no change */
659                 const int reg10_max = 0x4d;
660
661                 reg11 = (60 * sd->exposure + 999) / 1000;
662                 if (reg11 < 1)
663                         reg11 = 1;
664                 else if (reg11 > 16)
665                         reg11 = 16;
666
667                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
668                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
669                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
670                 if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
671                         reg10 = 1;
672                 else if (reg10 > reg10_max)
673                         reg10 = reg10_max;
674
675                 /* Write reg 10 and reg11 low nibble */
676                 i2c[3] = reg10;
677                 i2c[4] |= reg11 - 1;
678                 if (i2c_w(gspca_dev, i2c) < 0)
679                         PDEBUG(D_ERR, "i2c error exposure");
680                 break;
681             }
682         case SENSOR_OV7630_3: {
683                 __u8 i2c[] = {0xb0, 0x21, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
684                 int reg10, reg11;
685                 /* No clear idea why, but setting reg10 above this value
686                    results in no change */
687                 const int reg10_max = 0x4d;
688
689                 reg11 = (60 * sd->exposure + 999) / 1000;
690                 if (reg11 < 1)
691                         reg11 = 1;
692                 else if (reg11 > 16)
693                         reg11 = 16;
694
695                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
696                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
697                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
698                 if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
699                         reg10 = 1;
700                 else if (reg10 > reg10_max)
701                         reg10 = reg10_max;
702
703                 /* Write reg 10 and reg11 low nibble */
704                 i2c[3] = reg10;
705                 i2c[4] |= reg11 - 1;
706                 if (i2c_w(gspca_dev, i2c) < 0)
707                         PDEBUG(D_ERR, "i2c error exposure");
708                 break;
709             }
710         }
711 }
712
713
714 static void do_autogain(struct gspca_dev *gspca_dev)
715 {
716         struct sd *sd = (struct sd *) gspca_dev;
717         int avg_lum = atomic_read(&sd->avg_lum);
718
719         if (avg_lum == -1)
720                 return;
721
722         if (sd->autogain_ignore_frames > 0)
723                 sd->autogain_ignore_frames--;
724         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
725                         sd->brightness * DESIRED_AVG_LUM / 127,
726                         AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE))
727                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
728 }
729
730 /* this function is called at probe time */
731 static int sd_config(struct gspca_dev *gspca_dev,
732                         const struct usb_device_id *id)
733 {
734         struct sd *sd = (struct sd *) gspca_dev;
735         struct cam *cam;
736         __u16 product;
737         int sif = 0;
738
739         /* nctrls depends upon the sensor, so we use a per cam copy */
740         memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
741         gspca_dev->sd_desc = &sd->sd_desc;
742
743         sd->fr_h_sz = 12;               /* default size of the frame header */
744         sd->sd_desc.nctrls = 2;         /* default nb of ctrls */
745         sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
746
747         product = id->idProduct;
748 /*      switch (id->idVendor) { */
749 /*      case 0x0c45:                             * Sonix */
750                 switch (product) {
751                 case 0x6001:                    /* SN9C102 */
752                 case 0x6005:                    /* SN9C101 */
753                 case 0x6007:                    /* SN9C101 */
754                         sd->sensor = SENSOR_TAS5110;
755                         sd->sensor_has_gain = 1;
756                         sd->sd_desc.nctrls = 4;
757                         sd->sd_desc.dq_callback = do_autogain;
758                         sif = 1;
759                         break;
760                 case 0x6009:                    /* SN9C101 */
761                 case 0x600d:                    /* SN9C101 */
762                 case 0x6029:                    /* SN9C101 */
763                         sd->sensor = SENSOR_PAS106;
764                         sif = 1;
765                         break;
766                 case 0x6011:                    /* SN9C101 - SN9C101G */
767                         sd->sensor = SENSOR_OV6650;
768                         sd->sensor_has_gain = 1;
769                         sd->sd_desc.nctrls = 4;
770                         sd->sd_desc.dq_callback = do_autogain;
771                         sif = 1;
772                         break;
773                 case 0x6019:                    /* SN9C101 */
774                 case 0x602c:                    /* SN9C102 */
775                 case 0x602e:                    /* SN9C102 */
776                         sd->sensor = SENSOR_OV7630;
777                         break;
778                 case 0x60b0:                    /* SN9C103 */
779                         sd->sensor = SENSOR_OV7630_3;
780                         sd->fr_h_sz = 18;       /* size of frame header */
781                         sd->sensor_has_gain = 1;
782                         sd->sd_desc.nctrls = 4;
783                         sd->sd_desc.dq_callback = do_autogain;
784                         sd->autogain = 0;
785                         break;
786                 case 0x6024:                    /* SN9C102 */
787                 case 0x6025:                    /* SN9C102 */
788                         sd->sensor = SENSOR_TAS5130CXX;
789                         break;
790                 case 0x6028:                    /* SN9C102 */
791                         sd->sensor = SENSOR_PAS202;
792                         break;
793                 case 0x602d:                    /* SN9C102 */
794                         sd->sensor = SENSOR_HV7131R;
795                         break;
796                 case 0x60af:                    /* SN9C103 */
797                         sd->sensor = SENSOR_PAS202;
798                         sd->fr_h_sz = 18;       /* size of frame header (?) */
799                         break;
800                 }
801 /*              break; */
802 /*      } */
803
804         cam = &gspca_dev->cam;
805         cam->dev_name = (char *) id->driver_info;
806         cam->epaddr = 0x01;
807         if (!sif) {
808                 cam->cam_mode = vga_mode;
809                 cam->nmodes = ARRAY_SIZE(vga_mode);
810                 if (sd->sensor == SENSOR_OV7630_3) {
811                         /* We only have 320x240 & 640x480 */
812                         cam->cam_mode++;
813                         cam->nmodes--;
814                 }
815         } else {
816                 cam->cam_mode = sif_mode;
817                 cam->nmodes = ARRAY_SIZE(sif_mode);
818         }
819         sd->brightness = BRIGHTNESS_DEF;
820         sd->gain = GAIN_DEF;
821         sd->exposure = EXPOSURE_DEF;
822         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
823                 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
824         return 0;
825 }
826
827 /* this function is called at open time */
828 static int sd_open(struct gspca_dev *gspca_dev)
829 {
830         reg_r(gspca_dev, 0x00);
831         if (gspca_dev->usb_buf[0] != 0x10)
832                 return -ENODEV;
833         return 0;
834 }
835
836 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
837 {
838         int i;
839         const __u8 *data;
840         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
841
842         i = ARRAY_SIZE(pas106_data);
843         data = pas106_data[0];
844         while (--i >= 0) {
845                 memcpy(&i2c1[2], data, 2);
846                                         /* copy 2 bytes from the template */
847                 if (i2c_w(gspca_dev, i2c1) < 0)
848                         PDEBUG(D_ERR, "i2c error pas106");
849                 data += 2;
850         }
851 }
852
853 /* -- start the camera -- */
854 static void sd_start(struct gspca_dev *gspca_dev)
855 {
856         struct sd *sd = (struct sd *) gspca_dev;
857         int mode, l;
858         const __u8 *sn9c10x;
859         __u8 reg01, reg17;
860         __u8 reg17_19[3];
861
862         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
863         switch (sd->sensor) {
864         case SENSOR_HV7131R:
865                 sn9c10x = initHv7131;
866                 reg17_19[0] = 0x60;
867                 reg17_19[1] = (mode << 4) | 0x8a;
868                 reg17_19[2] = 0x20;
869                 break;
870         case SENSOR_OV6650:
871                 sn9c10x = initOv6650;
872                 reg17_19[0] = 0x68;
873                 reg17_19[1] = (mode << 4) | 0x8b;
874                 reg17_19[2] = 0x20;
875                 break;
876         case SENSOR_OV7630:
877                 sn9c10x = initOv7630;
878                 reg17_19[0] = 0x68;
879                 reg17_19[1] = (mode << 4) | COMP2;
880                 reg17_19[2] = MCK_INIT1;
881                 break;
882         case SENSOR_OV7630_3:
883                 sn9c10x = initOv7630_3;
884                 reg17_19[0] = 0x68;
885                 reg17_19[1] = (mode << 4) | COMP2;
886                 reg17_19[2] = MCK_INIT1;
887                 break;
888         case SENSOR_PAS106:
889                 sn9c10x = initPas106;
890                 reg17_19[0] = 0x24;             /* 0x28 */
891                 reg17_19[1] = (mode << 4) | COMP1;
892                 reg17_19[2] = MCK_INIT1;
893                 break;
894         case SENSOR_PAS202:
895                 sn9c10x = initPas202;
896                 reg17_19[0] = mode ? 0x24 : 0x20;
897                 reg17_19[1] = (mode << 4) | 0x89;
898                 reg17_19[2] = 0x20;
899                 break;
900         case SENSOR_TAS5110:
901                 sn9c10x = initTas5110;
902                 reg17_19[0] = 0x60;
903                 reg17_19[1] = (mode << 4) | 0x86;
904                 reg17_19[2] = 0x2b;             /* 0xf3; */
905                 break;
906         default:
907 /*      case SENSOR_TAS5130CXX: */
908                 sn9c10x = initTas5130;
909                 reg17_19[0] = 0x60;
910                 reg17_19[1] = (mode << 4) | COMP;
911                 reg17_19[2] = mode ? 0x23 : 0x43;
912                 break;
913         }
914         switch (sd->sensor) {
915         case SENSOR_OV7630:
916                 reg01 = 0x06;
917                 reg17 = 0x29;
918                 l = 0x10;
919                 break;
920         case SENSOR_OV7630_3:
921                 reg01 = 0x44;
922                 reg17 = 0x68;
923                 l = sizeof initOv7630_3;
924                 break;
925         default:
926                 reg01 = sn9c10x[0];
927                 reg17 = sn9c10x[0x17 - 1];
928                 l = 0x1f;
929                 break;
930         }
931
932         /* reg 0x01 bit 2 video transfert on */
933         reg_w(gspca_dev, 0x01, &reg01, 1);
934         /* reg 0x17 SensorClk enable inv Clk 0x60 */
935         reg_w(gspca_dev, 0x17, &reg17, 1);
936 /*fixme: for ov7630 102
937         reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
938         /* Set the registers from the template */
939         reg_w_big(gspca_dev, 0x01, sn9c10x, l);
940         switch (sd->sensor) {
941         case SENSOR_HV7131R:
942                 i2c_w_vector(gspca_dev, hv7131_sensor_init,
943                                 sizeof hv7131_sensor_init);
944                 break;
945         case SENSOR_OV6650:
946                 i2c_w_vector(gspca_dev, ov6650_sensor_init,
947                                 sizeof ov6650_sensor_init);
948                 break;
949         case SENSOR_OV7630:
950                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
951                                 sizeof ov7630_sensor_init_com);
952                 msleep(200);
953                 i2c_w_vector(gspca_dev, ov7630_sensor_init,
954                                 sizeof ov7630_sensor_init);
955                 break;
956         case SENSOR_OV7630_3:
957                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
958                                 sizeof ov7630_sensor_init_com);
959                 msleep(200);
960                 i2c_w_vector(gspca_dev, ov7630_sensor_init_3[mode],
961                                 sizeof ov7630_sensor_init_3[mode]);
962                 break;
963         case SENSOR_PAS106:
964                 pas106_i2cinit(gspca_dev);
965                 break;
966         case SENSOR_PAS202:
967                 i2c_w_vector(gspca_dev, pas202_sensor_init,
968                                 sizeof pas202_sensor_init);
969                 break;
970         case SENSOR_TAS5110:
971                 i2c_w_vector(gspca_dev, tas5110_sensor_init,
972                                 sizeof tas5110_sensor_init);
973                 break;
974         default:
975 /*      case SENSOR_TAS5130CXX: */
976                 i2c_w_vector(gspca_dev, tas5130_sensor_init,
977                                 sizeof tas5130_sensor_init);
978                 break;
979         }
980         /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
981         reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
982         /* compression register */
983         reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
984         /* H_start */
985         reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
986         /* V_START */
987         reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
988         /* reset 0x17 SensorClk enable inv Clk 0x60 */
989                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
990         reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
991         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
992         reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
993         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
994         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
995         /* Enable video transfert */
996         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
997         /* Compression */
998         reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
999         msleep(20);
1000
1001         setgain(gspca_dev);
1002         setbrightness(gspca_dev);
1003         setexposure(gspca_dev);
1004
1005         sd->autogain_ignore_frames = 0;
1006         atomic_set(&sd->avg_lum, -1);
1007 }
1008
1009 static void sd_stopN(struct gspca_dev *gspca_dev)
1010 {
1011         __u8 ByteSend;
1012
1013         ByteSend = 0x09;        /* 0X00 */
1014         reg_w(gspca_dev, 0x01, &ByteSend, 1);
1015 }
1016
1017 static void sd_stop0(struct gspca_dev *gspca_dev)
1018 {
1019 }
1020
1021 static void sd_close(struct gspca_dev *gspca_dev)
1022 {
1023 }
1024
1025 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1026                         struct gspca_frame *frame,      /* target */
1027                         unsigned char *data,            /* isoc packet */
1028                         int len)                        /* iso packet length */
1029 {
1030         int i;
1031         struct sd *sd = (struct sd *) gspca_dev;
1032
1033         if (len > 6 && len < 24) {
1034                 for (i = 0; i < len - 6; i++) {
1035                         if (data[0 + i] == 0xff
1036                             && data[1 + i] == 0xff
1037                             && data[2 + i] == 0x00
1038                             && data[3 + i] == 0xc4
1039                             && data[4 + i] == 0xc4
1040                             && data[5 + i] == 0x96) {   /* start of frame */
1041                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
1042                                                         frame, data, 0);
1043                                 if (i < (len - 10)) {
1044                                         atomic_set(&sd->avg_lum, data[i + 8] +
1045                                                         (data[i + 9] << 8));
1046                                 } else {
1047                                         atomic_set(&sd->avg_lum, -1);
1048 #ifdef CONFIG_VIDEO_ADV_DEBUG
1049                                         PDEBUG(D_STREAM, "packet too short to "
1050                                                 "get avg brightness");
1051 #endif
1052                                 }
1053                                 data += i + sd->fr_h_sz;
1054                                 len -= i + sd->fr_h_sz;
1055                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1056                                                 frame, data, len);
1057                                 return;
1058                         }
1059                 }
1060         }
1061         gspca_frame_add(gspca_dev, INTER_PACKET,
1062                         frame, data, len);
1063 }
1064
1065 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1066 {
1067         struct sd *sd = (struct sd *) gspca_dev;
1068
1069         sd->brightness = val;
1070         if (gspca_dev->streaming)
1071                 setbrightness(gspca_dev);
1072         return 0;
1073 }
1074
1075 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1076 {
1077         struct sd *sd = (struct sd *) gspca_dev;
1078
1079         *val = sd->brightness;
1080         return 0;
1081 }
1082
1083 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1084 {
1085         struct sd *sd = (struct sd *) gspca_dev;
1086
1087         sd->gain = val;
1088         if (gspca_dev->streaming)
1089                 setgain(gspca_dev);
1090         return 0;
1091 }
1092
1093 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1094 {
1095         struct sd *sd = (struct sd *) gspca_dev;
1096
1097         *val = sd->gain;
1098         return 0;
1099 }
1100
1101 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1102 {
1103         struct sd *sd = (struct sd *) gspca_dev;
1104
1105         sd->exposure = val;
1106         if (gspca_dev->streaming)
1107                 setexposure(gspca_dev);
1108         return 0;
1109 }
1110
1111 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1112 {
1113         struct sd *sd = (struct sd *) gspca_dev;
1114
1115         *val = sd->exposure;
1116         return 0;
1117 }
1118
1119 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1120 {
1121         struct sd *sd = (struct sd *) gspca_dev;
1122
1123         sd->autogain = val;
1124         /* when switching to autogain set defaults to make sure
1125            we are on a valid point of the autogain gain /
1126            exposure knee graph, and give this change time to
1127            take effect before doing autogain. */
1128         if (sd->autogain) {
1129                 sd->exposure = EXPOSURE_DEF;
1130                 sd->gain = GAIN_DEF;
1131                 if (gspca_dev->streaming) {
1132                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1133                         setexposure(gspca_dev);
1134                         setgain(gspca_dev);
1135                 }
1136         }
1137
1138         return 0;
1139 }
1140
1141 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1142 {
1143         struct sd *sd = (struct sd *) gspca_dev;
1144
1145         *val = sd->autogain;
1146         return 0;
1147 }
1148
1149 /* sub-driver description */
1150 static const struct sd_desc sd_desc = {
1151         .name = MODULE_NAME,
1152         .ctrls = sd_ctrls,
1153         .nctrls = ARRAY_SIZE(sd_ctrls),
1154         .config = sd_config,
1155         .open = sd_open,
1156         .start = sd_start,
1157         .stopN = sd_stopN,
1158         .stop0 = sd_stop0,
1159         .close = sd_close,
1160         .pkt_scan = sd_pkt_scan,
1161 };
1162
1163 /* -- module initialisation -- */
1164 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1165 static __devinitdata struct usb_device_id device_table[] = {
1166 #ifndef CONFIG_USB_SN9C102
1167         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1168         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1169         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1170         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1171         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1172         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1173         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1174         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1175         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1176         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1177         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1178         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1179         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1180         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1181         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1182         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1183 #endif
1184         {}
1185 };
1186 MODULE_DEVICE_TABLE(usb, device_table);
1187
1188 /* -- device connect -- */
1189 static int sd_probe(struct usb_interface *intf,
1190                         const struct usb_device_id *id)
1191 {
1192         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1193                                 THIS_MODULE);
1194 }
1195
1196 static struct usb_driver sd_driver = {
1197         .name = MODULE_NAME,
1198         .id_table = device_table,
1199         .probe = sd_probe,
1200         .disconnect = gspca_disconnect,
1201 };
1202
1203 /* -- module insert / remove -- */
1204 static int __init sd_mod_init(void)
1205 {
1206         if (usb_register(&sd_driver) < 0)
1207                 return -1;
1208         PDEBUG(D_PROBE, "v%s registered", version);
1209         return 0;
1210 }
1211 static void __exit sd_mod_exit(void)
1212 {
1213         usb_deregister(&sd_driver);
1214         PDEBUG(D_PROBE, "deregistered");
1215 }
1216
1217 module_init(sd_mod_init);
1218 module_exit(sd_mod_exit);