]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixb.c
7099c3770b3ee629f2e6176267e8f04ea4a3105d
[linux-2.6-omap-h63xx.git] / 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, 8)
28 static const char version[] = "2.1.8";
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         unsigned char freq;             /* light freq filter setting */
48
49         unsigned char fr_h_sz;          /* size of frame header */
50         char sensor;                    /* Type of image sensor chip */
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         char sensor_has_gain;
60         __u8 sensor_addr;
61 };
62
63 #define COMP2 0x8f
64 #define COMP 0xc7               /* 0x87 //0x07 */
65 #define COMP1 0xc9              /* 0x89 //0x09 */
66
67 #define MCK_INIT 0x63
68 #define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
69
70 #define SYS_CLK 0x04
71
72 /* We calculate the autogain at the end of the transfer of a frame, at this
73    moment a frame with the old settings is being transmitted, and a frame is
74    being captured with the old settings. So if we adjust the autogain we must
75    ignore atleast the 2 next frames for the new settings to come into effect
76    before doing any other adjustments */
77 #define AUTOGAIN_IGNORE_FRAMES 3
78 #define AUTOGAIN_DEADZONE 1000
79 #define DESIRED_AVG_LUM 7000
80
81 /* V4L2 controls supported by the driver */
82 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
92
93 static struct ctrl sd_ctrls[] = {
94         {
95             {
96                 .id      = V4L2_CID_BRIGHTNESS,
97                 .type    = V4L2_CTRL_TYPE_INTEGER,
98                 .name    = "Brightness",
99                 .minimum = 0,
100                 .maximum = 255,
101                 .step    = 1,
102 #define BRIGHTNESS_DEF 127
103                 .default_value = BRIGHTNESS_DEF,
104             },
105             .set = sd_setbrightness,
106             .get = sd_getbrightness,
107         },
108         {
109             {
110                 .id      = V4L2_CID_GAIN,
111                 .type    = V4L2_CTRL_TYPE_INTEGER,
112                 .name    = "Gain",
113                 .minimum = 0,
114                 .maximum = 255,
115                 .step    = 1,
116 #define GAIN_DEF 127
117 #define GAIN_KNEE 200
118                 .default_value = GAIN_DEF,
119             },
120             .set = sd_setgain,
121             .get = sd_getgain,
122         },
123         {
124                 {
125                         .id = V4L2_CID_EXPOSURE,
126                         .type = V4L2_CTRL_TYPE_INTEGER,
127                         .name = "Exposure",
128 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
129 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
130                         .minimum = 0,
131                         .maximum = 255,
132                         .step = 1,
133                         .default_value = EXPOSURE_DEF,
134                         .flags = 0,
135                 },
136                 .set = sd_setexposure,
137                 .get = sd_getexposure,
138         },
139         {
140                 {
141                         .id = V4L2_CID_AUTOGAIN,
142                         .type = V4L2_CTRL_TYPE_BOOLEAN,
143                         .name = "Automatic Gain (and Exposure)",
144                         .minimum = 0,
145                         .maximum = 1,
146                         .step = 1,
147 #define AUTOGAIN_DEF 1
148                         .default_value = AUTOGAIN_DEF,
149                         .flags = 0,
150                 },
151                 .set = sd_setautogain,
152                 .get = sd_getautogain,
153         },
154         {
155                 {
156                         .id      = V4L2_CID_POWER_LINE_FREQUENCY,
157                         .type    = V4L2_CTRL_TYPE_MENU,
158                         .name    = "Light frequency filter",
159                         .minimum = 0,
160                         .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
161                         .step    = 1,
162 #define FREQ_DEF 1
163                         .default_value = FREQ_DEF,
164                 },
165                 .set = sd_setfreq,
166                 .get = sd_getfreq,
167         },
168 };
169
170 static struct v4l2_pix_format vga_mode[] = {
171         {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
172                 .bytesperline = 160,
173                 .sizeimage = 160 * 120,
174                 .colorspace = V4L2_COLORSPACE_SRGB,
175                 .priv = 2},
176         {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
177                 .bytesperline = 320,
178                 .sizeimage = 320 * 240,
179                 .colorspace = V4L2_COLORSPACE_SRGB,
180                 .priv = 1},
181         {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
182                 .bytesperline = 640,
183                 .sizeimage = 640 * 480,
184                 .colorspace = V4L2_COLORSPACE_SRGB,
185                 .priv = 0},
186 };
187 static struct v4l2_pix_format sif_mode[] = {
188         {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
189                 .bytesperline = 176,
190                 .sizeimage = 176 * 144,
191                 .colorspace = V4L2_COLORSPACE_SRGB,
192                 .priv = 1},
193         {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
194                 .bytesperline = 352,
195                 .sizeimage = 352 * 288,
196                 .colorspace = V4L2_COLORSPACE_SRGB,
197                 .priv = 0},
198 };
199
200 static const __u8 probe_ov7630[] = {0x08, 0x44};
201
202 static const __u8 initHv7131[] = {
203         0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
204         0x00, 0x00,
205         0x00, 0x00, 0x00, 0x03, 0x01, 0x00,     /* shift from 0x02 0x01 0x00 */
206         0x28, 0x1e, 0x60, 0x8a, 0x20,
207         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
208 };
209 static const __u8 hv7131_sensor_init[][8] = {
210         {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
211         {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
212         {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
213         {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
214         {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
215 };
216 static const __u8 initOv6650[] = {
217         0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
218         0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219         0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
220         0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
221 };
222 static const __u8 ov6650_sensor_init[][8] =
223 {
224         /* Bright, contrast, etc are set througth SCBB interface.
225          * AVCAP on win2 do not send any data on this   controls. */
226         /* Anyway, some registers appears to alter bright and constrat */
227
228         /* Reset sensor */
229         {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
230         /* Set clock register 0x11 low nibble is clock divider */
231         {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
232         /* Next some unknown stuff */
233         {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
234 /*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
235                  * THIS SET GREEN SCREEN
236                  * (pixels could be innverted in decode kind of "brg",
237                  * but blue wont be there. Avoid this data ... */
238         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
239         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
240         {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
241         /* Disable autobright ? */
242         {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10},
243         /* Some more unknown stuff */
244         {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
245         {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
246 };
247
248 static const __u8 initOv7630[] = {
249         0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
250         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
251         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
252         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
253         0x68, COMP1, MCK_INIT1,                         /* r17 .. r19 */
254         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
255 };
256 static const __u8 initOv7630_3[] = {
257         0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
258         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
259         0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
260         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
261         0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
262         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,       /* r1a .. r20 */
263         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
264         0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
265 };
266 static const __u8 ov7630_sensor_init_com[][8] = {
267         {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
268         {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
269 /*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
270         {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
271         {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
272         {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
273         {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
274         {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
275         {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
276         {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
277         {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
278         {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
279 /*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
280         {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
281         {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
282         {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
283         {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
284         {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
285         {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
286 };
287 static const __u8 ov7630_sensor_init[][8] = {
288         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
289         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10},       /* jfm */
290         {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
291         {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
292         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
293 };
294 static const __u8 ov7630_sensor_init_3[][8] = {
295         {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
296         {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
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         case  SENSOR_OV7630_3:
488         case  SENSOR_OV7630: {
489                 __u8 i2cOV[] =
490                         {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
491
492                 /* change reg 0x06 */
493                 i2cOV[1] = sd->sensor_addr;
494                 i2cOV[3] = sd->brightness;
495                 if (i2c_w(gspca_dev, i2cOV) < 0)
496                         goto err;
497                 break;
498             }
499         case SENSOR_PAS106: {
500                 __u8 i2c1[] =
501                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
502
503                 i2c1[3] = sd->brightness >> 3;
504                 i2c1[2] = 0x0e;
505                 if (i2c_w(gspca_dev, i2c1) < 0)
506                         goto err;
507                 i2c1[3] = 0x01;
508                 i2c1[2] = 0x13;
509                 if (i2c_w(gspca_dev, i2c1) < 0)
510                         goto err;
511                 break;
512             }
513         case SENSOR_PAS202: {
514                 /* __u8 i2cpexpo1[] =
515                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
516                 __u8 i2cpexpo[] =
517                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
518                 __u8 i2cp202[] =
519                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
520                 static __u8 i2cpdoit[] =
521                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
522
523                 /* change reg 0x10 */
524                 i2cpexpo[4] = 0xff - sd->brightness;
525 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
526                         goto err; */
527 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
528                         goto err; */
529                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
530                         goto err;
531                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
532                         goto err;
533                 i2cp202[3] = sd->brightness >> 3;
534                 if (i2c_w(gspca_dev, i2cp202) < 0)
535                         goto err;
536                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
537                         goto err;
538                 break;
539             }
540         case SENSOR_TAS5130CXX: {
541                 __u8 i2c[] =
542                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
543
544                 value = 0xff - sd->brightness;
545                 i2c[4] = value;
546                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
547                 if (i2c_w(gspca_dev, i2c) < 0)
548                         goto err;
549                 break;
550             }
551         case SENSOR_TAS5110:
552                 /* FIXME figure out howto control brightness on TAS5110 */
553                 break;
554         }
555         return;
556 err:
557         PDEBUG(D_ERR, "i2c error brightness");
558 }
559
560 static void setsensorgain(struct gspca_dev *gspca_dev)
561 {
562         struct sd *sd = (struct sd *) gspca_dev;
563         unsigned char gain = sd->gain;
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
577         case SENSOR_OV6650:
578                 gain >>= 1;
579                 /* fall thru */
580         case SENSOR_OV7630_3: {
581                 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
582
583                 i2c[1] = sd->sensor_addr;
584                 i2c[3] = gain >> 2;
585                 if (i2c_w(gspca_dev, i2c) < 0)
586                         goto err;
587                 break;
588             }
589         }
590         return;
591 err:
592         PDEBUG(D_ERR, "i2c error gain");
593 }
594
595 static void setgain(struct gspca_dev *gspca_dev)
596 {
597         struct sd *sd = (struct sd *) gspca_dev;
598         __u8 gain;
599         __u8 rgb_value;
600
601         gain = sd->gain >> 4;
602
603         /* red and blue gain */
604         rgb_value = gain << 4 | gain;
605         reg_w(gspca_dev, 0x10, &rgb_value, 1);
606         /* green gain */
607         rgb_value = gain;
608         reg_w(gspca_dev, 0x11, &rgb_value, 1);
609
610         if (sd->sensor_has_gain)
611                 setsensorgain(gspca_dev);
612 }
613
614 static void setexposure(struct gspca_dev *gspca_dev)
615 {
616         struct sd *sd = (struct sd *) gspca_dev;
617
618         switch (sd->sensor) {
619         case SENSOR_TAS5110: {
620                 __u8 reg;
621
622                 /* register 19's high nibble contains the sn9c10x clock divider
623                    The high nibble configures the no fps according to the
624                    formula: 60 / high_nibble. With a maximum of 30 fps */
625                 reg = 120 * sd->exposure / 1000;
626                 if (reg < 2)
627                         reg = 2;
628                 else if (reg > 15)
629                         reg = 15;
630                 reg = (reg << 4) | 0x0b;
631                 reg_w(gspca_dev, 0x19, &reg, 1);
632                 break;
633             }
634         case SENSOR_OV6650:
635         case SENSOR_OV7630_3: {
636                 /* The ov6650 / ov7630 have 2 registers which both influence
637                    exposure, register 11, whose low nibble sets the nr off fps
638                    according to: fps = 30 / (low_nibble + 1)
639
640                    The fps configures the maximum exposure setting, but it is
641                    possible to use less exposure then what the fps maximum
642                    allows by setting register 10. register 10 configures the
643                    actual exposure as quotient of the full exposure, with 0
644                    being no exposure at all (not very usefull) and reg10_max
645                    being max exposure possible at that framerate.
646
647                    The code maps our 0 - 510 ms exposure ctrl to these 2
648                    registers, trying to keep fps as high as possible.
649                 */
650                 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
651                 int reg10, reg11;
652                 /* ov6645 datasheet says reg10_max is 9a, but that uses
653                    tline * 2 * reg10 as formula for calculating texpo, the
654                    ov6650 probably uses the same formula as the 7730 which uses
655                    tline * 4 * reg10, which explains why the reg10max we've
656                    found experimentally for the ov6650 is exactly half that of
657                    the ov6645. The ov7630 datasheet says the max is 0x41. */
658                 const int reg10_max = (sd->sensor == SENSOR_OV6650)? 0x4d:0x41;
659
660                 reg11 = (60 * sd->exposure + 999) / 1000;
661                 if (reg11 < 1)
662                         reg11 = 1;
663                 else if (reg11 > 16)
664                         reg11 = 16;
665
666                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
667                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
668                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
669
670                 /* Don't allow this to get below 10 when using autogain, the
671                    steps become very large (relatively) when below 10 causing
672                    the image to oscilate from much too dark, to much too bright
673                    and back again. */
674                 if (sd->autogain && reg10 < 10)
675                         reg10 = 10;
676                 else if (reg10 > reg10_max)
677                         reg10 = reg10_max;
678
679                 /* Write reg 10 and reg11 low nibble */
680                 i2c[1] = sd->sensor_addr;
681                 i2c[3] = reg10;
682                 i2c[4] |= reg11 - 1;
683                 if (sd->sensor == SENSOR_OV7630_3) {
684                         __u8 reg76 = reg10 & 0x03;
685                         __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
686                                             0x00, 0x00, 0x00, 0x10};
687                         reg10 >>= 2;
688                         i2c_reg76[3] = reg76;
689                         if (i2c_w(gspca_dev, i2c_reg76) < 0)
690                                 PDEBUG(D_ERR, "i2c error exposure");
691                 }
692                 if (i2c_w(gspca_dev, i2c) < 0)
693                         PDEBUG(D_ERR, "i2c error exposure");
694                 break;
695             }
696         }
697 }
698
699 static void setfreq(struct gspca_dev *gspca_dev)
700 {
701         struct sd *sd = (struct sd *) gspca_dev;
702
703         switch (sd->sensor) {
704         case SENSOR_OV6650:
705         case SENSOR_OV7630_3: {
706                 /* Framerate adjust register for artificial light 50 hz flicker
707                    compensation, identical to ov6630 0x2b register, see ov6630
708                    datasheet.
709                    0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
710                 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
711                 switch (sd->freq) {
712                 default:
713 /*              case 0:                  * no filter*/
714 /*              case 2:                  * 60 hz */
715                         i2c[3] = 0;
716                         break;
717                 case 1:                 /* 50 hz */
718                         i2c[3] = (sd->sensor == SENSOR_OV6650)? 0x4f:0x8a;
719                         break;
720                 }
721                 i2c[1] = sd->sensor_addr;
722                 if (i2c_w(gspca_dev, i2c) < 0)
723                         PDEBUG(D_ERR, "i2c error setfreq");
724                 break;
725             }
726         }
727 }
728
729
730 static void do_autogain(struct gspca_dev *gspca_dev)
731 {
732         struct sd *sd = (struct sd *) gspca_dev;
733         int avg_lum = atomic_read(&sd->avg_lum);
734
735         if (avg_lum == -1)
736                 return;
737
738         if (sd->autogain_ignore_frames > 0)
739                 sd->autogain_ignore_frames--;
740         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
741                         sd->brightness * DESIRED_AVG_LUM / 127,
742                         AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
743                 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
744                         (int)sd->gain, (int)sd->exposure);
745                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
746         }
747 }
748
749 /* this function is called at probe time */
750 static int sd_config(struct gspca_dev *gspca_dev,
751                         const struct usb_device_id *id)
752 {
753         struct sd *sd = (struct sd *) gspca_dev;
754         struct cam *cam;
755         __u16 product;
756         int sif = 0;
757
758         /* nctrls depends upon the sensor, so we use a per cam copy */
759         memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
760         gspca_dev->sd_desc = &sd->sd_desc;
761
762         sd->fr_h_sz = 12;               /* default size of the frame header */
763         sd->sd_desc.nctrls = 2;         /* default nb of ctrls */
764         sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
765         sd->freq = FREQ_DEF;
766
767         product = id->idProduct;
768 /*      switch (id->idVendor) { */
769 /*      case 0x0c45:                             * Sonix */
770                 switch (product) {
771                 case 0x6001:                    /* SN9C102 */
772                 case 0x6005:                    /* SN9C101 */
773                 case 0x6007:                    /* SN9C101 */
774                         sd->sensor = SENSOR_TAS5110;
775                         sd->sensor_has_gain = 1;
776                         sd->sd_desc.nctrls = 4;
777                         sd->sd_desc.dq_callback = do_autogain;
778                         sif = 1;
779                         break;
780                 case 0x6009:                    /* SN9C101 */
781                 case 0x600d:                    /* SN9C101 */
782                 case 0x6029:                    /* SN9C101 */
783                         sd->sensor = SENSOR_PAS106;
784                         sif = 1;
785                         break;
786                 case 0x6011:                    /* SN9C101 - SN9C101G */
787                         sd->sensor = SENSOR_OV6650;
788                         sd->sensor_has_gain = 1;
789                         sd->sensor_addr = 0x60;
790                         sd->sd_desc.nctrls = 4;
791                         sd->sd_desc.dq_callback = do_autogain;
792                         sif = 1;
793                         break;
794                 case 0x6019:                    /* SN9C101 */
795                 case 0x602c:                    /* SN9C102 */
796                 case 0x602e:                    /* SN9C102 */
797                         sd->sensor = SENSOR_OV7630;
798                         sd->sensor_addr = 0x21;
799                         break;
800                 case 0x60b0:                    /* SN9C103 */
801                         sd->sensor = SENSOR_OV7630_3;
802                         sd->sensor_addr = 0x21;
803                         sd->fr_h_sz = 18;       /* size of frame header */
804                         sd->sensor_has_gain = 1;
805                         sd->sd_desc.nctrls = 5;
806                         sd->sd_desc.dq_callback = do_autogain;
807                         sd->autogain = 0;
808                         break;
809                 case 0x6024:                    /* SN9C102 */
810                 case 0x6025:                    /* SN9C102 */
811                         sd->sensor = SENSOR_TAS5130CXX;
812                         break;
813                 case 0x6028:                    /* SN9C102 */
814                         sd->sensor = SENSOR_PAS202;
815                         break;
816                 case 0x602d:                    /* SN9C102 */
817                         sd->sensor = SENSOR_HV7131R;
818                         break;
819                 case 0x60af:                    /* SN9C103 */
820                         sd->sensor = SENSOR_PAS202;
821                         sd->fr_h_sz = 18;       /* size of frame header (?) */
822                         break;
823                 }
824 /*              break; */
825 /*      } */
826
827         cam = &gspca_dev->cam;
828         cam->dev_name = (char *) id->driver_info;
829         cam->epaddr = 0x01;
830         if (!sif) {
831                 cam->cam_mode = vga_mode;
832                 cam->nmodes = ARRAY_SIZE(vga_mode);
833                 if (sd->sensor == SENSOR_OV7630_3) {
834                         /* We only have 320x240 & 640x480 */
835                         cam->cam_mode++;
836                         cam->nmodes--;
837                 }
838         } else {
839                 cam->cam_mode = sif_mode;
840                 cam->nmodes = ARRAY_SIZE(sif_mode);
841         }
842         sd->brightness = BRIGHTNESS_DEF;
843         sd->gain = GAIN_DEF;
844         sd->exposure = EXPOSURE_DEF;
845         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
846                 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
847         return 0;
848 }
849
850 /* this function is called at open time */
851 static int sd_open(struct gspca_dev *gspca_dev)
852 {
853         reg_r(gspca_dev, 0x00);
854         if (gspca_dev->usb_buf[0] != 0x10)
855                 return -ENODEV;
856         return 0;
857 }
858
859 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
860 {
861         int i;
862         const __u8 *data;
863         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
864
865         i = ARRAY_SIZE(pas106_data);
866         data = pas106_data[0];
867         while (--i >= 0) {
868                 memcpy(&i2c1[2], data, 2);
869                                         /* copy 2 bytes from the template */
870                 if (i2c_w(gspca_dev, i2c1) < 0)
871                         PDEBUG(D_ERR, "i2c error pas106");
872                 data += 2;
873         }
874 }
875
876 /* -- start the camera -- */
877 static void sd_start(struct gspca_dev *gspca_dev)
878 {
879         struct sd *sd = (struct sd *) gspca_dev;
880         int mode, l;
881         const __u8 *sn9c10x;
882         __u8 reg01, reg17;
883         __u8 reg17_19[3];
884
885         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
886         switch (sd->sensor) {
887         case SENSOR_HV7131R:
888                 sn9c10x = initHv7131;
889                 reg17_19[0] = 0x60;
890                 reg17_19[1] = (mode << 4) | 0x8a;
891                 reg17_19[2] = 0x20;
892                 break;
893         case SENSOR_OV6650:
894                 sn9c10x = initOv6650;
895                 reg17_19[0] = 0x68;
896                 reg17_19[1] = (mode << 4) | 0x8b;
897                 reg17_19[2] = 0x20;
898                 break;
899         case SENSOR_OV7630:
900                 sn9c10x = initOv7630;
901                 reg17_19[0] = 0x68;
902                 reg17_19[1] = (mode << 4) | COMP2;
903                 reg17_19[2] = MCK_INIT1;
904                 break;
905         case SENSOR_OV7630_3:
906                 sn9c10x = initOv7630_3;
907                 reg17_19[0] = 0x68;
908                 reg17_19[1] = (mode << 4) | COMP2;
909                 reg17_19[2] = MCK_INIT1;
910                 break;
911         case SENSOR_PAS106:
912                 sn9c10x = initPas106;
913                 reg17_19[0] = 0x24;             /* 0x28 */
914                 reg17_19[1] = (mode << 4) | COMP1;
915                 reg17_19[2] = MCK_INIT1;
916                 break;
917         case SENSOR_PAS202:
918                 sn9c10x = initPas202;
919                 reg17_19[0] = mode ? 0x24 : 0x20;
920                 reg17_19[1] = (mode << 4) | 0x89;
921                 reg17_19[2] = 0x20;
922                 break;
923         case SENSOR_TAS5110:
924                 sn9c10x = initTas5110;
925                 reg17_19[0] = 0x60;
926                 reg17_19[1] = (mode << 4) | 0x86;
927                 reg17_19[2] = 0x2b;             /* 0xf3; */
928                 break;
929         default:
930 /*      case SENSOR_TAS5130CXX: */
931                 sn9c10x = initTas5130;
932                 reg17_19[0] = 0x60;
933                 reg17_19[1] = (mode << 4) | COMP;
934                 reg17_19[2] = mode ? 0x23 : 0x43;
935                 break;
936         }
937         switch (sd->sensor) {
938         case SENSOR_OV7630:
939                 reg01 = 0x06;
940                 reg17 = 0x29;
941                 l = sizeof initOv7630;
942                 break;
943         case SENSOR_OV7630_3:
944                 reg01 = 0x44;
945                 reg17 = 0x68;
946                 l = sizeof initOv7630_3;
947                 break;
948         default:
949                 reg01 = sn9c10x[0];
950                 reg17 = sn9c10x[0x17 - 1];
951                 l = 0x1f;
952                 break;
953         }
954
955         /* reg 0x01 bit 2 video transfert on */
956         reg_w(gspca_dev, 0x01, &reg01, 1);
957         /* reg 0x17 SensorClk enable inv Clk 0x60 */
958         reg_w(gspca_dev, 0x17, &reg17, 1);
959 /*fixme: for ov7630 102
960         reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
961         /* Set the registers from the template */
962         reg_w_big(gspca_dev, 0x01, sn9c10x, l);
963         switch (sd->sensor) {
964         case SENSOR_HV7131R:
965                 i2c_w_vector(gspca_dev, hv7131_sensor_init,
966                                 sizeof hv7131_sensor_init);
967                 break;
968         case SENSOR_OV6650:
969                 i2c_w_vector(gspca_dev, ov6650_sensor_init,
970                                 sizeof ov6650_sensor_init);
971                 break;
972         case SENSOR_OV7630:
973                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
974                                 sizeof ov7630_sensor_init_com);
975                 msleep(200);
976                 i2c_w_vector(gspca_dev, ov7630_sensor_init,
977                                 sizeof ov7630_sensor_init);
978                 break;
979         case SENSOR_OV7630_3:
980                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
981                                 sizeof ov7630_sensor_init_com);
982                 msleep(200);
983                 i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
984                 break;
985         case SENSOR_PAS106:
986                 pas106_i2cinit(gspca_dev);
987                 break;
988         case SENSOR_PAS202:
989                 i2c_w_vector(gspca_dev, pas202_sensor_init,
990                                 sizeof pas202_sensor_init);
991                 break;
992         case SENSOR_TAS5110:
993                 i2c_w_vector(gspca_dev, tas5110_sensor_init,
994                                 sizeof tas5110_sensor_init);
995                 break;
996         default:
997 /*      case SENSOR_TAS5130CXX: */
998                 i2c_w_vector(gspca_dev, tas5130_sensor_init,
999                                 sizeof tas5130_sensor_init);
1000                 break;
1001         }
1002         /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1003         reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
1004         /* compression register */
1005         reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
1006         /* H_start */
1007         reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
1008         /* V_START */
1009         reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
1010         /* reset 0x17 SensorClk enable inv Clk 0x60 */
1011                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1012         reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
1013         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
1014         reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
1015         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1016         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
1017         /* Enable video transfert */
1018         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
1019         /* Compression */
1020         reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
1021         msleep(20);
1022
1023         setgain(gspca_dev);
1024         setbrightness(gspca_dev);
1025         setexposure(gspca_dev);
1026         setfreq(gspca_dev);
1027
1028         sd->autogain_ignore_frames = 0;
1029         atomic_set(&sd->avg_lum, -1);
1030 }
1031
1032 static void sd_stopN(struct gspca_dev *gspca_dev)
1033 {
1034         __u8 ByteSend;
1035
1036         ByteSend = 0x09;        /* 0X00 */
1037         reg_w(gspca_dev, 0x01, &ByteSend, 1);
1038 }
1039
1040 static void sd_stop0(struct gspca_dev *gspca_dev)
1041 {
1042 }
1043
1044 static void sd_close(struct gspca_dev *gspca_dev)
1045 {
1046 }
1047
1048 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1049                         struct gspca_frame *frame,      /* target */
1050                         unsigned char *data,            /* isoc packet */
1051                         int len)                        /* iso packet length */
1052 {
1053         int i;
1054         struct sd *sd = (struct sd *) gspca_dev;
1055
1056         /* frames start with:
1057          *      ff ff 00 c4 c4 96       synchro
1058          *      00              (unknown)
1059          *      xx              (frame sequence / size / compression)
1060          *      (xx)            (idem - extra byte for sn9c103)
1061          *      ll mm           brightness sum inside auto exposure
1062          *      ll mm           brightness sum outside auto exposure
1063          *      (xx xx xx xx xx)        audio values for snc103
1064          */
1065         if (len > 6 && len < 24) {
1066                 for (i = 0; i < len - 6; i++) {
1067                         if (data[0 + i] == 0xff
1068                             && data[1 + i] == 0xff
1069                             && data[2 + i] == 0x00
1070                             && data[3 + i] == 0xc4
1071                             && data[4 + i] == 0xc4
1072                             && data[5 + i] == 0x96) {   /* start of frame */
1073                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
1074                                                         frame, data, 0);
1075                                 if (len - i < sd->fr_h_sz) {
1076                                         atomic_set(&sd->avg_lum, -1);
1077                                         PDEBUG(D_STREAM, "packet too short to"
1078                                                 " get avg brightness");
1079                                 } else if (sd->fr_h_sz == 12) {
1080                                         atomic_set(&sd->avg_lum,
1081                                                 data[i + 8] +
1082                                                         (data[i + 9] << 8));
1083                                 } else {
1084                                         atomic_set(&sd->avg_lum,
1085                                                 data[i + 9] +
1086                                                         (data[i + 10] << 8));
1087                                 }
1088                                 data += i + sd->fr_h_sz;
1089                                 len -= i + sd->fr_h_sz;
1090                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1091                                                 frame, data, len);
1092                                 return;
1093                         }
1094                 }
1095         }
1096         gspca_frame_add(gspca_dev, INTER_PACKET,
1097                         frame, data, len);
1098 }
1099
1100 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1101 {
1102         struct sd *sd = (struct sd *) gspca_dev;
1103
1104         sd->brightness = val;
1105         if (gspca_dev->streaming)
1106                 setbrightness(gspca_dev);
1107         return 0;
1108 }
1109
1110 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1111 {
1112         struct sd *sd = (struct sd *) gspca_dev;
1113
1114         *val = sd->brightness;
1115         return 0;
1116 }
1117
1118 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1119 {
1120         struct sd *sd = (struct sd *) gspca_dev;
1121
1122         sd->gain = val;
1123         if (gspca_dev->streaming)
1124                 setgain(gspca_dev);
1125         return 0;
1126 }
1127
1128 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1129 {
1130         struct sd *sd = (struct sd *) gspca_dev;
1131
1132         *val = sd->gain;
1133         return 0;
1134 }
1135
1136 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1137 {
1138         struct sd *sd = (struct sd *) gspca_dev;
1139
1140         sd->exposure = val;
1141         if (gspca_dev->streaming)
1142                 setexposure(gspca_dev);
1143         return 0;
1144 }
1145
1146 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1147 {
1148         struct sd *sd = (struct sd *) gspca_dev;
1149
1150         *val = sd->exposure;
1151         return 0;
1152 }
1153
1154 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1155 {
1156         struct sd *sd = (struct sd *) gspca_dev;
1157
1158         sd->autogain = val;
1159         /* when switching to autogain set defaults to make sure
1160            we are on a valid point of the autogain gain /
1161            exposure knee graph, and give this change time to
1162            take effect before doing autogain. */
1163         if (sd->autogain) {
1164                 sd->exposure = EXPOSURE_DEF;
1165                 sd->gain = GAIN_DEF;
1166                 if (gspca_dev->streaming) {
1167                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1168                         setexposure(gspca_dev);
1169                         setgain(gspca_dev);
1170                 }
1171         }
1172
1173         return 0;
1174 }
1175
1176 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1177 {
1178         struct sd *sd = (struct sd *) gspca_dev;
1179
1180         *val = sd->autogain;
1181         return 0;
1182 }
1183
1184 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1185 {
1186         struct sd *sd = (struct sd *) gspca_dev;
1187
1188         sd->freq = val;
1189         if (gspca_dev->streaming)
1190                 setfreq(gspca_dev);
1191         return 0;
1192 }
1193
1194 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1195 {
1196         struct sd *sd = (struct sd *) gspca_dev;
1197
1198         *val = sd->freq;
1199         return 0;
1200 }
1201
1202 static int sd_querymenu(struct gspca_dev *gspca_dev,
1203                         struct v4l2_querymenu *menu)
1204 {
1205         switch (menu->id) {
1206         case V4L2_CID_POWER_LINE_FREQUENCY:
1207                 switch (menu->index) {
1208                 case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1209                         strcpy((char *) menu->name, "NoFliker");
1210                         return 0;
1211                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1212                         strcpy((char *) menu->name, "50 Hz");
1213                         return 0;
1214                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1215                         strcpy((char *) menu->name, "60 Hz");
1216                         return 0;
1217                 }
1218                 break;
1219         }
1220         return -EINVAL;
1221 }
1222
1223 /* sub-driver description */
1224 static const struct sd_desc sd_desc = {
1225         .name = MODULE_NAME,
1226         .ctrls = sd_ctrls,
1227         .nctrls = ARRAY_SIZE(sd_ctrls),
1228         .config = sd_config,
1229         .open = sd_open,
1230         .start = sd_start,
1231         .stopN = sd_stopN,
1232         .stop0 = sd_stop0,
1233         .close = sd_close,
1234         .pkt_scan = sd_pkt_scan,
1235         .querymenu = sd_querymenu,
1236 };
1237
1238 /* -- module initialisation -- */
1239 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1240 static __devinitdata struct usb_device_id device_table[] = {
1241 #ifndef CONFIG_USB_SN9C102
1242         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1243         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1244         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1245         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1246         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1247         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1248         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1249         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1250         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1251         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1252         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1253         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1254         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1255         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1256         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1257         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1258 #endif
1259         {}
1260 };
1261 MODULE_DEVICE_TABLE(usb, device_table);
1262
1263 /* -- device connect -- */
1264 static int sd_probe(struct usb_interface *intf,
1265                         const struct usb_device_id *id)
1266 {
1267         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1268                                 THIS_MODULE);
1269 }
1270
1271 static struct usb_driver sd_driver = {
1272         .name = MODULE_NAME,
1273         .id_table = device_table,
1274         .probe = sd_probe,
1275         .disconnect = gspca_disconnect,
1276 };
1277
1278 /* -- module insert / remove -- */
1279 static int __init sd_mod_init(void)
1280 {
1281         if (usb_register(&sd_driver) < 0)
1282                 return -1;
1283         PDEBUG(D_PROBE, "v%s registered", version);
1284         return 0;
1285 }
1286 static void __exit sd_mod_exit(void)
1287 {
1288         usb_deregister(&sd_driver);
1289         PDEBUG(D_PROBE, "deregistered");
1290 }
1291
1292 module_init(sd_mod_init);
1293 module_exit(sd_mod_exit);