]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixb.c
V4L/DVB (8372): gspca: Small ov6650 fixes.
[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         /* Enable rgb brightness control */
242         {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
243         /* HDG: Note windows uses the line below, which sets both register 0x60
244            and 0x61 I believe these registers of the ov6650 are identical as
245            those of the ov7630, because if this is true the windows settings
246            add a bit additional red gain and a lot additional blue gain, which
247            matches my findings that the windows settings make blue much too
248            blue and red a little too red.
249         {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
250         /* Some more unknown stuff */
251         {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
252         {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
253 };
254
255 static const __u8 initOv7630[] = {
256         0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
257         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
258         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
259         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
260         0x68, COMP1, MCK_INIT1,                         /* r17 .. r19 */
261         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
262 };
263 static const __u8 initOv7630_3[] = {
264         0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
265         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
266         0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
267         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
268         0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
269         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,       /* r1a .. r20 */
270         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
271         0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
272 };
273 static const __u8 ov7630_sensor_init_com[][8] = {
274         {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
275         {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
276 /*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
277         {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
278         {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
279         {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
280         {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
281         {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
282         {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
283         {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
284         {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
285         {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
286 /*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
287         {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
288         {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
289         {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
290         {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
291         {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
292         {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
293 };
294 static const __u8 ov7630_sensor_init[][8] = {
295         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
296         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10},       /* jfm */
297         {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
298         {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
299         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
300 };
301 static const __u8 ov7630_sensor_init_3[][8] = {
302         {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
303         {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
304 };
305
306 static const __u8 initPas106[] = {
307         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
308         0x00, 0x00,
309         0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
310         0x16, 0x12, 0x28, COMP1, MCK_INIT1,
311         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
312 };
313 /* compression 0x86 mckinit1 0x2b */
314 static const __u8 pas106_data[][2] = {
315         {0x02, 0x04},           /* Pixel Clock Divider 6 */
316         {0x03, 0x13},           /* Frame Time MSB */
317 /*      {0x03, 0x12},            * Frame Time MSB */
318         {0x04, 0x06},           /* Frame Time LSB */
319 /*      {0x04, 0x05},            * Frame Time LSB */
320         {0x05, 0x65},           /* Shutter Time Line Offset */
321 /*      {0x05, 0x6d},            * Shutter Time Line Offset */
322 /*      {0x06, 0xb1},            * Shutter Time Pixel Offset */
323         {0x06, 0xcd},           /* Shutter Time Pixel Offset */
324         {0x07, 0xc1},           /* Black Level Subtract Sign */
325 /*      {0x07, 0x00},            * Black Level Subtract Sign */
326         {0x08, 0x06},           /* Black Level Subtract Level */
327         {0x08, 0x06},           /* Black Level Subtract Level */
328 /*      {0x08, 0x01},            * Black Level Subtract Level */
329         {0x09, 0x05},           /* Color Gain B Pixel 5 a */
330         {0x0a, 0x04},           /* Color Gain G1 Pixel 1 5 */
331         {0x0b, 0x04},           /* Color Gain G2 Pixel 1 0 5 */
332         {0x0c, 0x05},           /* Color Gain R Pixel 3 1 */
333         {0x0d, 0x00},           /* Color GainH  Pixel */
334         {0x0e, 0x0e},           /* Global Gain */
335         {0x0f, 0x00},           /* Contrast */
336         {0x10, 0x06},           /* H&V synchro polarity */
337         {0x11, 0x06},           /* ?default */
338         {0x12, 0x06},           /* DAC scale */
339         {0x14, 0x02},           /* ?default */
340         {0x13, 0x01},           /* Validate Settings */
341 };
342 static const __u8 initPas202[] = {
343         0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
344         0x00, 0x00,
345         0x00, 0x00, 0x00, 0x07, 0x03, 0x0a,     /* 6 */
346         0x28, 0x1e, 0x28, 0x89, 0x30,
347         0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
348 };
349 static const __u8 pas202_sensor_init[][8] = {
350         {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
351         {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
352         {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
353         {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
354         {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
355         {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
356         {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
357         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
358         {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
359         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
360         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
361         {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
362
363         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
364         {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
365         {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
366         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
367         {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
368         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
369         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
370         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
371 };
372
373 static const __u8 initTas5110[] = {
374         0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
375         0x00, 0x00,
376         0x00, 0x01, 0x00, 0x46, 0x09, 0x0a,     /* shift from 0x45 0x09 0x0a */
377         0x16, 0x12, 0x60, 0x86, 0x2b,
378         0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
379 };
380 static const __u8 tas5110_sensor_init[][8] = {
381         {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
382         {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
383         {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
384 };
385
386 static const __u8 initTas5130[] = {
387         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
388         0x00, 0x00,
389         0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
390         0x28, 0x1e, 0x60, COMP, MCK_INIT,
391         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
392 };
393 static const __u8 tas5130_sensor_init[][8] = {
394 /*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
395                                         * shutter 0x47 short exposure? */
396         {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
397                                         /* shutter 0x01 long exposure */
398         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
399 };
400
401 /* get one byte in gspca_dev->usb_buf */
402 static void reg_r(struct gspca_dev *gspca_dev,
403                   __u16 value)
404 {
405         usb_control_msg(gspca_dev->dev,
406                         usb_rcvctrlpipe(gspca_dev->dev, 0),
407                         0,                      /* request */
408                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
409                         value,
410                         0,                      /* index */
411                         gspca_dev->usb_buf, 1,
412                         500);
413 }
414
415 static void reg_w(struct gspca_dev *gspca_dev,
416                   __u16 value,
417                   const __u8 *buffer,
418                   int len)
419 {
420 #ifdef CONFIG_VIDEO_ADV_DEBUG
421         if (len > sizeof gspca_dev->usb_buf) {
422                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
423                 return;
424         }
425 #endif
426         memcpy(gspca_dev->usb_buf, buffer, len);
427         usb_control_msg(gspca_dev->dev,
428                         usb_sndctrlpipe(gspca_dev->dev, 0),
429                         0x08,                   /* request */
430                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
431                         value,
432                         0,                      /* index */
433                         gspca_dev->usb_buf, len,
434                         500);
435 }
436
437 static void reg_w_big(struct gspca_dev *gspca_dev,
438                   __u16 value,
439                   const __u8 *buffer,
440                   int len)
441 {
442         __u8 *tmpbuf;
443
444         tmpbuf = kmalloc(len, GFP_KERNEL);
445         memcpy(tmpbuf, buffer, len);
446         usb_control_msg(gspca_dev->dev,
447                         usb_sndctrlpipe(gspca_dev->dev, 0),
448                         0x08,                   /* request */
449                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
450                         value,
451                         0,                      /* index */
452                         tmpbuf, len,
453                         500);
454         kfree(tmpbuf);
455 }
456
457 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
458 {
459         int retry = 60;
460
461         /* is i2c ready */
462         reg_w(gspca_dev, 0x08, buffer, 8);
463         while (retry--) {
464                 msleep(10);
465                 reg_r(gspca_dev, 0x08);
466                 if (gspca_dev->usb_buf[0] & 0x04) {
467                         if (gspca_dev->usb_buf[0] & 0x08)
468                                 return -1;
469                         return 0;
470                 }
471         }
472         return -1;
473 }
474
475 static void i2c_w_vector(struct gspca_dev *gspca_dev,
476                         const __u8 buffer[][8], int len)
477 {
478         for (;;) {
479                 reg_w(gspca_dev, 0x08, *buffer, 8);
480                 len -= 8;
481                 if (len <= 0)
482                         break;
483                 buffer++;
484         }
485 }
486
487 static void setbrightness(struct gspca_dev *gspca_dev)
488 {
489         struct sd *sd = (struct sd *) gspca_dev;
490         __u8 value;
491
492         switch (sd->sensor) {
493         case  SENSOR_OV6650:
494         case  SENSOR_OV7630_3:
495         case  SENSOR_OV7630: {
496                 __u8 i2cOV[] =
497                         {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
498
499                 /* change reg 0x06 */
500                 i2cOV[1] = sd->sensor_addr;
501                 i2cOV[3] = sd->brightness;
502                 if (i2c_w(gspca_dev, i2cOV) < 0)
503                         goto err;
504                 break;
505             }
506         case SENSOR_PAS106: {
507                 __u8 i2c1[] =
508                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
509
510                 i2c1[3] = sd->brightness >> 3;
511                 i2c1[2] = 0x0e;
512                 if (i2c_w(gspca_dev, i2c1) < 0)
513                         goto err;
514                 i2c1[3] = 0x01;
515                 i2c1[2] = 0x13;
516                 if (i2c_w(gspca_dev, i2c1) < 0)
517                         goto err;
518                 break;
519             }
520         case SENSOR_PAS202: {
521                 /* __u8 i2cpexpo1[] =
522                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
523                 __u8 i2cpexpo[] =
524                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
525                 __u8 i2cp202[] =
526                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
527                 static __u8 i2cpdoit[] =
528                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
529
530                 /* change reg 0x10 */
531                 i2cpexpo[4] = 0xff - sd->brightness;
532 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
533                         goto err; */
534 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
535                         goto err; */
536                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
537                         goto err;
538                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
539                         goto err;
540                 i2cp202[3] = sd->brightness >> 3;
541                 if (i2c_w(gspca_dev, i2cp202) < 0)
542                         goto err;
543                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
544                         goto err;
545                 break;
546             }
547         case SENSOR_TAS5130CXX: {
548                 __u8 i2c[] =
549                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
550
551                 value = 0xff - sd->brightness;
552                 i2c[4] = value;
553                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
554                 if (i2c_w(gspca_dev, i2c) < 0)
555                         goto err;
556                 break;
557             }
558         case SENSOR_TAS5110:
559                 /* FIXME figure out howto control brightness on TAS5110 */
560                 break;
561         }
562         return;
563 err:
564         PDEBUG(D_ERR, "i2c error brightness");
565 }
566
567 static void setsensorgain(struct gspca_dev *gspca_dev)
568 {
569         struct sd *sd = (struct sd *) gspca_dev;
570         unsigned char gain = sd->gain;
571
572         switch (sd->sensor) {
573
574         case SENSOR_TAS5110: {
575                 __u8 i2c[] =
576                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
577
578                 i2c[4] = 255 - gain;
579                 if (i2c_w(gspca_dev, i2c) < 0)
580                         goto err;
581                 break;
582             }
583
584         case SENSOR_OV6650:
585                 gain >>= 1;
586                 /* fall thru */
587         case SENSOR_OV7630_3: {
588                 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
589
590                 i2c[1] = sd->sensor_addr;
591                 i2c[3] = gain >> 2;
592                 if (i2c_w(gspca_dev, i2c) < 0)
593                         goto err;
594                 break;
595             }
596         }
597         return;
598 err:
599         PDEBUG(D_ERR, "i2c error gain");
600 }
601
602 static void setgain(struct gspca_dev *gspca_dev)
603 {
604         struct sd *sd = (struct sd *) gspca_dev;
605         __u8 gain;
606         __u8 rgb_value;
607
608         gain = sd->gain >> 4;
609
610         /* red and blue gain */
611         rgb_value = gain << 4 | gain;
612         reg_w(gspca_dev, 0x10, &rgb_value, 1);
613         /* green gain */
614         rgb_value = gain;
615         reg_w(gspca_dev, 0x11, &rgb_value, 1);
616
617         if (sd->sensor_has_gain)
618                 setsensorgain(gspca_dev);
619 }
620
621 static void setexposure(struct gspca_dev *gspca_dev)
622 {
623         struct sd *sd = (struct sd *) gspca_dev;
624
625         switch (sd->sensor) {
626         case SENSOR_TAS5110: {
627                 __u8 reg;
628
629                 /* register 19's high nibble contains the sn9c10x clock divider
630                    The high nibble configures the no fps according to the
631                    formula: 60 / high_nibble. With a maximum of 30 fps */
632                 reg = 120 * sd->exposure / 1000;
633                 if (reg < 2)
634                         reg = 2;
635                 else if (reg > 15)
636                         reg = 15;
637                 reg = (reg << 4) | 0x0b;
638                 reg_w(gspca_dev, 0x19, &reg, 1);
639                 break;
640             }
641         case SENSOR_OV6650:
642         case SENSOR_OV7630_3: {
643                 /* The ov6650 / ov7630 have 2 registers which both influence
644                    exposure, register 11, whose low nibble sets the nr off fps
645                    according to: fps = 30 / (low_nibble + 1)
646
647                    The fps configures the maximum exposure setting, but it is
648                    possible to use less exposure then what the fps maximum
649                    allows by setting register 10. register 10 configures the
650                    actual exposure as quotient of the full exposure, with 0
651                    being no exposure at all (not very usefull) and reg10_max
652                    being max exposure possible at that framerate.
653
654                    The code maps our 0 - 510 ms exposure ctrl to these 2
655                    registers, trying to keep fps as high as possible.
656                 */
657                 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
658                 int reg10, reg11;
659                 /* ov6645 datasheet says reg10_max is 9a, but that uses
660                    tline * 2 * reg10 as formula for calculating texpo, the
661                    ov6650 probably uses the same formula as the 7730 which uses
662                    tline * 4 * reg10, which explains why the reg10max we've
663                    found experimentally for the ov6650 is exactly half that of
664                    the ov6645. The ov7630 datasheet says the max is 0x41. */
665                 const int reg10_max = (sd->sensor == SENSOR_OV6650)
666                                 ? 0x4d : 0x41;
667
668                 reg11 = (60 * sd->exposure + 999) / 1000;
669                 if (reg11 < 1)
670                         reg11 = 1;
671                 else if (reg11 > 16)
672                         reg11 = 16;
673
674                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
675                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
676                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
677
678                 /* Don't allow this to get below 10 when using autogain, the
679                    steps become very large (relatively) when below 10 causing
680                    the image to oscilate from much too dark, to much too bright
681                    and back again. */
682                 if (sd->autogain && reg10 < 10)
683                         reg10 = 10;
684                 else if (reg10 > reg10_max)
685                         reg10 = reg10_max;
686
687                 /* Write reg 10 and reg11 low nibble */
688                 i2c[1] = sd->sensor_addr;
689                 i2c[3] = reg10;
690                 i2c[4] |= reg11 - 1;
691                 if (sd->sensor == SENSOR_OV7630_3) {
692                         __u8 reg76 = reg10 & 0x03;
693                         __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
694                                             0x00, 0x00, 0x00, 0x10};
695                         reg10 >>= 2;
696                         i2c_reg76[3] = reg76;
697                         if (i2c_w(gspca_dev, i2c_reg76) < 0)
698                                 PDEBUG(D_ERR, "i2c error exposure");
699                 }
700                 if (i2c_w(gspca_dev, i2c) < 0)
701                         PDEBUG(D_ERR, "i2c error exposure");
702                 break;
703             }
704         }
705 }
706
707 static void setfreq(struct gspca_dev *gspca_dev)
708 {
709         struct sd *sd = (struct sd *) gspca_dev;
710
711         switch (sd->sensor) {
712         case SENSOR_OV6650:
713         case SENSOR_OV7630_3: {
714                 /* Framerate adjust register for artificial light 50 hz flicker
715                    compensation, identical to ov6630 0x2b register, see ov6630
716                    datasheet.
717                    0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
718                 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
719                 switch (sd->freq) {
720                 default:
721 /*              case 0:                  * no filter*/
722 /*              case 2:                  * 60 hz */
723                         i2c[3] = 0;
724                         break;
725                 case 1:                 /* 50 hz */
726                         i2c[3] = (sd->sensor == SENSOR_OV6650)
727                                         ? 0x4f : 0x8a;
728                         break;
729                 }
730                 i2c[1] = sd->sensor_addr;
731                 if (i2c_w(gspca_dev, i2c) < 0)
732                         PDEBUG(D_ERR, "i2c error setfreq");
733                 break;
734             }
735         }
736 }
737
738
739 static void do_autogain(struct gspca_dev *gspca_dev)
740 {
741         struct sd *sd = (struct sd *) gspca_dev;
742         int avg_lum = atomic_read(&sd->avg_lum);
743
744         if (avg_lum == -1)
745                 return;
746
747         if (sd->autogain_ignore_frames > 0)
748                 sd->autogain_ignore_frames--;
749         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
750                         sd->brightness * DESIRED_AVG_LUM / 127,
751                         AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
752                 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
753                         (int)sd->gain, (int)sd->exposure);
754                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
755         }
756 }
757
758 /* this function is called at probe time */
759 static int sd_config(struct gspca_dev *gspca_dev,
760                         const struct usb_device_id *id)
761 {
762         struct sd *sd = (struct sd *) gspca_dev;
763         struct cam *cam;
764         __u16 product;
765         int sif = 0;
766
767         /* nctrls depends upon the sensor, so we use a per cam copy */
768         memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
769         gspca_dev->sd_desc = &sd->sd_desc;
770
771         sd->fr_h_sz = 12;               /* default size of the frame header */
772         sd->sd_desc.nctrls = 2;         /* default nb of ctrls */
773         sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
774         sd->freq = FREQ_DEF;
775
776         product = id->idProduct;
777 /*      switch (id->idVendor) { */
778 /*      case 0x0c45:                             * Sonix */
779                 switch (product) {
780                 case 0x6001:                    /* SN9C102 */
781                 case 0x6005:                    /* SN9C101 */
782                 case 0x6007:                    /* SN9C101 */
783                         sd->sensor = SENSOR_TAS5110;
784                         sd->sensor_has_gain = 1;
785                         sd->sd_desc.nctrls = 4;
786                         sd->sd_desc.dq_callback = do_autogain;
787                         sif = 1;
788                         break;
789                 case 0x6009:                    /* SN9C101 */
790                 case 0x600d:                    /* SN9C101 */
791                 case 0x6029:                    /* SN9C101 */
792                         sd->sensor = SENSOR_PAS106;
793                         sif = 1;
794                         break;
795                 case 0x6011:                    /* SN9C101 - SN9C101G */
796                         sd->sensor = SENSOR_OV6650;
797                         sd->sensor_has_gain = 1;
798                         sd->sensor_addr = 0x60;
799                         sd->sd_desc.nctrls = 5;
800                         sd->sd_desc.dq_callback = do_autogain;
801                         sif = 1;
802                         break;
803                 case 0x6019:                    /* SN9C101 */
804                 case 0x602c:                    /* SN9C102 */
805                 case 0x602e:                    /* SN9C102 */
806                         sd->sensor = SENSOR_OV7630;
807                         sd->sensor_addr = 0x21;
808                         break;
809                 case 0x60b0:                    /* SN9C103 */
810                         sd->sensor = SENSOR_OV7630_3;
811                         sd->sensor_addr = 0x21;
812                         sd->fr_h_sz = 18;       /* size of frame header */
813                         sd->sensor_has_gain = 1;
814                         sd->sd_desc.nctrls = 5;
815                         sd->sd_desc.dq_callback = do_autogain;
816                         sd->autogain = 0;
817                         break;
818                 case 0x6024:                    /* SN9C102 */
819                 case 0x6025:                    /* SN9C102 */
820                         sd->sensor = SENSOR_TAS5130CXX;
821                         break;
822                 case 0x6028:                    /* SN9C102 */
823                         sd->sensor = SENSOR_PAS202;
824                         break;
825                 case 0x602d:                    /* SN9C102 */
826                         sd->sensor = SENSOR_HV7131R;
827                         break;
828                 case 0x60af:                    /* SN9C103 */
829                         sd->sensor = SENSOR_PAS202;
830                         sd->fr_h_sz = 18;       /* size of frame header (?) */
831                         break;
832                 }
833 /*              break; */
834 /*      } */
835
836         cam = &gspca_dev->cam;
837         cam->dev_name = (char *) id->driver_info;
838         cam->epaddr = 0x01;
839         if (!sif) {
840                 cam->cam_mode = vga_mode;
841                 cam->nmodes = ARRAY_SIZE(vga_mode);
842                 if (sd->sensor == SENSOR_OV7630_3) {
843                         /* We only have 320x240 & 640x480 */
844                         cam->cam_mode++;
845                         cam->nmodes--;
846                 }
847         } else {
848                 cam->cam_mode = sif_mode;
849                 cam->nmodes = ARRAY_SIZE(sif_mode);
850         }
851         sd->brightness = BRIGHTNESS_DEF;
852         sd->gain = GAIN_DEF;
853         sd->exposure = EXPOSURE_DEF;
854         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
855                 reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
856         return 0;
857 }
858
859 /* this function is called at open time */
860 static int sd_open(struct gspca_dev *gspca_dev)
861 {
862         reg_r(gspca_dev, 0x00);
863         if (gspca_dev->usb_buf[0] != 0x10)
864                 return -ENODEV;
865         return 0;
866 }
867
868 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
869 {
870         int i;
871         const __u8 *data;
872         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
873
874         i = ARRAY_SIZE(pas106_data);
875         data = pas106_data[0];
876         while (--i >= 0) {
877                 memcpy(&i2c1[2], data, 2);
878                                         /* copy 2 bytes from the template */
879                 if (i2c_w(gspca_dev, i2c1) < 0)
880                         PDEBUG(D_ERR, "i2c error pas106");
881                 data += 2;
882         }
883 }
884
885 /* -- start the camera -- */
886 static void sd_start(struct gspca_dev *gspca_dev)
887 {
888         struct sd *sd = (struct sd *) gspca_dev;
889         int mode, l;
890         const __u8 *sn9c10x;
891         __u8 reg01, reg17;
892         __u8 reg17_19[3];
893
894         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
895         switch (sd->sensor) {
896         case SENSOR_HV7131R:
897                 sn9c10x = initHv7131;
898                 reg17_19[0] = 0x60;
899                 reg17_19[1] = (mode << 4) | 0x8a;
900                 reg17_19[2] = 0x20;
901                 break;
902         case SENSOR_OV6650:
903                 sn9c10x = initOv6650;
904                 reg17_19[0] = 0x68;
905                 reg17_19[1] = (mode << 4) | 0x8b;
906                 reg17_19[2] = 0x20;
907                 break;
908         case SENSOR_OV7630:
909                 sn9c10x = initOv7630;
910                 reg17_19[0] = 0x68;
911                 reg17_19[1] = (mode << 4) | COMP2;
912                 reg17_19[2] = MCK_INIT1;
913                 break;
914         case SENSOR_OV7630_3:
915                 sn9c10x = initOv7630_3;
916                 reg17_19[0] = 0x68;
917                 reg17_19[1] = (mode << 4) | COMP2;
918                 reg17_19[2] = MCK_INIT1;
919                 break;
920         case SENSOR_PAS106:
921                 sn9c10x = initPas106;
922                 reg17_19[0] = 0x24;             /* 0x28 */
923                 reg17_19[1] = (mode << 4) | COMP1;
924                 reg17_19[2] = MCK_INIT1;
925                 break;
926         case SENSOR_PAS202:
927                 sn9c10x = initPas202;
928                 reg17_19[0] = mode ? 0x24 : 0x20;
929                 reg17_19[1] = (mode << 4) | 0x89;
930                 reg17_19[2] = 0x20;
931                 break;
932         case SENSOR_TAS5110:
933                 sn9c10x = initTas5110;
934                 reg17_19[0] = 0x60;
935                 reg17_19[1] = (mode << 4) | 0x86;
936                 reg17_19[2] = 0x2b;             /* 0xf3; */
937                 break;
938         default:
939 /*      case SENSOR_TAS5130CXX: */
940                 sn9c10x = initTas5130;
941                 reg17_19[0] = 0x60;
942                 reg17_19[1] = (mode << 4) | COMP;
943                 reg17_19[2] = mode ? 0x23 : 0x43;
944                 break;
945         }
946         switch (sd->sensor) {
947         case SENSOR_OV7630:
948                 reg01 = 0x06;
949                 reg17 = 0x29;
950                 l = sizeof initOv7630;
951                 break;
952         case SENSOR_OV7630_3:
953                 reg01 = 0x44;
954                 reg17 = 0x68;
955                 l = sizeof initOv7630_3;
956                 break;
957         default:
958                 reg01 = sn9c10x[0];
959                 reg17 = sn9c10x[0x17 - 1];
960                 l = 0x1f;
961                 break;
962         }
963
964         /* reg 0x01 bit 2 video transfert on */
965         reg_w(gspca_dev, 0x01, &reg01, 1);
966         /* reg 0x17 SensorClk enable inv Clk 0x60 */
967         reg_w(gspca_dev, 0x17, &reg17, 1);
968 /*fixme: for ov7630 102
969         reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
970         /* Set the registers from the template */
971         reg_w_big(gspca_dev, 0x01, sn9c10x, l);
972         switch (sd->sensor) {
973         case SENSOR_HV7131R:
974                 i2c_w_vector(gspca_dev, hv7131_sensor_init,
975                                 sizeof hv7131_sensor_init);
976                 break;
977         case SENSOR_OV6650:
978                 i2c_w_vector(gspca_dev, ov6650_sensor_init,
979                                 sizeof ov6650_sensor_init);
980                 break;
981         case SENSOR_OV7630:
982                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
983                                 sizeof ov7630_sensor_init_com);
984                 msleep(200);
985                 i2c_w_vector(gspca_dev, ov7630_sensor_init,
986                                 sizeof ov7630_sensor_init);
987                 break;
988         case SENSOR_OV7630_3:
989                 i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
990                                 sizeof ov7630_sensor_init_com);
991                 msleep(200);
992                 i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
993                 break;
994         case SENSOR_PAS106:
995                 pas106_i2cinit(gspca_dev);
996                 break;
997         case SENSOR_PAS202:
998                 i2c_w_vector(gspca_dev, pas202_sensor_init,
999                                 sizeof pas202_sensor_init);
1000                 break;
1001         case SENSOR_TAS5110:
1002                 i2c_w_vector(gspca_dev, tas5110_sensor_init,
1003                                 sizeof tas5110_sensor_init);
1004                 break;
1005         default:
1006 /*      case SENSOR_TAS5130CXX: */
1007                 i2c_w_vector(gspca_dev, tas5130_sensor_init,
1008                                 sizeof tas5130_sensor_init);
1009                 break;
1010         }
1011         /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1012         reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
1013         /* compression register */
1014         reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
1015         /* H_start */
1016         reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
1017         /* V_START */
1018         reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
1019         /* reset 0x17 SensorClk enable inv Clk 0x60 */
1020                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1021         reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
1022         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
1023         reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
1024         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1025         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
1026         /* Enable video transfert */
1027         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
1028         /* Compression */
1029         reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
1030         msleep(20);
1031
1032         setgain(gspca_dev);
1033         setbrightness(gspca_dev);
1034         setexposure(gspca_dev);
1035         setfreq(gspca_dev);
1036
1037         sd->autogain_ignore_frames = 0;
1038         atomic_set(&sd->avg_lum, -1);
1039 }
1040
1041 static void sd_stopN(struct gspca_dev *gspca_dev)
1042 {
1043         __u8 ByteSend;
1044
1045         ByteSend = 0x09;        /* 0X00 */
1046         reg_w(gspca_dev, 0x01, &ByteSend, 1);
1047 }
1048
1049 static void sd_stop0(struct gspca_dev *gspca_dev)
1050 {
1051 }
1052
1053 static void sd_close(struct gspca_dev *gspca_dev)
1054 {
1055 }
1056
1057 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1058                         struct gspca_frame *frame,      /* target */
1059                         unsigned char *data,            /* isoc packet */
1060                         int len)                        /* iso packet length */
1061 {
1062         int i;
1063         struct sd *sd = (struct sd *) gspca_dev;
1064
1065         /* frames start with:
1066          *      ff ff 00 c4 c4 96       synchro
1067          *      00              (unknown)
1068          *      xx              (frame sequence / size / compression)
1069          *      (xx)            (idem - extra byte for sn9c103)
1070          *      ll mm           brightness sum inside auto exposure
1071          *      ll mm           brightness sum outside auto exposure
1072          *      (xx xx xx xx xx)        audio values for snc103
1073          */
1074         if (len > 6 && len < 24) {
1075                 for (i = 0; i < len - 6; i++) {
1076                         if (data[0 + i] == 0xff
1077                             && data[1 + i] == 0xff
1078                             && data[2 + i] == 0x00
1079                             && data[3 + i] == 0xc4
1080                             && data[4 + i] == 0xc4
1081                             && data[5 + i] == 0x96) {   /* start of frame */
1082                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
1083                                                         frame, data, 0);
1084                                 if (len - i < sd->fr_h_sz) {
1085                                         atomic_set(&sd->avg_lum, -1);
1086                                         PDEBUG(D_STREAM, "packet too short to"
1087                                                 " get avg brightness");
1088                                 } else if (sd->fr_h_sz == 12) {
1089                                         atomic_set(&sd->avg_lum,
1090                                                 data[i + 8] +
1091                                                         (data[i + 9] << 8));
1092                                 } else {
1093                                         atomic_set(&sd->avg_lum,
1094                                                 data[i + 9] +
1095                                                         (data[i + 10] << 8));
1096                                 }
1097                                 data += i + sd->fr_h_sz;
1098                                 len -= i + sd->fr_h_sz;
1099                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1100                                                 frame, data, len);
1101                                 return;
1102                         }
1103                 }
1104         }
1105         gspca_frame_add(gspca_dev, INTER_PACKET,
1106                         frame, data, len);
1107 }
1108
1109 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1110 {
1111         struct sd *sd = (struct sd *) gspca_dev;
1112
1113         sd->brightness = val;
1114         if (gspca_dev->streaming)
1115                 setbrightness(gspca_dev);
1116         return 0;
1117 }
1118
1119 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1120 {
1121         struct sd *sd = (struct sd *) gspca_dev;
1122
1123         *val = sd->brightness;
1124         return 0;
1125 }
1126
1127 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1128 {
1129         struct sd *sd = (struct sd *) gspca_dev;
1130
1131         sd->gain = val;
1132         if (gspca_dev->streaming)
1133                 setgain(gspca_dev);
1134         return 0;
1135 }
1136
1137 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1138 {
1139         struct sd *sd = (struct sd *) gspca_dev;
1140
1141         *val = sd->gain;
1142         return 0;
1143 }
1144
1145 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1146 {
1147         struct sd *sd = (struct sd *) gspca_dev;
1148
1149         sd->exposure = val;
1150         if (gspca_dev->streaming)
1151                 setexposure(gspca_dev);
1152         return 0;
1153 }
1154
1155 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1156 {
1157         struct sd *sd = (struct sd *) gspca_dev;
1158
1159         *val = sd->exposure;
1160         return 0;
1161 }
1162
1163 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1164 {
1165         struct sd *sd = (struct sd *) gspca_dev;
1166
1167         sd->autogain = val;
1168         /* when switching to autogain set defaults to make sure
1169            we are on a valid point of the autogain gain /
1170            exposure knee graph, and give this change time to
1171            take effect before doing autogain. */
1172         if (sd->autogain) {
1173                 sd->exposure = EXPOSURE_DEF;
1174                 sd->gain = GAIN_DEF;
1175                 if (gspca_dev->streaming) {
1176                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1177                         setexposure(gspca_dev);
1178                         setgain(gspca_dev);
1179                 }
1180         }
1181
1182         return 0;
1183 }
1184
1185 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1186 {
1187         struct sd *sd = (struct sd *) gspca_dev;
1188
1189         *val = sd->autogain;
1190         return 0;
1191 }
1192
1193 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1194 {
1195         struct sd *sd = (struct sd *) gspca_dev;
1196
1197         sd->freq = val;
1198         if (gspca_dev->streaming)
1199                 setfreq(gspca_dev);
1200         return 0;
1201 }
1202
1203 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1204 {
1205         struct sd *sd = (struct sd *) gspca_dev;
1206
1207         *val = sd->freq;
1208         return 0;
1209 }
1210
1211 static int sd_querymenu(struct gspca_dev *gspca_dev,
1212                         struct v4l2_querymenu *menu)
1213 {
1214         switch (menu->id) {
1215         case V4L2_CID_POWER_LINE_FREQUENCY:
1216                 switch (menu->index) {
1217                 case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1218                         strcpy((char *) menu->name, "NoFliker");
1219                         return 0;
1220                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1221                         strcpy((char *) menu->name, "50 Hz");
1222                         return 0;
1223                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1224                         strcpy((char *) menu->name, "60 Hz");
1225                         return 0;
1226                 }
1227                 break;
1228         }
1229         return -EINVAL;
1230 }
1231
1232 /* sub-driver description */
1233 static const struct sd_desc sd_desc = {
1234         .name = MODULE_NAME,
1235         .ctrls = sd_ctrls,
1236         .nctrls = ARRAY_SIZE(sd_ctrls),
1237         .config = sd_config,
1238         .open = sd_open,
1239         .start = sd_start,
1240         .stopN = sd_stopN,
1241         .stop0 = sd_stop0,
1242         .close = sd_close,
1243         .pkt_scan = sd_pkt_scan,
1244         .querymenu = sd_querymenu,
1245 };
1246
1247 /* -- module initialisation -- */
1248 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1249 static __devinitdata struct usb_device_id device_table[] = {
1250 #ifndef CONFIG_USB_SN9C102
1251         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1252         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1253         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1254         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1255         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1256         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1257         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1258         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1259         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1260         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1261         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1262         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1263         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1264         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1265         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1266         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1267 #endif
1268         {}
1269 };
1270 MODULE_DEVICE_TABLE(usb, device_table);
1271
1272 /* -- device connect -- */
1273 static int sd_probe(struct usb_interface *intf,
1274                         const struct usb_device_id *id)
1275 {
1276         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1277                                 THIS_MODULE);
1278 }
1279
1280 static struct usb_driver sd_driver = {
1281         .name = MODULE_NAME,
1282         .id_table = device_table,
1283         .probe = sd_probe,
1284         .disconnect = gspca_disconnect,
1285 };
1286
1287 /* -- module insert / remove -- */
1288 static int __init sd_mod_init(void)
1289 {
1290         if (usb_register(&sd_driver) < 0)
1291                 return -1;
1292         PDEBUG(D_PROBE, "v%s registered", version);
1293         return 0;
1294 }
1295 static void __exit sd_mod_exit(void)
1296 {
1297         usb_deregister(&sd_driver);
1298         PDEBUG(D_PROBE, "deregistered");
1299 }
1300
1301 module_init(sd_mod_init);
1302 module_exit(sd_mod_exit);