V4L/DVB (8361): gspca: Bad check of i2c write to sn9c10x.
[safe/jmp/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] & 0x04) {
460                         if (gspca_dev->usb_buf[0] & 0x08)
461                                 return -1;
462                         return 0;
463                 }
464         }
465         return -1;
466 }
467
468 static void i2c_w_vector(struct gspca_dev *gspca_dev,
469                         const __u8 buffer[][8], int len)
470 {
471         for (;;) {
472                 reg_w(gspca_dev, 0x08, *buffer, 8);
473                 len -= 8;
474                 if (len <= 0)
475                         break;
476                 buffer++;
477         }
478 }
479
480 static void setbrightness(struct gspca_dev *gspca_dev)
481 {
482         struct sd *sd = (struct sd *) gspca_dev;
483         __u8 value;
484
485         switch (sd->sensor) {
486         case SENSOR_OV6650: {
487                 __u8 i2cOV6650[] =
488                         {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
489
490                 i2cOV6650[3] = sd->brightness;
491                 if (i2c_w(gspca_dev, i2cOV6650) < 0)
492                          goto err;
493                 break;
494             }
495         case  SENSOR_OV7630_3:
496         case  SENSOR_OV7630: {
497                 __u8 i2cOV[] =
498                         {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
499
500                 /* change reg 0x06 */
501                 i2cOV[3] = sd->brightness;
502                 if (i2c_w(gspca_dev, i2cOV) < 0)
503                         goto err;
504                 break;
505             }
506         case SENSOR_PAS106: {
507                 __u8 i2c1[] =
508                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
509
510                 i2c1[3] = sd->brightness >> 3;
511                 i2c1[2] = 0x0e;
512                 if (i2c_w(gspca_dev, i2c1) < 0)
513                         goto err;
514                 i2c1[3] = 0x01;
515                 i2c1[2] = 0x13;
516                 if (i2c_w(gspca_dev, i2c1) < 0)
517                         goto err;
518                 break;
519             }
520         case SENSOR_PAS202: {
521                 /* __u8 i2cpexpo1[] =
522                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
523                 __u8 i2cpexpo[] =
524                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
525                 __u8 i2cp202[] =
526                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
527                 static __u8 i2cpdoit[] =
528                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
529
530                 /* change reg 0x10 */
531                 i2cpexpo[4] = 0xff - sd->brightness;
532 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
533                         goto err; */
534 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
535                         goto err; */
536                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
537                         goto err;
538                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
539                         goto err;
540                 i2cp202[3] = sd->brightness >> 3;
541                 if (i2c_w(gspca_dev, i2cp202) < 0)
542                         goto err;
543                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
544                         goto err;
545                 break;
546             }
547         case SENSOR_TAS5130CXX: {
548                 __u8 i2c[] =
549                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
550
551                 value = 0xff - sd->brightness;
552                 i2c[4] = value;
553                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
554                 if (i2c_w(gspca_dev, i2c) < 0)
555                         goto err;
556                 break;
557             }
558         case SENSOR_TAS5110:
559                 /* FIXME figure out howto control brightness on TAS5110 */
560                 break;
561         }
562         return;
563 err:
564         PDEBUG(D_ERR, "i2c error brightness");
565 }
566
567 static void setsensorgain(struct gspca_dev *gspca_dev)
568 {
569         struct sd *sd = (struct sd *) gspca_dev;
570
571         switch (sd->sensor) {
572
573         case SENSOR_TAS5110: {
574                 __u8 i2c[] =
575                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
576
577                 i2c[4] = 255 - sd->gain;
578                 if (i2c_w(gspca_dev, i2c) < 0)
579                         goto err;
580                 break;
581             }
582         case SENSOR_OV6650: {
583                 __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
584
585                 i2c[3] = sd->gain >> 3;
586                 if (i2c_w(gspca_dev, i2c) < 0)
587                         goto err;
588                 break;
589             }
590         case SENSOR_OV7630_3: {
591                 __u8 i2c[] = {0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
592
593                 i2c[3] = sd->gain >> 2;
594                 if (i2c_w(gspca_dev, i2c) < 0)
595                         goto err;
596                 break;
597             }
598         }
599         return;
600 err:
601         PDEBUG(D_ERR, "i2c error gain");
602 }
603
604 static void setgain(struct gspca_dev *gspca_dev)
605 {
606         struct sd *sd = (struct sd *) gspca_dev;
607         __u8 gain;
608         __u8 rgb_value;
609
610         gain = sd->gain >> 4;
611
612         /* red and blue gain */
613         rgb_value = gain << 4 | gain;
614         reg_w(gspca_dev, 0x10, &rgb_value, 1);
615         /* green gain */
616         rgb_value = gain;
617         reg_w(gspca_dev, 0x11, &rgb_value, 1);
618
619         if (sd->sensor_has_gain)
620                 setsensorgain(gspca_dev);
621 }
622
623 static void setexposure(struct gspca_dev *gspca_dev)
624 {
625         struct sd *sd = (struct sd *) gspca_dev;
626
627         switch (sd->sensor) {
628         case SENSOR_TAS5110: {
629                 __u8 reg;
630
631                 /* register 19's high nibble contains the sn9c10x clock divider
632                    The high nibble configures the no fps according to the
633                    formula: 60 / high_nibble. With a maximum of 30 fps */
634                 reg = 120 * sd->exposure / 1000;
635                 if (reg < 2)
636                         reg = 2;
637                 else if (reg > 15)
638                         reg = 15;
639                 reg = (reg << 4) | 0x0b;
640                 reg_w(gspca_dev, 0x19, &reg, 1);
641                 break;
642             }
643         case SENSOR_OV6650: {
644                 /* The ov6650 has 2 registers which both influence exposure,
645                    first there is register 11, whose low nibble sets the no fps
646                    according to: fps = 30 / (low_nibble + 1)
647
648                    The fps configures the maximum exposure setting, but it is
649                    possible to use less exposure then what the fps maximum
650                    allows by setting register 10. register 10 configures the
651                    actual exposure as quotient of the full exposure, with 0
652                    being no exposure at all (not very usefull) and reg10_max
653                    being max exposure possible at that framerate.
654
655                    The code maps our 0 - 510 ms exposure ctrl to these 2
656                    registers, trying to keep fps as high as possible.
657                 */
658                 __u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
659                 int reg10, reg11;
660                 /* No clear idea why, but setting reg10 above this value
661                    results in no change */
662                 const int reg10_max = 0x4d;
663
664                 reg11 = (60 * sd->exposure + 999) / 1000;
665                 if (reg11 < 1)
666                         reg11 = 1;
667                 else if (reg11 > 16)
668                         reg11 = 16;
669
670                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
671                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
672                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
673                 if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
674                         reg10 = 1;
675                 else if (reg10 > reg10_max)
676                         reg10 = reg10_max;
677
678                 /* Write reg 10 and reg11 low nibble */
679                 i2c[3] = reg10;
680                 i2c[4] |= reg11 - 1;
681                 if (i2c_w(gspca_dev, i2c) < 0)
682                         PDEBUG(D_ERR, "i2c error exposure");
683                 break;
684             }
685         case SENSOR_OV7630_3: {
686                 __u8 i2c[] = {0xb0, 0x21, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
687                 int reg10, reg11;
688                 /* No clear idea why, but setting reg10 above this value
689                    results in no change */
690                 const int reg10_max = 0x4d;
691
692                 reg11 = (60 * sd->exposure + 999) / 1000;
693                 if (reg11 < 1)
694                         reg11 = 1;
695                 else if (reg11 > 16)
696                         reg11 = 16;
697
698                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
699                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
700                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
701                 if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
702                         reg10 = 1;
703                 else if (reg10 > reg10_max)
704                         reg10 = reg10_max;
705
706                 /* Write reg 10 and reg11 low nibble */
707                 i2c[3] = reg10;
708                 i2c[4] |= reg11 - 1;
709                 if (i2c_w(gspca_dev, i2c) < 0)
710                         PDEBUG(D_ERR, "i2c error exposure");
711                 break;
712             }
713         }
714 }
715
716
717 static void do_autogain(struct gspca_dev *gspca_dev)
718 {
719         struct sd *sd = (struct sd *) gspca_dev;
720         int avg_lum = atomic_read(&sd->avg_lum);
721
722         if (avg_lum == -1)
723                 return;
724
725         if (sd->autogain_ignore_frames > 0)
726                 sd->autogain_ignore_frames--;
727         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
728                         sd->brightness * DESIRED_AVG_LUM / 127,
729                         AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE))
730                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
731 }
732
733 /* this function is called at probe time */
734 static int sd_config(struct gspca_dev *gspca_dev,
735                         const struct usb_device_id *id)
736 {
737         struct sd *sd = (struct sd *) gspca_dev;
738         struct cam *cam;
739         __u16 product;
740         int sif = 0;
741
742         /* nctrls depends upon the sensor, so we use a per cam copy */
743         memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
744         gspca_dev->sd_desc = &sd->sd_desc;
745
746         sd->fr_h_sz = 12;               /* default size of the frame header */
747         sd->sd_desc.nctrls = 2;         /* default nb of ctrls */
748         sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
749
750         product = id->idProduct;
751 /*      switch (id->idVendor) { */
752 /*      case 0x0c45:                             * Sonix */
753                 switch (product) {
754                 case 0x6001:                    /* SN9C102 */
755                 case 0x6005:                    /* SN9C101 */
756                 case 0x6007:                    /* SN9C101 */
757                         sd->sensor = SENSOR_TAS5110;
758                         sd->sensor_has_gain = 1;
759                         sd->sd_desc.nctrls = 4;
760                         sd->sd_desc.dq_callback = do_autogain;
761                         sif = 1;
762                         break;
763                 case 0x6009:                    /* SN9C101 */
764                 case 0x600d:                    /* SN9C101 */
765                 case 0x6029:                    /* SN9C101 */
766                         sd->sensor = SENSOR_PAS106;
767                         sif = 1;
768                         break;
769                 case 0x6011:                    /* SN9C101 - SN9C101G */
770                         sd->sensor = SENSOR_OV6650;
771                         sd->sensor_has_gain = 1;
772                         sd->sd_desc.nctrls = 4;
773                         sd->sd_desc.dq_callback = do_autogain;
774                         sif = 1;
775                         break;
776                 case 0x6019:                    /* SN9C101 */
777                 case 0x602c:                    /* SN9C102 */
778                 case 0x602e:                    /* SN9C102 */
779                         sd->sensor = SENSOR_OV7630;
780                         break;
781                 case 0x60b0:                    /* SN9C103 */
782                         sd->sensor = SENSOR_OV7630_3;
783                         sd->fr_h_sz = 18;       /* size of frame header */
784                         sd->sensor_has_gain = 1;
785                         sd->sd_desc.nctrls = 4;
786                         sd->sd_desc.dq_callback = do_autogain;
787                         sd->autogain = 0;
788                         break;
789                 case 0x6024:                    /* SN9C102 */
790                 case 0x6025:                    /* SN9C102 */
791                         sd->sensor = SENSOR_TAS5130CXX;
792                         break;
793                 case 0x6028:                    /* SN9C102 */
794                         sd->sensor = SENSOR_PAS202;
795                         break;
796                 case 0x602d:                    /* SN9C102 */
797                         sd->sensor = SENSOR_HV7131R;
798                         break;
799                 case 0x60af:                    /* SN9C103 */
800                         sd->sensor = SENSOR_PAS202;
801                         sd->fr_h_sz = 18;       /* size of frame header (?) */
802                         break;
803                 }
804 /*              break; */
805 /*      } */
806
807         cam = &gspca_dev->cam;
808         cam->dev_name = (char *) id->driver_info;
809         cam->epaddr = 0x01;
810         if (!sif) {
811                 cam->cam_mode = vga_mode;
812                 cam->nmodes = ARRAY_SIZE(vga_mode);
813                 if (sd->sensor == SENSOR_OV7630_3) {
814                         /* We only have 320x240 & 640x480 */
815                         cam->cam_mode++;
816                         cam->nmodes--;
817                 }
818         } else {
819                 cam->cam_mode = sif_mode;
820                 cam->nmodes = ARRAY_SIZE(sif_mode);
821         }
822         sd->brightness = BRIGHTNESS_DEF;
823         sd->gain = GAIN_DEF;
824         sd->exposure = EXPOSURE_DEF;
825         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
826                 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
827         return 0;
828 }
829
830 /* this function is called at open time */
831 static int sd_open(struct gspca_dev *gspca_dev)
832 {
833         reg_r(gspca_dev, 0x00);
834         if (gspca_dev->usb_buf[0] != 0x10)
835                 return -ENODEV;
836         return 0;
837 }
838
839 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
840 {
841         int i;
842         const __u8 *data;
843         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
844
845         i = ARRAY_SIZE(pas106_data);
846         data = pas106_data[0];
847         while (--i >= 0) {
848                 memcpy(&i2c1[2], data, 2);
849                                         /* copy 2 bytes from the template */
850                 if (i2c_w(gspca_dev, i2c1) < 0)
851                         PDEBUG(D_ERR, "i2c error pas106");
852                 data += 2;
853         }
854 }
855
856 /* -- start the camera -- */
857 static void sd_start(struct gspca_dev *gspca_dev)
858 {
859         struct sd *sd = (struct sd *) gspca_dev;
860         int mode, l;
861         const __u8 *sn9c10x;
862         __u8 reg01, reg17;
863         __u8 reg17_19[3];
864
865         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
866         switch (sd->sensor) {
867         case SENSOR_HV7131R:
868                 sn9c10x = initHv7131;
869                 reg17_19[0] = 0x60;
870                 reg17_19[1] = (mode << 4) | 0x8a;
871                 reg17_19[2] = 0x20;
872                 break;
873         case SENSOR_OV6650:
874                 sn9c10x = initOv6650;
875                 reg17_19[0] = 0x68;
876                 reg17_19[1] = (mode << 4) | 0x8b;
877                 reg17_19[2] = 0x20;
878                 break;
879         case SENSOR_OV7630:
880                 sn9c10x = initOv7630;
881                 reg17_19[0] = 0x68;
882                 reg17_19[1] = (mode << 4) | COMP2;
883                 reg17_19[2] = MCK_INIT1;
884                 break;
885         case SENSOR_OV7630_3:
886                 sn9c10x = initOv7630_3;
887                 reg17_19[0] = 0x68;
888                 reg17_19[1] = (mode << 4) | COMP2;
889                 reg17_19[2] = MCK_INIT1;
890                 break;
891         case SENSOR_PAS106:
892                 sn9c10x = initPas106;
893                 reg17_19[0] = 0x24;             /* 0x28 */
894                 reg17_19[1] = (mode << 4) | COMP1;
895                 reg17_19[2] = MCK_INIT1;
896                 break;
897         case SENSOR_PAS202:
898                 sn9c10x = initPas202;
899                 reg17_19[0] = mode ? 0x24 : 0x20;
900                 reg17_19[1] = (mode << 4) | 0x89;
901                 reg17_19[2] = 0x20;
902                 break;
903         case SENSOR_TAS5110:
904                 sn9c10x = initTas5110;
905                 reg17_19[0] = 0x60;
906                 reg17_19[1] = (mode << 4) | 0x86;
907                 reg17_19[2] = 0x2b;             /* 0xf3; */
908                 break;
909         default:
910 /*      case SENSOR_TAS5130CXX: */
911                 sn9c10x = initTas5130;
912                 reg17_19[0] = 0x60;
913                 reg17_19[1] = (mode << 4) | COMP;
914                 reg17_19[2] = mode ? 0x23 : 0x43;
915                 break;
916         }
917         switch (sd->sensor) {
918         case SENSOR_OV7630:
919                 reg01 = 0x06;
920                 reg17 = 0x29;
921                 l = 0x10;
922                 break;
923         case SENSOR_OV7630_3:
924                 reg01 = 0x44;
925                 reg17 = 0x68;
926                 l = sizeof initOv7630_3;
927                 break;
928         default:
929                 reg01 = sn9c10x[0];
930                 reg17 = sn9c10x[0x17 - 1];
931                 l = 0x1f;
932                 break;
933         }
934
935         /* reg 0x01 bit 2 video transfert on */
936         reg_w(gspca_dev, 0x01, &reg01, 1);
937         /* reg 0x17 SensorClk enable inv Clk 0x60 */
938         reg_w(gspca_dev, 0x17, &reg17, 1);
939 /*fixme: for ov7630 102
940         reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
941         /* Set the registers from the template */
942         reg_w_big(gspca_dev, 0x01, sn9c10x, l);
943         switch (sd->sensor) {
944         case SENSOR_HV7131R:
945                 i2c_w_vector(gspca_dev, hv7131_sensor_init,
946                                 sizeof hv7131_sensor_init);
947                 break;
948         case SENSOR_OV6650:
949                 i2c_w_vector(gspca_dev, ov6650_sensor_init,
950                                 sizeof ov6650_sensor_init);
951                 break;
952         case SENSOR_OV7630:
953                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
954                                 sizeof ov7630_sensor_init_com);
955                 msleep(200);
956                 i2c_w_vector(gspca_dev, ov7630_sensor_init,
957                                 sizeof ov7630_sensor_init);
958                 break;
959         case SENSOR_OV7630_3:
960                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
961                                 sizeof ov7630_sensor_init_com);
962                 msleep(200);
963                 i2c_w_vector(gspca_dev, ov7630_sensor_init_3[mode],
964                                 sizeof ov7630_sensor_init_3[mode]);
965                 break;
966         case SENSOR_PAS106:
967                 pas106_i2cinit(gspca_dev);
968                 break;
969         case SENSOR_PAS202:
970                 i2c_w_vector(gspca_dev, pas202_sensor_init,
971                                 sizeof pas202_sensor_init);
972                 break;
973         case SENSOR_TAS5110:
974                 i2c_w_vector(gspca_dev, tas5110_sensor_init,
975                                 sizeof tas5110_sensor_init);
976                 break;
977         default:
978 /*      case SENSOR_TAS5130CXX: */
979                 i2c_w_vector(gspca_dev, tas5130_sensor_init,
980                                 sizeof tas5130_sensor_init);
981                 break;
982         }
983         /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
984         reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
985         /* compression register */
986         reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
987         /* H_start */
988         reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
989         /* V_START */
990         reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
991         /* reset 0x17 SensorClk enable inv Clk 0x60 */
992                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
993         reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
994         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
995         reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
996         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
997         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
998         /* Enable video transfert */
999         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
1000         /* Compression */
1001         reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
1002         msleep(20);
1003
1004         setgain(gspca_dev);
1005         setbrightness(gspca_dev);
1006         setexposure(gspca_dev);
1007
1008         sd->autogain_ignore_frames = 0;
1009         atomic_set(&sd->avg_lum, -1);
1010 }
1011
1012 static void sd_stopN(struct gspca_dev *gspca_dev)
1013 {
1014         __u8 ByteSend;
1015
1016         ByteSend = 0x09;        /* 0X00 */
1017         reg_w(gspca_dev, 0x01, &ByteSend, 1);
1018 }
1019
1020 static void sd_stop0(struct gspca_dev *gspca_dev)
1021 {
1022 }
1023
1024 static void sd_close(struct gspca_dev *gspca_dev)
1025 {
1026 }
1027
1028 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1029                         struct gspca_frame *frame,      /* target */
1030                         unsigned char *data,            /* isoc packet */
1031                         int len)                        /* iso packet length */
1032 {
1033         int i;
1034         struct sd *sd = (struct sd *) gspca_dev;
1035
1036         if (len > 6 && len < 24) {
1037                 for (i = 0; i < len - 6; i++) {
1038                         if (data[0 + i] == 0xff
1039                             && data[1 + i] == 0xff
1040                             && data[2 + i] == 0x00
1041                             && data[3 + i] == 0xc4
1042                             && data[4 + i] == 0xc4
1043                             && data[5 + i] == 0x96) {   /* start of frame */
1044                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
1045                                                         frame, data, 0);
1046                                 if (i < (len - 10)) {
1047                                         atomic_set(&sd->avg_lum, data[i + 8] +
1048                                                         (data[i + 9] << 8));
1049                                 } else {
1050                                         atomic_set(&sd->avg_lum, -1);
1051 #ifdef CONFIG_VIDEO_ADV_DEBUG
1052                                         PDEBUG(D_STREAM, "packet too short to "
1053                                                 "get avg brightness");
1054 #endif
1055                                 }
1056                                 data += i + sd->fr_h_sz;
1057                                 len -= i + sd->fr_h_sz;
1058                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1059                                                 frame, data, len);
1060                                 return;
1061                         }
1062                 }
1063         }
1064         gspca_frame_add(gspca_dev, INTER_PACKET,
1065                         frame, data, len);
1066 }
1067
1068 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1069 {
1070         struct sd *sd = (struct sd *) gspca_dev;
1071
1072         sd->brightness = val;
1073         if (gspca_dev->streaming)
1074                 setbrightness(gspca_dev);
1075         return 0;
1076 }
1077
1078 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1079 {
1080         struct sd *sd = (struct sd *) gspca_dev;
1081
1082         *val = sd->brightness;
1083         return 0;
1084 }
1085
1086 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1087 {
1088         struct sd *sd = (struct sd *) gspca_dev;
1089
1090         sd->gain = val;
1091         if (gspca_dev->streaming)
1092                 setgain(gspca_dev);
1093         return 0;
1094 }
1095
1096 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1097 {
1098         struct sd *sd = (struct sd *) gspca_dev;
1099
1100         *val = sd->gain;
1101         return 0;
1102 }
1103
1104 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1105 {
1106         struct sd *sd = (struct sd *) gspca_dev;
1107
1108         sd->exposure = val;
1109         if (gspca_dev->streaming)
1110                 setexposure(gspca_dev);
1111         return 0;
1112 }
1113
1114 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1115 {
1116         struct sd *sd = (struct sd *) gspca_dev;
1117
1118         *val = sd->exposure;
1119         return 0;
1120 }
1121
1122 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1123 {
1124         struct sd *sd = (struct sd *) gspca_dev;
1125
1126         sd->autogain = val;
1127         /* when switching to autogain set defaults to make sure
1128            we are on a valid point of the autogain gain /
1129            exposure knee graph, and give this change time to
1130            take effect before doing autogain. */
1131         if (sd->autogain) {
1132                 sd->exposure = EXPOSURE_DEF;
1133                 sd->gain = GAIN_DEF;
1134                 if (gspca_dev->streaming) {
1135                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1136                         setexposure(gspca_dev);
1137                         setgain(gspca_dev);
1138                 }
1139         }
1140
1141         return 0;
1142 }
1143
1144 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1145 {
1146         struct sd *sd = (struct sd *) gspca_dev;
1147
1148         *val = sd->autogain;
1149         return 0;
1150 }
1151
1152 /* sub-driver description */
1153 static const struct sd_desc sd_desc = {
1154         .name = MODULE_NAME,
1155         .ctrls = sd_ctrls,
1156         .nctrls = ARRAY_SIZE(sd_ctrls),
1157         .config = sd_config,
1158         .open = sd_open,
1159         .start = sd_start,
1160         .stopN = sd_stopN,
1161         .stop0 = sd_stop0,
1162         .close = sd_close,
1163         .pkt_scan = sd_pkt_scan,
1164 };
1165
1166 /* -- module initialisation -- */
1167 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1168 static __devinitdata struct usb_device_id device_table[] = {
1169 #ifndef CONFIG_USB_SN9C102
1170         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1171         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1172         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1173         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1174         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1175         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1176         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1177         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1178         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1179         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1180         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1181         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1182         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1183         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1184         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1185         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1186 #endif
1187         {}
1188 };
1189 MODULE_DEVICE_TABLE(usb, device_table);
1190
1191 /* -- device connect -- */
1192 static int sd_probe(struct usb_interface *intf,
1193                         const struct usb_device_id *id)
1194 {
1195         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1196                                 THIS_MODULE);
1197 }
1198
1199 static struct usb_driver sd_driver = {
1200         .name = MODULE_NAME,
1201         .id_table = device_table,
1202         .probe = sd_probe,
1203         .disconnect = gspca_disconnect,
1204 };
1205
1206 /* -- module insert / remove -- */
1207 static int __init sd_mod_init(void)
1208 {
1209         if (usb_register(&sd_driver) < 0)
1210                 return -1;
1211         PDEBUG(D_PROBE, "v%s registered", version);
1212         return 0;
1213 }
1214 static void __exit sd_mod_exit(void)
1215 {
1216         usb_deregister(&sd_driver);
1217         PDEBUG(D_PROBE, "deregistered");
1218 }
1219
1220 module_init(sd_mod_init);
1221 module_exit(sd_mod_exit);