V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack.
[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 short gain;
43         unsigned short 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 500
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 = 511,
111                 .step    = 1,
112 #define GAIN_DEF 255
113 #define GAIN_KNEE 400
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 0
125 #define EXPOSURE_KNEE 353 /* 10 fps */
126                         .minimum = 0,
127                         .maximum = 511,
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         0x16, 0x12,                     /* 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, 0x78, 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},          jfm */
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[][8] = {
282         {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16},      /* exposure */
283         {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16},
284         {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16},
285         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
286 /*      {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d},
287                 * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */
288 /*      {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d},        * from win */
289         {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d},
290 };
291
292 static const __u8 initPas106[] = {
293         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
294         0x00, 0x00,
295         0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
296         0x16, 0x12, 0x28, COMP1, MCK_INIT1,
297         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
298 };
299 /* compression 0x86 mckinit1 0x2b */
300 static const __u8 pas106_data[][2] = {
301         {0x02, 0x04},           /* Pixel Clock Divider 6 */
302         {0x03, 0x13},           /* Frame Time MSB */
303 /*      {0x03, 0x12},            * Frame Time MSB */
304         {0x04, 0x06},           /* Frame Time LSB */
305 /*      {0x04, 0x05},            * Frame Time LSB */
306         {0x05, 0x65},           /* Shutter Time Line Offset */
307 /*      {0x05, 0x6d},            * Shutter Time Line Offset */
308 /*      {0x06, 0xb1},            * Shutter Time Pixel Offset */
309         {0x06, 0xcd},           /* Shutter Time Pixel Offset */
310         {0x07, 0xc1},           /* Black Level Subtract Sign */
311 /*      {0x07, 0x00},            * Black Level Subtract Sign */
312         {0x08, 0x06},           /* Black Level Subtract Level */
313         {0x08, 0x06},           /* Black Level Subtract Level */
314 /*      {0x08, 0x01},            * Black Level Subtract Level */
315         {0x09, 0x05},           /* Color Gain B Pixel 5 a */
316         {0x0a, 0x04},           /* Color Gain G1 Pixel 1 5 */
317         {0x0b, 0x04},           /* Color Gain G2 Pixel 1 0 5 */
318         {0x0c, 0x05},           /* Color Gain R Pixel 3 1 */
319         {0x0d, 0x00},           /* Color GainH  Pixel */
320         {0x0e, 0x0e},           /* Global Gain */
321         {0x0f, 0x00},           /* Contrast */
322         {0x10, 0x06},           /* H&V synchro polarity */
323         {0x11, 0x06},           /* ?default */
324         {0x12, 0x06},           /* DAC scale */
325         {0x14, 0x02},           /* ?default */
326         {0x13, 0x01},           /* Validate Settings */
327 };
328 static const __u8 initPas202[] = {
329         0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
330         0x00, 0x00,
331         0x00, 0x00, 0x00, 0x07, 0x03, 0x0a,     /* 6 */
332         0x28, 0x1e, 0x28, 0x89, 0x30,
333         0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
334 };
335 static const __u8 pas202_sensor_init[][8] = {
336         {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
337         {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
338         {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
339         {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
340         {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
341         {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
342         {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
343         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
344         {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
345         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
346         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
347         {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
348
349         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
350         {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
351         {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
352         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
353         {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
354         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
355         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
356         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
357 };
358
359 static const __u8 initTas5110[] = {
360         0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
361         0x00, 0x00,
362         0x00, 0x01, 0x00, 0x46, 0x09, 0x0a,     /* shift from 0x45 0x09 0x0a */
363         0x16, 0x12, 0x60, 0x86, 0x2b,
364         0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
365 };
366 static const __u8 tas5110_sensor_init[][8] = {
367         {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
368         {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
369         {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
370 };
371
372 static const __u8 initTas5130[] = {
373         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
374         0x00, 0x00,
375         0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
376         0x28, 0x1e, 0x60, COMP, MCK_INIT,
377         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
378 };
379 static const __u8 tas5130_sensor_init[][8] = {
380 /*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
381                                         * shutter 0x47 short exposure? */
382         {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
383                                         /* shutter 0x01 long exposure */
384         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
385 };
386
387 /* get one byte in gspca_dev->usb_buf */
388 static void reg_r(struct gspca_dev *gspca_dev,
389                   __u16 value)
390 {
391         usb_control_msg(gspca_dev->dev,
392                         usb_rcvctrlpipe(gspca_dev->dev, 0),
393                         0,                      /* request */
394                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
395                         value,
396                         0,                      /* index */
397                         gspca_dev->usb_buf, 1,
398                         500);
399 }
400
401 static void reg_w(struct gspca_dev *gspca_dev,
402                   __u16 value,
403                   const __u8 *buffer,
404                   int len)
405 {
406 #ifdef CONFIG_VIDEO_ADV_DEBUG
407         if (len > sizeof gspca_dev->usb_buf) {
408                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
409                 return;
410         }
411 #endif
412         memcpy(gspca_dev->usb_buf, buffer, len);
413         usb_control_msg(gspca_dev->dev,
414                         usb_sndctrlpipe(gspca_dev->dev, 0),
415                         0x08,                   /* request */
416                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
417                         value,
418                         0,                      /* index */
419                         gspca_dev->usb_buf, len,
420                         500);
421 }
422
423 static void reg_w_big(struct gspca_dev *gspca_dev,
424                   __u16 value,
425                   const __u8 *buffer,
426                   int len)
427 {
428         __u8 *tmpbuf;
429
430         tmpbuf = kmalloc(len, GFP_KERNEL);
431         memcpy(tmpbuf, buffer, len);
432         usb_control_msg(gspca_dev->dev,
433                         usb_sndctrlpipe(gspca_dev->dev, 0),
434                         0x08,                   /* request */
435                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
436                         value,
437                         0,                      /* index */
438                         tmpbuf, len,
439                         500);
440         kfree(tmpbuf);
441 }
442
443 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
444 {
445         int retry = 60;
446
447         /* is i2c ready */
448         reg_w(gspca_dev, 0x08, buffer, 8);
449         while (retry--) {
450                 msleep(10);
451                 reg_r(gspca_dev, 0x08);
452                 if (gspca_dev->usb_buf[0] == 4)
453                         return 0;
454         }
455         return -1;
456 }
457
458 static void i2c_w_vector(struct gspca_dev *gspca_dev,
459                         const __u8 buffer[][8], int len)
460 {
461         for (;;) {
462                 reg_w(gspca_dev, 0x08, *buffer, 8);
463                 len -= 8;
464                 if (len <= 0)
465                         break;
466                 buffer++;
467         }
468 }
469
470 static void setbrightness(struct gspca_dev *gspca_dev)
471 {
472         struct sd *sd = (struct sd *) gspca_dev;
473         __u8 value;
474
475         switch (sd->sensor) {
476         case SENSOR_OV6650: {
477                 __u8 i2cOV6650[] =
478                         {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
479
480                 i2cOV6650[3] = sd->brightness;
481                 if (i2c_w(gspca_dev, i2cOV6650) < 0)
482                          goto err;
483                 break;
484             }
485         case  SENSOR_OV7630: {
486                 __u8 i2cOV[] =
487                         {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
488
489                 /* change reg 0x06 */
490                 i2cOV[3] = sd->brightness;
491                 if (i2c_w(gspca_dev, i2cOV) < 0)
492                         goto err;
493                 break;
494             }
495         case SENSOR_PAS106: {
496                 __u8 i2c1[] =
497                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
498
499                 i2c1[3] = sd->brightness >> 3;
500                 i2c1[2] = 0x0e;
501                 if (i2c_w(gspca_dev, i2c1) < 0)
502                         goto err;
503                 i2c1[3] = 0x01;
504                 i2c1[2] = 0x13;
505                 if (i2c_w(gspca_dev, i2c1) < 0)
506                         goto err;
507                 break;
508             }
509         case SENSOR_PAS202: {
510                 /* __u8 i2cpexpo1[] =
511                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
512                 __u8 i2cpexpo[] =
513                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
514                 __u8 i2cp202[] =
515                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
516                 static __u8 i2cpdoit[] =
517                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
518
519                 /* change reg 0x10 */
520                 i2cpexpo[4] = 0xff - sd->brightness;
521 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
522                         goto err; */
523 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
524                         goto err; */
525                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
526                         goto err;
527                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
528                         goto err;
529                 i2cp202[3] = sd->brightness >> 3;
530                 if (i2c_w(gspca_dev, i2cp202) < 0)
531                         goto err;
532                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
533                         goto err;
534                 break;
535             }
536         case SENSOR_TAS5130CXX: {
537                 __u8 i2c[] =
538                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
539
540                 value = 0xff - sd->brightness;
541                 i2c[4] = value;
542                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
543                 if (i2c_w(gspca_dev, i2c) < 0)
544                         goto err;
545                 break;
546             }
547         case SENSOR_TAS5110:
548                 /* FIXME figure out howto control brightness on TAS5110 */
549                 break;
550         }
551         return;
552 err:
553         PDEBUG(D_ERR, "i2c error brightness");
554 }
555
556 static void setsensorgain(struct gspca_dev *gspca_dev)
557 {
558         struct sd *sd = (struct sd *) gspca_dev;
559         unsigned short gain;
560
561         gain = (sd->gain + 1) >> 1;
562         if (gain > 255)
563                 gain = 255;
564
565         switch (sd->sensor) {
566
567         case SENSOR_TAS5110: {
568                 __u8 i2c[] =
569                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
570
571                 i2c[4] = 255 - gain;
572                 if (i2c_w(gspca_dev, i2c) < 0)
573                         goto err;
574                 break;
575             }
576         case SENSOR_OV6650: {
577                 __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
578                 i2c[3] = gain;
579                 if (i2c_w(gspca_dev, i2c) < 0)
580                         goto err;
581                 break;
582             }
583         }
584         return;
585 err:
586         PDEBUG(D_ERR, "i2c error gain");
587 }
588
589 static void setgain(struct gspca_dev *gspca_dev)
590 {
591         struct sd *sd = (struct sd *) gspca_dev;
592         __u8 gain;
593         __u8 rgb_value;
594
595         gain = sd->gain >> 5;
596
597         /* red and blue gain */
598         rgb_value = gain << 4 | gain;
599         reg_w(gspca_dev, 0x10, &rgb_value, 1);
600         /* green gain */
601         rgb_value = gain;
602         reg_w(gspca_dev, 0x11, &rgb_value, 1);
603
604         if (sd->sensor_has_gain)
605                 setsensorgain(gspca_dev);
606 }
607
608 static void setexposure(struct gspca_dev *gspca_dev)
609 {
610         struct sd *sd = (struct sd *) gspca_dev;
611         /* translate 0 - 255 to a number of fps in a 30 - 1 scale */
612         int fps = 30 - sd->exposure * 29 / 511;
613
614         switch (sd->sensor) {
615         case SENSOR_TAS5110: {
616                 __u8 reg;
617
618                 /* register 19's high nibble contains the sn9c10x clock divider
619                    The high nibble configures the no fps according to the
620                    formula: 60 / high_nibble. With a maximum of 30 fps */
621                 reg = 60 / fps;
622                 if (reg > 15)
623                         reg = 15;
624                 reg = (reg << 4) | 0x0b;
625                 reg_w(gspca_dev, 0x19, &reg, 1);
626                 break;
627             }
628         case SENSOR_OV6650: {
629                 __u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10};
630                 i2c[3] = 30 / fps - 1;
631                 if (i2c[3] > 15)
632                         i2c[3] = 15;
633                 i2c[3] |= 0xc0;
634                 if (i2c_w(gspca_dev, i2c) < 0)
635                         PDEBUG(D_ERR, "i2c error exposure");
636                 break;
637             }
638         }
639 }
640
641
642 static void do_autogain(struct gspca_dev *gspca_dev)
643 {
644         struct sd *sd = (struct sd *) gspca_dev;
645         int avg_lum = atomic_read(&sd->avg_lum);
646
647         if (avg_lum == -1)
648                 return;
649
650         if (sd->autogain_ignore_frames > 0)
651                 sd->autogain_ignore_frames--;
652         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
653                         sd->brightness * DESIRED_AVG_LUM / 127,
654                         AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE))
655                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
656 }
657
658 /* this function is called at probe time */
659 static int sd_config(struct gspca_dev *gspca_dev,
660                         const struct usb_device_id *id)
661 {
662         struct sd *sd = (struct sd *) gspca_dev;
663         struct cam *cam;
664         __u16 product;
665         int sif = 0;
666
667         /* nctrls depends upon the sensor, so we use a per cam copy */
668         memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
669         gspca_dev->sd_desc = &sd->sd_desc;
670
671         sd->fr_h_sz = 12;               /* default size of the frame header */
672         sd->sd_desc.nctrls = 2;         /* default nb of ctrls */
673
674         product = id->idProduct;
675 /*      switch (id->idVendor) { */
676 /*      case 0x0c45:                             * Sonix */
677                 switch (product) {
678                 case 0x6001:                    /* SN9C102 */
679                 case 0x6005:                    /* SN9C101 */
680                 case 0x6007:                    /* SN9C101 */
681                         sd->sensor = SENSOR_TAS5110;
682                         sd->sensor_has_gain = 1;
683                         sd->sd_desc.nctrls = 4;
684                         sd->sd_desc.dq_callback = do_autogain;
685                         sif = 1;
686                         break;
687                 case 0x6009:                    /* SN9C101 */
688                 case 0x600d:                    /* SN9C101 */
689                 case 0x6029:                    /* SN9C101 */
690                         sd->sensor = SENSOR_PAS106;
691                         sif = 1;
692                         break;
693                 case 0x6011:                    /* SN9C101 - SN9C101G */
694                         sd->sensor = SENSOR_OV6650;
695                         sd->sensor_has_gain = 1;
696                         sd->sd_desc.nctrls = 4;
697                         sd->sd_desc.dq_callback = do_autogain;
698                         sif = 1;
699                         break;
700                 case 0x6019:                    /* SN9C101 */
701                 case 0x602c:                    /* SN9C102 */
702                 case 0x602e:                    /* SN9C102 */
703                         sd->sensor = SENSOR_OV7630;
704                         break;
705                 case 0x60b0:                    /* SN9C103 */
706                         sd->sensor = SENSOR_OV7630_3;
707                         sd->fr_h_sz = 18;       /* size of frame header */
708                         break;
709                 case 0x6024:                    /* SN9C102 */
710                 case 0x6025:                    /* SN9C102 */
711                         sd->sensor = SENSOR_TAS5130CXX;
712                         break;
713                 case 0x6028:                    /* SN9C102 */
714                         sd->sensor = SENSOR_PAS202;
715                         break;
716                 case 0x602d:                    /* SN9C102 */
717                         sd->sensor = SENSOR_HV7131R;
718                         break;
719                 case 0x60af:                    /* SN9C103 */
720                         sd->sensor = SENSOR_PAS202;
721                         sd->fr_h_sz = 18;       /* size of frame header (?) */
722                         break;
723                 }
724 /*              break; */
725 /*      } */
726
727         cam = &gspca_dev->cam;
728         cam->dev_name = (char *) id->driver_info;
729         cam->epaddr = 0x01;
730         if (!sif) {
731                 cam->cam_mode = vga_mode;
732                 cam->nmodes = ARRAY_SIZE(vga_mode);
733         } else {
734                 cam->cam_mode = sif_mode;
735                 cam->nmodes = ARRAY_SIZE(sif_mode);
736         }
737         sd->brightness = BRIGHTNESS_DEF;
738         sd->gain = GAIN_DEF;
739         sd->exposure = EXPOSURE_DEF;
740         sd->autogain = AUTOGAIN_DEF;
741         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
742                 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
743         return 0;
744 }
745
746 /* this function is called at open time */
747 static int sd_open(struct gspca_dev *gspca_dev)
748 {
749         reg_r(gspca_dev, 0x00);
750         if (gspca_dev->usb_buf[0] != 0x10)
751                 return -ENODEV;
752         return 0;
753 }
754
755 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
756 {
757         int i;
758         const __u8 *data;
759         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
760
761         i = ARRAY_SIZE(pas106_data);
762         data = pas106_data[0];
763         while (--i >= 0) {
764                 memcpy(&i2c1[2], data, 2);
765                                         /* copy 2 bytes from the template */
766                 if (i2c_w(gspca_dev, i2c1) < 0)
767                         PDEBUG(D_ERR, "i2c error pas106");
768                 data += 2;
769         }
770 }
771
772 /* -- start the camera -- */
773 static void sd_start(struct gspca_dev *gspca_dev)
774 {
775         struct sd *sd = (struct sd *) gspca_dev;
776         int mode, l;
777         const __u8 *sn9c10x;
778         __u8 reg01, reg17;
779         __u8 reg17_19[3];
780         static const __u8 reg15[2] = { 0x28, 0x1e };
781
782         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
783         switch (sd->sensor) {
784         case SENSOR_HV7131R:
785                 sn9c10x = initHv7131;
786                 reg17_19[0] = 0x60;
787                 reg17_19[1] = (mode << 4) | 0x8a;
788                 reg17_19[2] = 0x20;
789                 break;
790         case SENSOR_OV6650:
791                 sn9c10x = initOv6650;
792                 reg17_19[0] = 0x68;
793                 reg17_19[1] = (mode << 4) | 0x8b;
794                 reg17_19[2] = 0x20;
795                 break;
796         case SENSOR_OV7630:
797                 sn9c10x = initOv7630;
798                 reg17_19[0] = 0x68;
799                 reg17_19[1] = (mode << 4) | COMP2;
800                 reg17_19[2] = MCK_INIT1;
801                 break;
802         case SENSOR_OV7630_3:
803                 sn9c10x = initOv7630_3;
804                 reg17_19[0] = 0x68;
805                 reg17_19[1] = (mode << 4) | COMP2;
806                 reg17_19[2] = MCK_INIT1;
807                 break;
808         case SENSOR_PAS106:
809                 sn9c10x = initPas106;
810                 reg17_19[0] = 0x24;             /* 0x28 */
811                 reg17_19[1] = (mode << 4) | COMP1;
812                 reg17_19[2] = MCK_INIT1;
813                 break;
814         case SENSOR_PAS202:
815                 sn9c10x = initPas202;
816                 reg17_19[0] = mode ? 0x24 : 0x20;
817                 reg17_19[1] = (mode << 4) | 0x89;
818                 reg17_19[2] = 0x20;
819                 break;
820         case SENSOR_TAS5110:
821                 sn9c10x = initTas5110;
822                 reg17_19[0] = 0x60;
823                 reg17_19[1] = (mode << 4) | 0x86;
824                 reg17_19[2] = 0x2b;             /* 0xf3; */
825                 break;
826         default:
827 /*      case SENSOR_TAS5130CXX: */
828                 sn9c10x = initTas5130;
829                 reg17_19[0] = 0x60;
830                 reg17_19[1] = (mode << 4) | COMP;
831                 reg17_19[2] = mode ? 0x23 : 0x43;
832                 break;
833         }
834         switch (sd->sensor) {
835         case SENSOR_OV7630:
836                 reg01 = 0x06;
837                 reg17 = 0x29;
838                 l = 0x10;
839                 break;
840         case SENSOR_OV7630_3:
841                 reg01 = 0x44;
842                 reg17 = 0x68;
843                 l = sizeof initOv7630_3;
844                 break;
845         default:
846                 reg01 = sn9c10x[0];
847                 reg17 = sn9c10x[0x17 - 1];
848                 l = 0x1f;
849                 break;
850         }
851
852         /* reg 0x01 bit 2 video transfert on */
853         reg_w(gspca_dev, 0x01, &reg01, 1);
854         /* reg 0x17 SensorClk enable inv Clk 0x60 */
855         reg_w(gspca_dev, 0x17, &reg17, 1);
856 /*fixme: for ov7630 102
857         reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
858         /* Set the registers from the template */
859         reg_w_big(gspca_dev, 0x01, sn9c10x, l);
860         switch (sd->sensor) {
861         case SENSOR_HV7131R:
862                 i2c_w_vector(gspca_dev, hv7131_sensor_init,
863                                 sizeof hv7131_sensor_init);
864                 break;
865         case SENSOR_OV6650:
866                 i2c_w_vector(gspca_dev, ov6650_sensor_init,
867                                 sizeof ov6650_sensor_init);
868                 break;
869         case SENSOR_OV7630:
870                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
871                                 sizeof ov7630_sensor_init_com);
872                 msleep(200);
873                 i2c_w_vector(gspca_dev, ov7630_sensor_init,
874                                 sizeof ov7630_sensor_init);
875                 break;
876         case SENSOR_OV7630_3:
877                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
878                                 sizeof ov7630_sensor_init_com);
879                 msleep(200);
880                 i2c_w_vector(gspca_dev, ov7630_sensor_init_3,
881                                 sizeof ov7630_sensor_init_3);
882                 break;
883         case SENSOR_PAS106:
884                 pas106_i2cinit(gspca_dev);
885                 break;
886         case SENSOR_PAS202:
887                 i2c_w_vector(gspca_dev, pas202_sensor_init,
888                                 sizeof pas202_sensor_init);
889                 break;
890         case SENSOR_TAS5110:
891                 i2c_w_vector(gspca_dev, tas5110_sensor_init,
892                                 sizeof tas5110_sensor_init);
893                 break;
894         default:
895 /*      case SENSOR_TAS5130CXX: */
896                 i2c_w_vector(gspca_dev, tas5130_sensor_init,
897                                 sizeof tas5130_sensor_init);
898                 break;
899         }
900         /* H_size V_size  0x28, 0x1e maybe 640x480 */
901         reg_w(gspca_dev, 0x15, reg15, 2);
902         /* compression register */
903         reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
904         if (sd->sensor != SENSOR_OV7630_3) {
905                 /* H_start */
906                 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
907                 /* V_START */
908                 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
909         }
910         /* reset 0x17 SensorClk enable inv Clk 0x60 */
911                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
912         reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
913         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
914         if (sd->sensor != SENSOR_OV7630_3)
915                 reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
916         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
917         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
918         /* Enable video transfert */
919         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
920         /* Compression */
921         reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
922         msleep(20);
923
924         setgain(gspca_dev);
925         setbrightness(gspca_dev);
926         setexposure(gspca_dev);
927
928         sd->autogain_ignore_frames = 0;
929         atomic_set(&sd->avg_lum, -1);
930 }
931
932 static void sd_stopN(struct gspca_dev *gspca_dev)
933 {
934         __u8 ByteSend;
935
936         ByteSend = 0x09;        /* 0X00 */
937         reg_w(gspca_dev, 0x01, &ByteSend, 1);
938 }
939
940 static void sd_stop0(struct gspca_dev *gspca_dev)
941 {
942 }
943
944 static void sd_close(struct gspca_dev *gspca_dev)
945 {
946 }
947
948 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
949                         struct gspca_frame *frame,      /* target */
950                         unsigned char *data,            /* isoc packet */
951                         int len)                        /* iso packet length */
952 {
953         int i;
954         struct sd *sd = (struct sd *) gspca_dev;
955
956         if (len > 6 && len < 24) {
957                 for (i = 0; i < len - 6; i++) {
958                         if (data[0 + i] == 0xff
959                             && data[1 + i] == 0xff
960                             && data[2 + i] == 0x00
961                             && data[3 + i] == 0xc4
962                             && data[4 + i] == 0xc4
963                             && data[5 + i] == 0x96) {   /* start of frame */
964                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
965                                                         frame, data, 0);
966                                 if (i < (len - 10)) {
967                                         atomic_set(&sd->avg_lum, data[i + 8] +
968                                                         (data[i + 9] << 8));
969                                 } else {
970                                         atomic_set(&sd->avg_lum, -1);
971 #ifdef CONFIG_VIDEO_ADV_DEBUG
972                                         PDEBUG(D_STREAM, "packet too short to "
973                                                 "get avg brightness");
974 #endif
975                                 }
976                                 data += i + sd->fr_h_sz;
977                                 len -= i + sd->fr_h_sz;
978                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
979                                                 frame, data, len);
980                                 return;
981                         }
982                 }
983         }
984         gspca_frame_add(gspca_dev, INTER_PACKET,
985                         frame, data, len);
986 }
987
988 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
989 {
990         struct sd *sd = (struct sd *) gspca_dev;
991
992         sd->brightness = val;
993         if (gspca_dev->streaming)
994                 setbrightness(gspca_dev);
995         return 0;
996 }
997
998 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
999 {
1000         struct sd *sd = (struct sd *) gspca_dev;
1001
1002         *val = sd->brightness;
1003         return 0;
1004 }
1005
1006 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1007 {
1008         struct sd *sd = (struct sd *) gspca_dev;
1009
1010         sd->gain = val;
1011         if (gspca_dev->streaming)
1012                 setgain(gspca_dev);
1013         return 0;
1014 }
1015
1016 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1017 {
1018         struct sd *sd = (struct sd *) gspca_dev;
1019
1020         *val = sd->gain;
1021         return 0;
1022 }
1023
1024 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1025 {
1026         struct sd *sd = (struct sd *) gspca_dev;
1027
1028         sd->exposure = val;
1029         if (gspca_dev->streaming)
1030                 setexposure(gspca_dev);
1031         return 0;
1032 }
1033
1034 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1035 {
1036         struct sd *sd = (struct sd *) gspca_dev;
1037
1038         *val = sd->exposure;
1039         return 0;
1040 }
1041
1042 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1043 {
1044         struct sd *sd = (struct sd *) gspca_dev;
1045
1046         sd->autogain = val;
1047         /* when switching to autogain set defaults to make sure
1048            we are on a valid point of the autogain gain /
1049            exposure knee graph, and give this change time to
1050            take effect before doing autogain. */
1051         if (sd->autogain) {
1052                 sd->exposure = EXPOSURE_DEF;
1053                 sd->gain = GAIN_DEF;
1054                 if (gspca_dev->streaming) {
1055                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1056                         setexposure(gspca_dev);
1057                         setgain(gspca_dev);
1058                 }
1059         }
1060
1061         return 0;
1062 }
1063
1064 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1065 {
1066         struct sd *sd = (struct sd *) gspca_dev;
1067
1068         *val = sd->autogain;
1069         return 0;
1070 }
1071
1072 /* sub-driver description */
1073 static const struct sd_desc sd_desc = {
1074         .name = MODULE_NAME,
1075         .ctrls = sd_ctrls,
1076         .nctrls = ARRAY_SIZE(sd_ctrls),
1077         .config = sd_config,
1078         .open = sd_open,
1079         .start = sd_start,
1080         .stopN = sd_stopN,
1081         .stop0 = sd_stop0,
1082         .close = sd_close,
1083         .pkt_scan = sd_pkt_scan,
1084 };
1085
1086 /* -- module initialisation -- */
1087 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1088 static __devinitdata struct usb_device_id device_table[] = {
1089 #ifndef CONFIG_USB_SN9C102
1090         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1091         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1092         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1093         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1094         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1095         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1096         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1097         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1098         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1099         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1100         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1101         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1102         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1103         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1104         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1105         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1106 #endif
1107         {}
1108 };
1109 MODULE_DEVICE_TABLE(usb, device_table);
1110
1111 /* -- device connect -- */
1112 static int sd_probe(struct usb_interface *intf,
1113                         const struct usb_device_id *id)
1114 {
1115         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1116                                 THIS_MODULE);
1117 }
1118
1119 static struct usb_driver sd_driver = {
1120         .name = MODULE_NAME,
1121         .id_table = device_table,
1122         .probe = sd_probe,
1123         .disconnect = gspca_disconnect,
1124 };
1125
1126 /* -- module insert / remove -- */
1127 static int __init sd_mod_init(void)
1128 {
1129         if (usb_register(&sd_driver) < 0)
1130                 return -1;
1131         PDEBUG(D_PROBE, "v%s registered", version);
1132         return 0;
1133 }
1134 static void __exit sd_mod_exit(void)
1135 {
1136         usb_deregister(&sd_driver);
1137         PDEBUG(D_PROBE, "deregistered");
1138 }
1139
1140 module_init(sd_mod_init);
1141 module_exit(sd_mod_exit);