]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/sonixb.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[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 /* Some documentation on known sonixb registers:
24
25 Reg     Use
26 0x10    high nibble red gain low nibble blue gain
27 0x11    low nibble green gain
28 0x12    hstart
29 0x13    vstart
30 0x15    hsize (hsize = register-value * 16)
31 0x16    vsize (vsize = register-value * 16)
32 0x17    bit 0 toggle compression quality (according to sn9c102 driver)
33 0x18    bit 7 enables compression, bit 4-5 set image down scaling:
34         00 scale 1, 01 scale 1/2, 10, scale 1/4
35 0x19    high-nibble is sensor clock divider, changes exposure on sensors which
36         use a clock generated by the bridge. Some sensors have their own clock.
37 0x1c    auto_exposure area (for avg_lum) startx (startx = register-value * 32)
38 0x1d    auto_exposure area (for avg_lum) starty (starty = register-value * 32)
39 0x1e    auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
40 0x1f    auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
41 */
42
43 #define MODULE_NAME "sonixb"
44
45 #include "gspca.h"
46
47 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
48 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
49 MODULE_LICENSE("GPL");
50
51 /* specific webcam descriptor */
52 struct sd {
53         struct gspca_dev gspca_dev;     /* !! must be the first item */
54         atomic_t avg_lum;
55         int prev_avg_lum;
56
57         unsigned char gain;
58         unsigned char exposure;
59         unsigned char brightness;
60         unsigned char autogain;
61         unsigned char autogain_ignore_frames;
62         unsigned char frames_to_drop;
63         unsigned char freq;             /* light freq filter setting */
64
65         __u8 bridge;                    /* Type of bridge */
66 #define BRIDGE_101 0
67 #define BRIDGE_102 0 /* We make no difference between 101 and 102 */
68 #define BRIDGE_103 1
69
70         __u8 sensor;                    /* Type of image sensor chip */
71 #define SENSOR_HV7131R 0
72 #define SENSOR_OV6650 1
73 #define SENSOR_OV7630 2
74 #define SENSOR_PAS106 3
75 #define SENSOR_PAS202 4
76 #define SENSOR_TAS5110 5
77 #define SENSOR_TAS5130CXX 6
78         __u8 reg11;
79 };
80
81 typedef const __u8 sensor_init_t[8];
82
83 struct sensor_data {
84         const __u8 *bridge_init[2];
85         int bridge_init_size[2];
86         sensor_init_t *sensor_init;
87         int sensor_init_size;
88         sensor_init_t *sensor_bridge_init[2];
89         int sensor_bridge_init_size[2];
90         int flags;
91         unsigned ctrl_dis;
92         __u8 sensor_addr;
93 };
94
95 /* sensor_data flags */
96 #define F_GAIN 0x01             /* has gain */
97 #define F_SIF  0x02             /* sif or vga */
98
99 /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100 #define MODE_RAW 0x10           /* raw bayer mode */
101 #define MODE_REDUCED_SIF 0x20   /* vga mode (320x240 / 160x120) on sif cam */
102
103 /* ctrl_dis helper macros */
104 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
105 #define NO_FREQ (1 << FREQ_IDX)
106 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
107
108 #define COMP2 0x8f
109 #define COMP 0xc7               /* 0x87 //0x07 */
110 #define COMP1 0xc9              /* 0x89 //0x09 */
111
112 #define MCK_INIT 0x63
113 #define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
114
115 #define SYS_CLK 0x04
116
117 #define SENS(bridge_1, bridge_3, sensor, sensor_1, \
118         sensor_3, _flags, _ctrl_dis, _sensor_addr) \
119 { \
120         .bridge_init = { bridge_1, bridge_3 }, \
121         .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
122         .sensor_init = sensor, \
123         .sensor_init_size = sizeof(sensor), \
124         .sensor_bridge_init = { sensor_1, sensor_3,}, \
125         .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
126         .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
127 }
128
129 /* We calculate the autogain at the end of the transfer of a frame, at this
130    moment a frame with the old settings is being transmitted, and a frame is
131    being captured with the old settings. So if we adjust the autogain we must
132    ignore atleast the 2 next frames for the new settings to come into effect
133    before doing any other adjustments */
134 #define AUTOGAIN_IGNORE_FRAMES 3
135
136 /* V4L2 controls supported by the driver */
137 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
138 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
139 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
140 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
141 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
142 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
143 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
144 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
145 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
146 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
147
148 static struct ctrl sd_ctrls[] = {
149 #define BRIGHTNESS_IDX 0
150         {
151             {
152                 .id      = V4L2_CID_BRIGHTNESS,
153                 .type    = V4L2_CTRL_TYPE_INTEGER,
154                 .name    = "Brightness",
155                 .minimum = 0,
156                 .maximum = 255,
157                 .step    = 1,
158 #define BRIGHTNESS_DEF 127
159                 .default_value = BRIGHTNESS_DEF,
160             },
161             .set = sd_setbrightness,
162             .get = sd_getbrightness,
163         },
164 #define GAIN_IDX 1
165         {
166             {
167                 .id      = V4L2_CID_GAIN,
168                 .type    = V4L2_CTRL_TYPE_INTEGER,
169                 .name    = "Gain",
170                 .minimum = 0,
171                 .maximum = 255,
172                 .step    = 1,
173 #define GAIN_DEF 127
174 #define GAIN_KNEE 200
175                 .default_value = GAIN_DEF,
176             },
177             .set = sd_setgain,
178             .get = sd_getgain,
179         },
180 #define EXPOSURE_IDX 2
181         {
182                 {
183                         .id = V4L2_CID_EXPOSURE,
184                         .type = V4L2_CTRL_TYPE_INTEGER,
185                         .name = "Exposure",
186 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
187 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
188                         .minimum = 0,
189                         .maximum = 255,
190                         .step = 1,
191                         .default_value = EXPOSURE_DEF,
192                         .flags = 0,
193                 },
194                 .set = sd_setexposure,
195                 .get = sd_getexposure,
196         },
197 #define AUTOGAIN_IDX 3
198         {
199                 {
200                         .id = V4L2_CID_AUTOGAIN,
201                         .type = V4L2_CTRL_TYPE_BOOLEAN,
202                         .name = "Automatic Gain (and Exposure)",
203                         .minimum = 0,
204                         .maximum = 1,
205                         .step = 1,
206 #define AUTOGAIN_DEF 1
207                         .default_value = AUTOGAIN_DEF,
208                         .flags = 0,
209                 },
210                 .set = sd_setautogain,
211                 .get = sd_getautogain,
212         },
213 #define FREQ_IDX 4
214         {
215                 {
216                         .id      = V4L2_CID_POWER_LINE_FREQUENCY,
217                         .type    = V4L2_CTRL_TYPE_MENU,
218                         .name    = "Light frequency filter",
219                         .minimum = 0,
220                         .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
221                         .step    = 1,
222 #define FREQ_DEF 1
223                         .default_value = FREQ_DEF,
224                 },
225                 .set = sd_setfreq,
226                 .get = sd_getfreq,
227         },
228 };
229
230 static const struct v4l2_pix_format vga_mode[] = {
231         {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
232                 .bytesperline = 160,
233                 .sizeimage = 160 * 120,
234                 .colorspace = V4L2_COLORSPACE_SRGB,
235                 .priv = 2 | MODE_RAW},
236         {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
237                 .bytesperline = 160,
238                 .sizeimage = 160 * 120 * 5 / 4,
239                 .colorspace = V4L2_COLORSPACE_SRGB,
240                 .priv = 2},
241         {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
242                 .bytesperline = 320,
243                 .sizeimage = 320 * 240 * 5 / 4,
244                 .colorspace = V4L2_COLORSPACE_SRGB,
245                 .priv = 1},
246         {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
247                 .bytesperline = 640,
248                 .sizeimage = 640 * 480 * 5 / 4,
249                 .colorspace = V4L2_COLORSPACE_SRGB,
250                 .priv = 0},
251 };
252 static const struct v4l2_pix_format sif_mode[] = {
253         {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
254                 .bytesperline = 160,
255                 .sizeimage = 160 * 120,
256                 .colorspace = V4L2_COLORSPACE_SRGB,
257                 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
258         {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
259                 .bytesperline = 160,
260                 .sizeimage = 160 * 120 * 5 / 4,
261                 .colorspace = V4L2_COLORSPACE_SRGB,
262                 .priv = 1 | MODE_REDUCED_SIF},
263         {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
264                 .bytesperline = 176,
265                 .sizeimage = 176 * 144,
266                 .colorspace = V4L2_COLORSPACE_SRGB,
267                 .priv = 1 | MODE_RAW},
268         {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
269                 .bytesperline = 176,
270                 .sizeimage = 176 * 144 * 5 / 4,
271                 .colorspace = V4L2_COLORSPACE_SRGB,
272                 .priv = 1},
273         {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
274                 .bytesperline = 320,
275                 .sizeimage = 320 * 240 * 5 / 4,
276                 .colorspace = V4L2_COLORSPACE_SRGB,
277                 .priv = 0 | MODE_REDUCED_SIF},
278         {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
279                 .bytesperline = 352,
280                 .sizeimage = 352 * 288 * 5 / 4,
281                 .colorspace = V4L2_COLORSPACE_SRGB,
282                 .priv = 0},
283 };
284
285 static const __u8 initHv7131[] = {
286         0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
287         0x00, 0x00,
288         0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
289         0x28, 0x1e, 0x60, 0x8a, 0x20,
290         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
291 };
292 static const __u8 hv7131_sensor_init[][8] = {
293         {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
294         {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
295         {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
296         {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
297         {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
298 };
299 static const __u8 initOv6650[] = {
300         0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
301         0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302         0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
303         0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
304 };
305 static const __u8 ov6650_sensor_init[][8] =
306 {
307         /* Bright, contrast, etc are set througth SCBB interface.
308          * AVCAP on win2 do not send any data on this   controls. */
309         /* Anyway, some registers appears to alter bright and constrat */
310
311         /* Reset sensor */
312         {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
313         /* Set clock register 0x11 low nibble is clock divider */
314         {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
315         /* Next some unknown stuff */
316         {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
317 /*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
318                  * THIS SET GREEN SCREEN
319                  * (pixels could be innverted in decode kind of "brg",
320                  * but blue wont be there. Avoid this data ... */
321         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
322         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
323         {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
324         /* Enable rgb brightness control */
325         {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
326         /* HDG: Note windows uses the line below, which sets both register 0x60
327            and 0x61 I believe these registers of the ov6650 are identical as
328            those of the ov7630, because if this is true the windows settings
329            add a bit additional red gain and a lot additional blue gain, which
330            matches my findings that the windows settings make blue much too
331            blue and red a little too red.
332         {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
333         /* Some more unknown stuff */
334         {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
335         {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
336 };
337
338 static const __u8 initOv7630[] = {
339         0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
340         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
341         0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
342         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
343         0x68, COMP2, MCK_INIT1,                         /* r17 .. r19 */
344         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
345 };
346 static const __u8 initOv7630_3[] = {
347         0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
348         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
349         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
350         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
351         0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
352         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,       /* r1a .. r20 */
353         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
354         0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
355 };
356 static const __u8 ov7630_sensor_init[][8] = {
357         {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
358         {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
359 /*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
360         {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
361         {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
362         {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
363         {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
364         {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
365         {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
366         {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
367         {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
368         {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
369 /*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
370         {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
371         {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
372         {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
373         {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
374         {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
375         {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
376 };
377
378 static const __u8 ov7630_sensor_init_3[][8] = {
379         {0xa0, 0x21, 0x13, 0x80, 0x00,  0x00, 0x00, 0x10},
380 };
381
382 static const __u8 initPas106[] = {
383         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
384         0x00, 0x00,
385         0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
386         0x16, 0x12, 0x24, COMP1, MCK_INIT1,
387         0x18, 0x10, 0x02, 0x02, 0x09, 0x07
388 };
389 /* compression 0x86 mckinit1 0x2b */
390 static const __u8 pas106_sensor_init[][8] = {
391         /* Pixel Clock Divider 6 */
392         { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
393         /* Frame Time MSB (also seen as 0x12) */
394         { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
395         /* Frame Time LSB (also seen as 0x05) */
396         { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
397         /* Shutter Time Line Offset (also seen as 0x6d) */
398         { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
399         /* Shutter Time Pixel Offset (also seen as 0xb1) */
400         { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
401         /* Black Level Subtract Sign (also seen 0x00) */
402         { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
403         /* Black Level Subtract Level (also seen 0x01) */
404         { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
405         { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
406         /* Color Gain B Pixel 5 a */
407         { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
408         /* Color Gain G1 Pixel 1 5 */
409         { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
410         /* Color Gain G2 Pixel 1 0 5 */
411         { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
412         /* Color Gain R Pixel 3 1 */
413         { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
414         /* Color GainH  Pixel */
415         { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
416         /* Global Gain */
417         { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
418         /* Contrast */
419         { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
420         /* H&V synchro polarity */
421         { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
422         /* ?default */
423         { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
424         /* DAC scale */
425         { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
426         /* ?default */
427         { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
428         /* Validate Settings */
429         { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
430 };
431
432 static const __u8 initPas202[] = {
433         0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
434         0x00, 0x00,
435         0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
436         0x28, 0x1e, 0x28, 0x89, 0x20,
437         0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
438 };
439 static const __u8 pas202_sensor_init[][8] = {
440         {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
441         {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
442         {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
443         {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
444         {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
445         {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
446         {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
447         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
448         {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
449         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
450         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
451         {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
452
453         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
454         {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
455         {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
456         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
457         {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
458         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
459         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
460         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
461 };
462
463 static const __u8 initTas5110[] = {
464         0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
465         0x00, 0x00,
466         0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
467         0x16, 0x12, 0x60, 0x86, 0x2b,
468         0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
469 };
470 static const __u8 tas5110_sensor_init[][8] = {
471         {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
472         {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
473         {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
474 };
475
476 static const __u8 initTas5130[] = {
477         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
478         0x00, 0x00,
479         0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
480         0x28, 0x1e, 0x60, COMP, MCK_INIT,
481         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
482 };
483 static const __u8 tas5130_sensor_init[][8] = {
484 /*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
485                                         * shutter 0x47 short exposure? */
486         {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
487                                         /* shutter 0x01 long exposure */
488         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
489 };
490
491 static struct sensor_data sensor_data[] = {
492 SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
493 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
494 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
495         F_GAIN, 0, 0x21),
496 SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
497         0),
498 SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
499         NO_EXPO|NO_FREQ, 0),
500 SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
501         NO_BRIGHTNESS|NO_FREQ, 0),
502 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
503         0),
504 };
505
506 /* get one byte in gspca_dev->usb_buf */
507 static void reg_r(struct gspca_dev *gspca_dev,
508                   __u16 value)
509 {
510         usb_control_msg(gspca_dev->dev,
511                         usb_rcvctrlpipe(gspca_dev->dev, 0),
512                         0,                      /* request */
513                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
514                         value,
515                         0,                      /* index */
516                         gspca_dev->usb_buf, 1,
517                         500);
518 }
519
520 static void reg_w(struct gspca_dev *gspca_dev,
521                   __u16 value,
522                   const __u8 *buffer,
523                   int len)
524 {
525 #ifdef GSPCA_DEBUG
526         if (len > USB_BUF_SZ) {
527                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
528                 return;
529         }
530 #endif
531         memcpy(gspca_dev->usb_buf, buffer, len);
532         usb_control_msg(gspca_dev->dev,
533                         usb_sndctrlpipe(gspca_dev->dev, 0),
534                         0x08,                   /* request */
535                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
536                         value,
537                         0,                      /* index */
538                         gspca_dev->usb_buf, len,
539                         500);
540 }
541
542 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
543 {
544         int retry = 60;
545
546         /* is i2c ready */
547         reg_w(gspca_dev, 0x08, buffer, 8);
548         while (retry--) {
549                 msleep(10);
550                 reg_r(gspca_dev, 0x08);
551                 if (gspca_dev->usb_buf[0] & 0x04) {
552                         if (gspca_dev->usb_buf[0] & 0x08)
553                                 return -1;
554                         return 0;
555                 }
556         }
557         return -1;
558 }
559
560 static void i2c_w_vector(struct gspca_dev *gspca_dev,
561                         const __u8 buffer[][8], int len)
562 {
563         for (;;) {
564                 reg_w(gspca_dev, 0x08, *buffer, 8);
565                 len -= 8;
566                 if (len <= 0)
567                         break;
568                 buffer++;
569         }
570 }
571
572 static void setbrightness(struct gspca_dev *gspca_dev)
573 {
574         struct sd *sd = (struct sd *) gspca_dev;
575         __u8 value;
576
577         switch (sd->sensor) {
578         case  SENSOR_OV6650:
579         case  SENSOR_OV7630: {
580                 __u8 i2cOV[] =
581                         {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
582
583                 /* change reg 0x06 */
584                 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
585                 i2cOV[3] = sd->brightness;
586                 if (i2c_w(gspca_dev, i2cOV) < 0)
587                         goto err;
588                 break;
589             }
590         case SENSOR_PAS106: {
591                 __u8 i2c1[] =
592                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
593
594                 i2c1[3] = sd->brightness >> 3;
595                 i2c1[2] = 0x0e;
596                 if (i2c_w(gspca_dev, i2c1) < 0)
597                         goto err;
598                 i2c1[3] = 0x01;
599                 i2c1[2] = 0x13;
600                 if (i2c_w(gspca_dev, i2c1) < 0)
601                         goto err;
602                 break;
603             }
604         case SENSOR_PAS202: {
605                 /* __u8 i2cpexpo1[] =
606                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
607                 __u8 i2cpexpo[] =
608                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
609                 __u8 i2cp202[] =
610                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
611                 static __u8 i2cpdoit[] =
612                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
613
614                 /* change reg 0x10 */
615                 i2cpexpo[4] = 0xff - sd->brightness;
616 /*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
617                         goto err; */
618 /*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
619                         goto err; */
620                 if (i2c_w(gspca_dev, i2cpexpo) < 0)
621                         goto err;
622                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
623                         goto err;
624                 i2cp202[3] = sd->brightness >> 3;
625                 if (i2c_w(gspca_dev, i2cp202) < 0)
626                         goto err;
627                 if (i2c_w(gspca_dev, i2cpdoit) < 0)
628                         goto err;
629                 break;
630             }
631         case SENSOR_TAS5130CXX: {
632                 __u8 i2c[] =
633                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
634
635                 value = 0xff - sd->brightness;
636                 i2c[4] = value;
637                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
638                 if (i2c_w(gspca_dev, i2c) < 0)
639                         goto err;
640                 break;
641             }
642         }
643         return;
644 err:
645         PDEBUG(D_ERR, "i2c error brightness");
646 }
647
648 static void setsensorgain(struct gspca_dev *gspca_dev)
649 {
650         struct sd *sd = (struct sd *) gspca_dev;
651         unsigned char gain = sd->gain;
652
653         switch (sd->sensor) {
654
655         case SENSOR_TAS5110: {
656                 __u8 i2c[] =
657                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
658
659                 i2c[4] = 255 - gain;
660                 if (i2c_w(gspca_dev, i2c) < 0)
661                         goto err;
662                 break;
663             }
664
665         case SENSOR_OV6650:
666                 gain >>= 1;
667                 /* fall thru */
668         case SENSOR_OV7630: {
669                 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
670
671                 i2c[1] = sensor_data[sd->sensor].sensor_addr;
672                 i2c[3] = gain >> 2;
673                 if (i2c_w(gspca_dev, i2c) < 0)
674                         goto err;
675                 break;
676             }
677         }
678         return;
679 err:
680         PDEBUG(D_ERR, "i2c error gain");
681 }
682
683 static void setgain(struct gspca_dev *gspca_dev)
684 {
685         struct sd *sd = (struct sd *) gspca_dev;
686         __u8 gain;
687         __u8 rgb_value;
688
689         gain = sd->gain >> 4;
690
691         /* red and blue gain */
692         rgb_value = gain << 4 | gain;
693         reg_w(gspca_dev, 0x10, &rgb_value, 1);
694         /* green gain */
695         rgb_value = gain;
696         reg_w(gspca_dev, 0x11, &rgb_value, 1);
697
698         if (sensor_data[sd->sensor].flags & F_GAIN)
699                 setsensorgain(gspca_dev);
700 }
701
702 static void setexposure(struct gspca_dev *gspca_dev)
703 {
704         struct sd *sd = (struct sd *) gspca_dev;
705
706         switch (sd->sensor) {
707         case SENSOR_TAS5110: {
708                 __u8 reg;
709
710                 /* register 19's high nibble contains the sn9c10x clock divider
711                    The high nibble configures the no fps according to the
712                    formula: 60 / high_nibble. With a maximum of 30 fps */
713                 reg = 120 * sd->exposure / 1000;
714                 if (reg < 2)
715                         reg = 2;
716                 else if (reg > 15)
717                         reg = 15;
718                 reg = (reg << 4) | 0x0b;
719                 reg_w(gspca_dev, 0x19, &reg, 1);
720                 break;
721             }
722         case SENSOR_OV6650:
723         case SENSOR_OV7630: {
724                 /* The ov6650 / ov7630 have 2 registers which both influence
725                    exposure, register 11, whose low nibble sets the nr off fps
726                    according to: fps = 30 / (low_nibble + 1)
727
728                    The fps configures the maximum exposure setting, but it is
729                    possible to use less exposure then what the fps maximum
730                    allows by setting register 10. register 10 configures the
731                    actual exposure as quotient of the full exposure, with 0
732                    being no exposure at all (not very usefull) and reg10_max
733                    being max exposure possible at that framerate.
734
735                    The code maps our 0 - 510 ms exposure ctrl to these 2
736                    registers, trying to keep fps as high as possible.
737                 */
738                 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
739                 int reg10, reg11, reg10_max;
740
741                 /* ov6645 datasheet says reg10_max is 9a, but that uses
742                    tline * 2 * reg10 as formula for calculating texpo, the
743                    ov6650 probably uses the same formula as the 7730 which uses
744                    tline * 4 * reg10, which explains why the reg10max we've
745                    found experimentally for the ov6650 is exactly half that of
746                    the ov6645. The ov7630 datasheet says the max is 0x41. */
747                 if (sd->sensor == SENSOR_OV6650) {
748                         reg10_max = 0x4d;
749                         i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
750                 } else
751                         reg10_max = 0x41;
752
753                 reg11 = (60 * sd->exposure + 999) / 1000;
754                 if (reg11 < 1)
755                         reg11 = 1;
756                 else if (reg11 > 16)
757                         reg11 = 16;
758
759                 /* In 640x480, if the reg11 has less than 3, the image is
760                    unstable (not enough bandwidth). */
761                 if (gspca_dev->width == 640 && reg11 < 3)
762                         reg11 = 3;
763
764                 /* frame exposure time in ms = 1000 * reg11 / 30    ->
765                 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
766                 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
767
768                 /* Don't allow this to get below 10 when using autogain, the
769                    steps become very large (relatively) when below 10 causing
770                    the image to oscilate from much too dark, to much too bright
771                    and back again. */
772                 if (sd->autogain && reg10 < 10)
773                         reg10 = 10;
774                 else if (reg10 > reg10_max)
775                         reg10 = reg10_max;
776
777                 /* Write reg 10 and reg11 low nibble */
778                 i2c[1] = sensor_data[sd->sensor].sensor_addr;
779                 i2c[3] = reg10;
780                 i2c[4] |= reg11 - 1;
781
782                 /* If register 11 didn't change, don't change it */
783                 if (sd->reg11 == reg11 )
784                         i2c[0] = 0xa0;
785
786                 if (i2c_w(gspca_dev, i2c) == 0)
787                         sd->reg11 = reg11;
788                 else
789                         PDEBUG(D_ERR, "i2c error exposure");
790                 break;
791             }
792         }
793 }
794
795 static void setfreq(struct gspca_dev *gspca_dev)
796 {
797         struct sd *sd = (struct sd *) gspca_dev;
798
799         switch (sd->sensor) {
800         case SENSOR_OV6650:
801         case SENSOR_OV7630: {
802                 /* Framerate adjust register for artificial light 50 hz flicker
803                    compensation, for the ov6650 this is identical to ov6630
804                    0x2b register, see ov6630 datasheet.
805                    0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
806                 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
807                 switch (sd->freq) {
808                 default:
809 /*              case 0:                  * no filter*/
810 /*              case 2:                  * 60 hz */
811                         i2c[3] = 0;
812                         break;
813                 case 1:                 /* 50 hz */
814                         i2c[3] = (sd->sensor == SENSOR_OV6650)
815                                         ? 0x4f : 0x8a;
816                         break;
817                 }
818                 i2c[1] = sensor_data[sd->sensor].sensor_addr;
819                 if (i2c_w(gspca_dev, i2c) < 0)
820                         PDEBUG(D_ERR, "i2c error setfreq");
821                 break;
822             }
823         }
824 }
825
826 static void do_autogain(struct gspca_dev *gspca_dev)
827 {
828         int deadzone, desired_avg_lum;
829         struct sd *sd = (struct sd *) gspca_dev;
830         int avg_lum = atomic_read(&sd->avg_lum);
831
832         if (avg_lum == -1)
833                 return;
834
835         /* SIF / VGA sensors have a different autoexposure area and thus
836            different avg_lum values for the same picture brightness */
837         if (sensor_data[sd->sensor].flags & F_SIF) {
838                 deadzone = 1000;
839                 desired_avg_lum = 7000;
840         } else {
841                 deadzone = 3000;
842                 desired_avg_lum = 23000;
843         }
844
845         if (sd->autogain_ignore_frames > 0)
846                 sd->autogain_ignore_frames--;
847         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
848                         sd->brightness * desired_avg_lum / 127,
849                         deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
850                 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
851                         (int)sd->gain, (int)sd->exposure);
852                 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
853         }
854 }
855
856 /* this function is called at probe time */
857 static int sd_config(struct gspca_dev *gspca_dev,
858                         const struct usb_device_id *id)
859 {
860         struct sd *sd = (struct sd *) gspca_dev;
861         struct cam *cam;
862
863         reg_r(gspca_dev, 0x00);
864         if (gspca_dev->usb_buf[0] != 0x10)
865                 return -ENODEV;
866
867         /* copy the webcam info from the device id */
868         sd->sensor = id->driver_info >> 8;
869         sd->bridge = id->driver_info & 0xff;
870         gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
871
872         cam = &gspca_dev->cam;
873         if (!(sensor_data[sd->sensor].flags & F_SIF)) {
874                 cam->cam_mode = vga_mode;
875                 cam->nmodes = ARRAY_SIZE(vga_mode);
876         } else {
877                 cam->cam_mode = sif_mode;
878                 cam->nmodes = ARRAY_SIZE(sif_mode);
879         }
880         sd->brightness = BRIGHTNESS_DEF;
881         sd->gain = GAIN_DEF;
882         sd->exposure = EXPOSURE_DEF;
883         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
884                 sd->autogain = 0; /* Disable do_autogain callback */
885         else
886                 sd->autogain = AUTOGAIN_DEF;
887         sd->freq = FREQ_DEF;
888
889         return 0;
890 }
891
892 /* this function is called at probe and resume time */
893 static int sd_init(struct gspca_dev *gspca_dev)
894 {
895         const __u8 stop = 0x09; /* Disable stream turn of LED */
896
897         reg_w(gspca_dev, 0x01, &stop, 1);
898
899         return 0;
900 }
901
902 /* -- start the camera -- */
903 static int sd_start(struct gspca_dev *gspca_dev)
904 {
905         struct sd *sd = (struct sd *) gspca_dev;
906         struct cam *cam = &gspca_dev->cam;
907         int mode, l;
908         const __u8 *sn9c10x;
909         __u8 reg12_19[8];
910
911         mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
912         sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
913         l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
914         memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
915         reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
916         /* Special cases where reg 17 and or 19 value depends on mode */
917         switch (sd->sensor) {
918         case SENSOR_PAS202:
919                 reg12_19[5] = mode ? 0x24 : 0x20;
920                 break;
921         case SENSOR_TAS5130CXX:
922                 /* probably not mode specific at all most likely the upper
923                    nibble of 0x19 is exposure (clock divider) just as with
924                    the tas5110, we need someone to test this. */
925                 reg12_19[7] = mode ? 0x23 : 0x43;
926                 break;
927         }
928         /* Disable compression when the raw bayer format has been selected */
929         if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
930                 reg12_19[6] &= ~0x80;
931
932         /* Vga mode emulation on SIF sensor? */
933         if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
934                 reg12_19[0] += 16; /* 0x12: hstart adjust */
935                 reg12_19[1] += 24; /* 0x13: vstart adjust */
936                 reg12_19[3] = 320 / 16; /* 0x15: hsize */
937                 reg12_19[4] = 240 / 16; /* 0x16: vsize */
938         }
939
940         /* reg 0x01 bit 2 video transfert on */
941         reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
942         /* reg 0x17 SensorClk enable inv Clk 0x60 */
943         reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
944         /* Set the registers from the template */
945         reg_w(gspca_dev, 0x01, sn9c10x, l);
946
947         /* Init the sensor */
948         i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
949                         sensor_data[sd->sensor].sensor_init_size);
950         if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
951                 i2c_w_vector(gspca_dev,
952                         sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
953                         sensor_data[sd->sensor].sensor_bridge_init_size[
954                                 sd->bridge]);
955
956         /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
957         reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
958         /* compression register */
959         reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
960         /* H_start */
961         reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
962         /* V_START */
963         reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
964         /* reset 0x17 SensorClk enable inv Clk 0x60 */
965                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
966         reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
967         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
968         reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
969         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
970         reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
971         /* Enable video transfert */
972         reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
973         /* Compression */
974         reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
975         msleep(20);
976
977         sd->reg11 = -1;
978
979         setgain(gspca_dev);
980         setbrightness(gspca_dev);
981         setexposure(gspca_dev);
982         setfreq(gspca_dev);
983
984         sd->frames_to_drop = 0;
985         sd->autogain_ignore_frames = 0;
986         atomic_set(&sd->avg_lum, -1);
987         return 0;
988 }
989
990 static void sd_stopN(struct gspca_dev *gspca_dev)
991 {
992         sd_init(gspca_dev);
993 }
994
995 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
996                         struct gspca_frame *frame,      /* target */
997                         unsigned char *data,            /* isoc packet */
998                         int len)                        /* iso packet length */
999 {
1000         int i;
1001         struct sd *sd = (struct sd *) gspca_dev;
1002         struct cam *cam = &gspca_dev->cam;
1003
1004         /* frames start with:
1005          *      ff ff 00 c4 c4 96       synchro
1006          *      00              (unknown)
1007          *      xx              (frame sequence / size / compression)
1008          *      (xx)            (idem - extra byte for sn9c103)
1009          *      ll mm           brightness sum inside auto exposure
1010          *      ll mm           brightness sum outside auto exposure
1011          *      (xx xx xx xx xx)        audio values for snc103
1012          */
1013         if (len > 6 && len < 24) {
1014                 for (i = 0; i < len - 6; i++) {
1015                         if (data[0 + i] == 0xff
1016                             && data[1 + i] == 0xff
1017                             && data[2 + i] == 0x00
1018                             && data[3 + i] == 0xc4
1019                             && data[4 + i] == 0xc4
1020                             && data[5 + i] == 0x96) {   /* start of frame */
1021                                 int lum = -1;
1022                                 int pkt_type = LAST_PACKET;
1023                                 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1024                                         18 : 12;
1025
1026                                 if (len - i < fr_h_sz) {
1027                                         PDEBUG(D_STREAM, "packet too short to"
1028                                                 " get avg brightness");
1029                                 } else if (sd->bridge == BRIDGE_103) {
1030                                         lum = data[i + 9] +
1031                                                 (data[i + 10] << 8);
1032                                 } else {
1033                                         lum = data[i + 8] + (data[i + 9] << 8);
1034                                 }
1035                                 /* When exposure changes midway a frame we
1036                                    get a lum of 0 in this case drop 2 frames
1037                                    as the frames directly after an exposure
1038                                    change have an unstable image. Sometimes lum
1039                                    *really* is 0 (cam used in low light with
1040                                    low exposure setting), so do not drop frames
1041                                    if the previous lum was 0 too. */
1042                                 if (lum == 0 && sd->prev_avg_lum != 0) {
1043                                         lum = -1;
1044                                         sd->frames_to_drop = 2;
1045                                         sd->prev_avg_lum = 0;
1046                                 } else
1047                                         sd->prev_avg_lum = lum;
1048                                 atomic_set(&sd->avg_lum, lum);
1049
1050                                 if (sd->frames_to_drop) {
1051                                         sd->frames_to_drop--;
1052                                         pkt_type = DISCARD_PACKET;
1053                                 }
1054
1055                                 frame = gspca_frame_add(gspca_dev, pkt_type,
1056                                                         frame, data, 0);
1057                                 data += i + fr_h_sz;
1058                                 len -= i + fr_h_sz;
1059                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1060                                                 frame, data, len);
1061                                 return;
1062                         }
1063                 }
1064         }
1065
1066         if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1067                 /* In raw mode we sometimes get some garbage after the frame
1068                    ignore this */
1069                 int used = frame->data_end - frame->data;
1070                 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1071
1072                 if (used + len > size)
1073                         len = size - used;
1074         }
1075
1076         gspca_frame_add(gspca_dev, INTER_PACKET,
1077                         frame, data, len);
1078 }
1079
1080 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1081 {
1082         struct sd *sd = (struct sd *) gspca_dev;
1083
1084         sd->brightness = val;
1085         if (gspca_dev->streaming)
1086                 setbrightness(gspca_dev);
1087         return 0;
1088 }
1089
1090 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1091 {
1092         struct sd *sd = (struct sd *) gspca_dev;
1093
1094         *val = sd->brightness;
1095         return 0;
1096 }
1097
1098 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1099 {
1100         struct sd *sd = (struct sd *) gspca_dev;
1101
1102         sd->gain = val;
1103         if (gspca_dev->streaming)
1104                 setgain(gspca_dev);
1105         return 0;
1106 }
1107
1108 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1109 {
1110         struct sd *sd = (struct sd *) gspca_dev;
1111
1112         *val = sd->gain;
1113         return 0;
1114 }
1115
1116 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1117 {
1118         struct sd *sd = (struct sd *) gspca_dev;
1119
1120         sd->exposure = val;
1121         if (gspca_dev->streaming)
1122                 setexposure(gspca_dev);
1123         return 0;
1124 }
1125
1126 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1127 {
1128         struct sd *sd = (struct sd *) gspca_dev;
1129
1130         *val = sd->exposure;
1131         return 0;
1132 }
1133
1134 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1135 {
1136         struct sd *sd = (struct sd *) gspca_dev;
1137
1138         sd->autogain = val;
1139         /* when switching to autogain set defaults to make sure
1140            we are on a valid point of the autogain gain /
1141            exposure knee graph, and give this change time to
1142            take effect before doing autogain. */
1143         if (sd->autogain) {
1144                 sd->exposure = EXPOSURE_DEF;
1145                 sd->gain = GAIN_DEF;
1146                 if (gspca_dev->streaming) {
1147                         sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1148                         setexposure(gspca_dev);
1149                         setgain(gspca_dev);
1150                 }
1151         }
1152
1153         return 0;
1154 }
1155
1156 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1157 {
1158         struct sd *sd = (struct sd *) gspca_dev;
1159
1160         *val = sd->autogain;
1161         return 0;
1162 }
1163
1164 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1165 {
1166         struct sd *sd = (struct sd *) gspca_dev;
1167
1168         sd->freq = val;
1169         if (gspca_dev->streaming)
1170                 setfreq(gspca_dev);
1171         return 0;
1172 }
1173
1174 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1175 {
1176         struct sd *sd = (struct sd *) gspca_dev;
1177
1178         *val = sd->freq;
1179         return 0;
1180 }
1181
1182 static int sd_querymenu(struct gspca_dev *gspca_dev,
1183                         struct v4l2_querymenu *menu)
1184 {
1185         switch (menu->id) {
1186         case V4L2_CID_POWER_LINE_FREQUENCY:
1187                 switch (menu->index) {
1188                 case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1189                         strcpy((char *) menu->name, "NoFliker");
1190                         return 0;
1191                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1192                         strcpy((char *) menu->name, "50 Hz");
1193                         return 0;
1194                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1195                         strcpy((char *) menu->name, "60 Hz");
1196                         return 0;
1197                 }
1198                 break;
1199         }
1200         return -EINVAL;
1201 }
1202
1203 /* sub-driver description */
1204 static const struct sd_desc sd_desc = {
1205         .name = MODULE_NAME,
1206         .ctrls = sd_ctrls,
1207         .nctrls = ARRAY_SIZE(sd_ctrls),
1208         .config = sd_config,
1209         .init = sd_init,
1210         .start = sd_start,
1211         .stopN = sd_stopN,
1212         .pkt_scan = sd_pkt_scan,
1213         .querymenu = sd_querymenu,
1214         .dq_callback = do_autogain,
1215 };
1216
1217 /* -- module initialisation -- */
1218 #define SB(sensor, bridge) \
1219         .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1220
1221
1222 static __devinitdata struct usb_device_id device_table[] = {
1223         {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
1224         {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
1225 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1226         {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
1227         {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1228         {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1229 #endif
1230         {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1231 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1232         {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1233         {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1234         {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1235         {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1236         {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1237 #endif
1238         {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1239         {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1240 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1241         {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1242 #endif
1243         {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1244 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1245         {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1246 #endif
1247         {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1248         {}
1249 };
1250 MODULE_DEVICE_TABLE(usb, device_table);
1251
1252 /* -- device connect -- */
1253 static int sd_probe(struct usb_interface *intf,
1254                         const struct usb_device_id *id)
1255 {
1256         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1257                                 THIS_MODULE);
1258 }
1259
1260 static struct usb_driver sd_driver = {
1261         .name = MODULE_NAME,
1262         .id_table = device_table,
1263         .probe = sd_probe,
1264         .disconnect = gspca_disconnect,
1265 #ifdef CONFIG_PM
1266         .suspend = gspca_suspend,
1267         .resume = gspca_resume,
1268 #endif
1269 };
1270
1271 /* -- module insert / remove -- */
1272 static int __init sd_mod_init(void)
1273 {
1274         int ret;
1275         ret = usb_register(&sd_driver);
1276         if (ret < 0)
1277                 return ret;
1278         PDEBUG(D_PROBE, "registered");
1279         return 0;
1280 }
1281 static void __exit sd_mod_exit(void)
1282 {
1283         usb_deregister(&sd_driver);
1284         PDEBUG(D_PROBE, "deregistered");
1285 }
1286
1287 module_init(sd_mod_init);
1288 module_exit(sd_mod_exit);