pandora: defconfig: update
[pandora-kernel.git] / drivers / media / video / gspca / ov534_9.c
1 /*
2  * ov534-ov9xxx gspca driver
3  *
4  * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr
5  * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
6  * Copyright (C) 2008 Jim Paris <jim@jtan.com>
7  *
8  * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9  * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10  * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25  */
26
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
29 #define MODULE_NAME "ov534_9"
30
31 #include "gspca.h"
32
33 #define OV534_REG_ADDRESS       0xf1    /* sensor address */
34 #define OV534_REG_SUBADDR       0xf2
35 #define OV534_REG_WRITE         0xf3
36 #define OV534_REG_READ          0xf4
37 #define OV534_REG_OPERATION     0xf5
38 #define OV534_REG_STATUS        0xf6
39
40 #define OV534_OP_WRITE_3        0x37
41 #define OV534_OP_WRITE_2        0x33
42 #define OV534_OP_READ_2         0xf9
43
44 #define CTRL_TIMEOUT 500
45
46 MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
47 MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
48 MODULE_LICENSE("GPL");
49
50 /* controls */
51 enum e_ctrl {
52         BRIGHTNESS,
53         CONTRAST,
54         AUTOGAIN,
55         EXPOSURE,
56         SHARPNESS,
57         SATUR,
58         LIGHTFREQ,
59         NCTRLS          /* number of controls */
60 };
61
62 /* specific webcam descriptor */
63 struct sd {
64         struct gspca_dev gspca_dev;     /* !! must be the first item */
65         struct gspca_ctrl ctrls[NCTRLS];
66         __u32 last_pts;
67         u8 last_fid;
68
69         u8 sensor;
70 };
71 enum sensors {
72         SENSOR_OV965x,          /* ov9657 */
73         SENSOR_OV971x,          /* ov9712 */
74         NSENSORS
75 };
76
77 /* V4L2 controls supported by the driver */
78 static void setbrightness(struct gspca_dev *gspca_dev);
79 static void setcontrast(struct gspca_dev *gspca_dev);
80 static void setautogain(struct gspca_dev *gspca_dev);
81 static void setexposure(struct gspca_dev *gspca_dev);
82 static void setsharpness(struct gspca_dev *gspca_dev);
83 static void setsatur(struct gspca_dev *gspca_dev);
84 static void setlightfreq(struct gspca_dev *gspca_dev);
85
86 static const struct ctrl sd_ctrls[NCTRLS] = {
87 [BRIGHTNESS] = {
88         {
89                 .id      = V4L2_CID_BRIGHTNESS,
90                 .type    = V4L2_CTRL_TYPE_INTEGER,
91                 .name    = "Brightness",
92                 .minimum = 0,
93                 .maximum = 15,
94                 .step    = 1,
95                 .default_value = 7
96         },
97         .set_control = setbrightness
98     },
99 [CONTRAST] = {
100         {
101                 .id      = V4L2_CID_CONTRAST,
102                 .type    = V4L2_CTRL_TYPE_INTEGER,
103                 .name    = "Contrast",
104                 .minimum = 0,
105                 .maximum = 15,
106                 .step    = 1,
107                 .default_value = 3
108         },
109         .set_control = setcontrast
110     },
111 [AUTOGAIN] = {
112         {
113                 .id      = V4L2_CID_AUTOGAIN,
114                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
115                 .name    = "Autogain",
116                 .minimum = 0,
117                 .maximum = 1,
118                 .step    = 1,
119 #define AUTOGAIN_DEF 1
120                 .default_value = AUTOGAIN_DEF,
121         },
122         .set_control = setautogain
123     },
124 [EXPOSURE] = {
125         {
126                 .id      = V4L2_CID_EXPOSURE,
127                 .type    = V4L2_CTRL_TYPE_INTEGER,
128                 .name    = "Exposure",
129                 .minimum = 0,
130                 .maximum = 3,
131                 .step    = 1,
132                 .default_value = 0
133         },
134         .set_control = setexposure
135     },
136 [SHARPNESS] = {
137         {
138                 .id      = V4L2_CID_SHARPNESS,
139                 .type    = V4L2_CTRL_TYPE_INTEGER,
140                 .name    = "Sharpness",
141                 .minimum = -1,          /* -1 = auto */
142                 .maximum = 4,
143                 .step    = 1,
144                 .default_value = -1
145         },
146         .set_control = setsharpness
147     },
148 [SATUR] = {
149         {
150                 .id      = V4L2_CID_SATURATION,
151                 .type    = V4L2_CTRL_TYPE_INTEGER,
152                 .name    = "Saturation",
153                 .minimum = 0,
154                 .maximum = 4,
155                 .step    = 1,
156                 .default_value = 2
157         },
158         .set_control = setsatur
159     },
160 [LIGHTFREQ] = {
161         {
162                 .id      = V4L2_CID_POWER_LINE_FREQUENCY,
163                 .type    = V4L2_CTRL_TYPE_MENU,
164                 .name    = "Light frequency filter",
165                 .minimum = 0,
166                 .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
167                 .step    = 1,
168                 .default_value = 0
169         },
170         .set_control = setlightfreq
171     },
172 };
173
174 static const struct v4l2_pix_format ov965x_mode[] = {
175 #define QVGA_MODE 0
176         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
177                 .bytesperline = 320,
178                 .sizeimage = 320 * 240 * 3 / 8 + 590,
179                 .colorspace = V4L2_COLORSPACE_JPEG},
180 #define VGA_MODE 1
181         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
182                 .bytesperline = 640,
183                 .sizeimage = 640 * 480 * 3 / 8 + 590,
184                 .colorspace = V4L2_COLORSPACE_JPEG},
185 #define SVGA_MODE 2
186         {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
187                 .bytesperline = 800,
188                 .sizeimage = 800 * 600 * 3 / 8 + 590,
189                 .colorspace = V4L2_COLORSPACE_JPEG},
190 #define XGA_MODE 3
191         {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
192                 .bytesperline = 1024,
193                 .sizeimage = 1024 * 768 * 3 / 8 + 590,
194                 .colorspace = V4L2_COLORSPACE_JPEG},
195 #define SXGA_MODE 4
196         {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
197                 .bytesperline = 1280,
198                 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
199                 .colorspace = V4L2_COLORSPACE_JPEG},
200 };
201
202 static const struct v4l2_pix_format ov971x_mode[] = {
203         {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
204                 .bytesperline = 640,
205                 .sizeimage = 640 * 480,
206                 .colorspace = V4L2_COLORSPACE_SRGB
207         }
208 };
209
210 static const u8 bridge_init[][2] = {
211         {0x88, 0xf8},
212         {0x89, 0xff},
213         {0x76, 0x03},
214         {0x92, 0x03},
215         {0x95, 0x10},
216         {0xe2, 0x00},
217         {0xe7, 0x3e},
218         {0x8d, 0x1c},
219         {0x8e, 0x00},
220         {0x8f, 0x00},
221         {0x1f, 0x00},
222         {0xc3, 0xf9},
223         {0x89, 0xff},
224         {0x88, 0xf8},
225         {0x76, 0x03},
226         {0x92, 0x01},
227         {0x93, 0x18},
228         {0x1c, 0x0a},
229         {0x1d, 0x48},
230         {0xc0, 0x50},
231         {0xc1, 0x3c},
232         {0x34, 0x05},
233         {0xc2, 0x0c},
234         {0xc3, 0xf9},
235         {0x34, 0x05},
236         {0xe7, 0x2e},
237         {0x31, 0xf9},
238         {0x35, 0x02},
239         {0xd9, 0x10},
240         {0x25, 0x42},
241         {0x94, 0x11},
242 };
243
244 static const u8 ov965x_init[][2] = {
245         {0x12, 0x80},   /* com7 - SSCB reset */
246         {0x00, 0x00},   /* gain */
247         {0x01, 0x80},   /* blue */
248         {0x02, 0x80},   /* red */
249         {0x03, 0x1b},   /* vref */
250         {0x04, 0x03},   /* com1 - exposure low bits */
251         {0x0b, 0x57},   /* ver */
252         {0x0e, 0x61},   /* com5 */
253         {0x0f, 0x42},   /* com6 */
254         {0x11, 0x00},   /* clkrc */
255         {0x12, 0x02},   /* com7 - 15fps VGA YUYV */
256         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
257         {0x14, 0x28},   /* com9 */
258         {0x16, 0x24},   /* reg16 */
259         {0x17, 0x1d},   /* hstart*/
260         {0x18, 0xbd},   /* hstop */
261         {0x19, 0x01},   /* vstrt */
262         {0x1a, 0x81},   /* vstop*/
263         {0x1e, 0x04},   /* mvfp */
264         {0x24, 0x3c},   /* aew */
265         {0x25, 0x36},   /* aeb */
266         {0x26, 0x71},   /* vpt */
267         {0x27, 0x08},   /* bbias */
268         {0x28, 0x08},   /* gbbias */
269         {0x29, 0x15},   /* gr com */
270         {0x2a, 0x00},   /* exhch */
271         {0x2b, 0x00},   /* exhcl */
272         {0x2c, 0x08},   /* rbias */
273         {0x32, 0xff},   /* href */
274         {0x33, 0x00},   /* chlf */
275         {0x34, 0x3f},   /* aref1 */
276         {0x35, 0x00},   /* aref2 */
277         {0x36, 0xf8},   /* aref3 */
278         {0x38, 0x72},   /* adc2 */
279         {0x39, 0x57},   /* aref4 */
280         {0x3a, 0x80},   /* tslb - yuyv */
281         {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
282         {0x3d, 0x99},   /* com13 */
283         {0x3f, 0xc1},   /* edge */
284         {0x40, 0xc0},   /* com15 */
285         {0x41, 0x40},   /* com16 */
286         {0x42, 0xc0},   /* com17 */
287         {0x43, 0x0a},   /* rsvd */
288         {0x44, 0xf0},
289         {0x45, 0x46},
290         {0x46, 0x62},
291         {0x47, 0x2a},
292         {0x48, 0x3c},
293         {0x4a, 0xfc},
294         {0x4b, 0xfc},
295         {0x4c, 0x7f},
296         {0x4d, 0x7f},
297         {0x4e, 0x7f},
298         {0x4f, 0x98},   /* matrix */
299         {0x50, 0x98},
300         {0x51, 0x00},
301         {0x52, 0x28},
302         {0x53, 0x70},
303         {0x54, 0x98},
304         {0x58, 0x1a},   /* matrix coef sign */
305         {0x59, 0x85},   /* AWB control */
306         {0x5a, 0xa9},
307         {0x5b, 0x64},
308         {0x5c, 0x84},
309         {0x5d, 0x53},
310         {0x5e, 0x0e},
311         {0x5f, 0xf0},   /* AWB blue limit */
312         {0x60, 0xf0},   /* AWB red limit */
313         {0x61, 0xf0},   /* AWB green limit */
314         {0x62, 0x00},   /* lcc1 */
315         {0x63, 0x00},   /* lcc2 */
316         {0x64, 0x02},   /* lcc3 */
317         {0x65, 0x16},   /* lcc4 */
318         {0x66, 0x01},   /* lcc5 */
319         {0x69, 0x02},   /* hv */
320         {0x6b, 0x5a},   /* dbvl */
321         {0x6c, 0x04},
322         {0x6d, 0x55},
323         {0x6e, 0x00},
324         {0x6f, 0x9d},
325         {0x70, 0x21},   /* dnsth */
326         {0x71, 0x78},
327         {0x72, 0x00},   /* poidx */
328         {0x73, 0x01},   /* pckdv */
329         {0x74, 0x3a},   /* xindx */
330         {0x75, 0x35},   /* yindx */
331         {0x76, 0x01},
332         {0x77, 0x02},
333         {0x7a, 0x12},   /* gamma curve */
334         {0x7b, 0x08},
335         {0x7c, 0x16},
336         {0x7d, 0x30},
337         {0x7e, 0x5e},
338         {0x7f, 0x72},
339         {0x80, 0x82},
340         {0x81, 0x8e},
341         {0x82, 0x9a},
342         {0x83, 0xa4},
343         {0x84, 0xac},
344         {0x85, 0xb8},
345         {0x86, 0xc3},
346         {0x87, 0xd6},
347         {0x88, 0xe6},
348         {0x89, 0xf2},
349         {0x8a, 0x03},
350         {0x8c, 0x89},   /* com19 */
351         {0x14, 0x28},   /* com9 */
352         {0x90, 0x7d},
353         {0x91, 0x7b},
354         {0x9d, 0x03},   /* lcc6 */
355         {0x9e, 0x04},   /* lcc7 */
356         {0x9f, 0x7a},
357         {0xa0, 0x79},
358         {0xa1, 0x40},   /* aechm */
359         {0xa4, 0x50},   /* com21 */
360         {0xa5, 0x68},   /* com26 */
361         {0xa6, 0x4a},   /* AWB green */
362         {0xa8, 0xc1},   /* refa8 */
363         {0xa9, 0xef},   /* refa9 */
364         {0xaa, 0x92},
365         {0xab, 0x04},
366         {0xac, 0x80},   /* black level control */
367         {0xad, 0x80},
368         {0xae, 0x80},
369         {0xaf, 0x80},
370         {0xb2, 0xf2},
371         {0xb3, 0x20},
372         {0xb4, 0x20},   /* ctrlb4 */
373         {0xb5, 0x00},
374         {0xb6, 0xaf},
375         {0xbb, 0xae},
376         {0xbc, 0x7f},   /* ADC channel offsets */
377         {0xdb, 0x7f},
378         {0xbe, 0x7f},
379         {0xbf, 0x7f},
380         {0xc0, 0xe2},
381         {0xc1, 0xc0},
382         {0xc2, 0x01},
383         {0xc3, 0x4e},
384         {0xc6, 0x85},
385         {0xc7, 0x80},   /* com24 */
386         {0xc9, 0xe0},
387         {0xca, 0xe8},
388         {0xcb, 0xf0},
389         {0xcc, 0xd8},
390         {0xcd, 0xf1},
391         {0x4f, 0x98},   /* matrix */
392         {0x50, 0x98},
393         {0x51, 0x00},
394         {0x52, 0x28},
395         {0x53, 0x70},
396         {0x54, 0x98},
397         {0x58, 0x1a},
398         {0xff, 0x41},   /* read 41, write ff 00 */
399         {0x41, 0x40},   /* com16 */
400
401         {0xc5, 0x03},   /* 60 Hz banding filter */
402         {0x6a, 0x02},   /* 50 Hz banding filter */
403
404         {0x12, 0x62},   /* com7 - 30fps VGA YUV */
405         {0x36, 0xfa},   /* aref3 */
406         {0x69, 0x0a},   /* hv */
407         {0x8c, 0x89},   /* com22 */
408         {0x14, 0x28},   /* com9 */
409         {0x3e, 0x0c},
410         {0x41, 0x40},   /* com16 */
411         {0x72, 0x00},
412         {0x73, 0x00},
413         {0x74, 0x3a},
414         {0x75, 0x35},
415         {0x76, 0x01},
416         {0xc7, 0x80},
417         {0x03, 0x12},   /* vref */
418         {0x17, 0x16},   /* hstart */
419         {0x18, 0x02},   /* hstop */
420         {0x19, 0x01},   /* vstrt */
421         {0x1a, 0x3d},   /* vstop */
422         {0x32, 0xff},   /* href */
423         {0xc0, 0xaa},
424 };
425
426 static const u8 bridge_init_2[][2] = {
427         {0x94, 0xaa},
428         {0xf1, 0x60},
429         {0xe5, 0x04},
430         {0xc0, 0x50},
431         {0xc1, 0x3c},
432         {0x8c, 0x00},
433         {0x8d, 0x1c},
434         {0x34, 0x05},
435
436         {0xc2, 0x0c},
437         {0xc3, 0xf9},
438         {0xda, 0x01},
439         {0x50, 0x00},
440         {0x51, 0xa0},
441         {0x52, 0x3c},
442         {0x53, 0x00},
443         {0x54, 0x00},
444         {0x55, 0x00},
445         {0x57, 0x00},
446         {0x5c, 0x00},
447         {0x5a, 0xa0},
448         {0x5b, 0x78},
449         {0x35, 0x02},
450         {0xd9, 0x10},
451         {0x94, 0x11},
452 };
453
454 static const u8 ov965x_init_2[][2] = {
455         {0x3b, 0xc4},
456         {0x1e, 0x04},   /* mvfp */
457         {0x13, 0xe0},   /* com8 */
458         {0x00, 0x00},   /* gain */
459         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
460         {0x11, 0x03},   /* clkrc */
461         {0x6b, 0x5a},   /* dblv */
462         {0x6a, 0x05},
463         {0xc5, 0x07},
464         {0xa2, 0x4b},
465         {0xa3, 0x3e},
466         {0x2d, 0x00},
467         {0xff, 0x42},   /* read 42, write ff 00 */
468         {0x42, 0xc0},   /* com17 */
469         {0x2d, 0x00},
470         {0xff, 0x42},   /* read 42, write ff 00 */
471         {0x42, 0xc1},   /* com17 */
472 /* sharpness */
473         {0x3f, 0x01},
474         {0xff, 0x42},   /* read 42, write ff 00 */
475         {0x42, 0xc1},   /* com17 */
476 /* saturation */
477         {0x4f, 0x98},   /* matrix */
478         {0x50, 0x98},
479         {0x51, 0x00},
480         {0x52, 0x28},
481         {0x53, 0x70},
482         {0x54, 0x98},
483         {0x58, 0x1a},
484         {0xff, 0x41},   /* read 41, write ff 00 */
485         {0x41, 0x40},   /* com16 */
486 /* contrast */
487         {0x56, 0x40},
488 /* brightness */
489         {0x55, 0x8f},
490 /* expo */
491         {0x10, 0x25},   /* aech - exposure high bits */
492         {0xff, 0x13},   /* read 13, write ff 00 */
493         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
494 };
495
496 static const u8 ov971x_init[][2] = {
497         {0x12, 0x80},
498         {0x09, 0x10},
499         {0x1e, 0x07},
500         {0x5f, 0x18},
501         {0x69, 0x04},
502         {0x65, 0x2a},
503         {0x68, 0x0a},
504         {0x39, 0x28},
505         {0x4d, 0x90},
506         {0xc1, 0x80},
507         {0x0c, 0x30},
508         {0x6d, 0x02},
509         {0x96, 0xf1},
510         {0xbc, 0x68},
511         {0x12, 0x00},
512         {0x3b, 0x00},
513         {0x97, 0x80},
514         {0x17, 0x25},
515         {0x18, 0xa2},
516         {0x19, 0x01},
517         {0x1a, 0xca},
518         {0x03, 0x0a},
519         {0x32, 0x07},
520         {0x98, 0x40},   /*{0x98, 0x00},*/
521         {0x99, 0xA0},   /*{0x99, 0x00},*/
522         {0x9a, 0x01},   /*{0x9a, 0x00},*/
523         {0x57, 0x00},
524         {0x58, 0x78},   /*{0x58, 0xc8},*/
525         {0x59, 0x50},   /*{0x59, 0xa0},*/
526         {0x4c, 0x13},
527         {0x4b, 0x36},
528         {0x3d, 0x3c},
529         {0x3e, 0x03},
530         {0xbd, 0x50},   /*{0xbd, 0xa0},*/
531         {0xbe, 0x78},   /*{0xbe, 0xc8},*/
532         {0x4e, 0x55},
533         {0x4f, 0x55},
534         {0x50, 0x55},
535         {0x51, 0x55},
536         {0x24, 0x55},
537         {0x25, 0x40},
538         {0x26, 0xa1},
539         {0x5c, 0x59},
540         {0x5d, 0x00},
541         {0x11, 0x00},
542         {0x2a, 0x98},
543         {0x2b, 0x06},
544         {0x2d, 0x00},
545         {0x2e, 0x00},
546         {0x13, 0xa5},
547         {0x14, 0x40},
548         {0x4a, 0x00},
549         {0x49, 0xce},
550         {0x22, 0x03},
551         {0x09, 0x00}
552 };
553
554 static const u8 ov965x_start_1_vga[][2] = {     /* same for qvga */
555         {0x12, 0x62},   /* com7 - 30fps VGA YUV */
556         {0x36, 0xfa},   /* aref3 */
557         {0x69, 0x0a},   /* hv */
558         {0x8c, 0x89},   /* com22 */
559         {0x14, 0x28},   /* com9 */
560         {0x3e, 0x0c},   /* com14 */
561         {0x41, 0x40},   /* com16 */
562         {0x72, 0x00},
563         {0x73, 0x00},
564         {0x74, 0x3a},
565         {0x75, 0x35},
566         {0x76, 0x01},
567         {0xc7, 0x80},   /* com24 */
568         {0x03, 0x12},   /* vref */
569         {0x17, 0x16},   /* hstart */
570         {0x18, 0x02},   /* hstop */
571         {0x19, 0x01},   /* vstrt */
572         {0x1a, 0x3d},   /* vstop */
573         {0x32, 0xff},   /* href */
574         {0xc0, 0xaa},
575 };
576
577 static const u8 ov965x_start_1_svga[][2] = {
578         {0x12, 0x02},   /* com7 - YUYV - VGA 15 full resolution */
579         {0x36, 0xf8},   /* aref3 */
580         {0x69, 0x02},   /* hv */
581         {0x8c, 0x0d},   /* com22 */
582         {0x3e, 0x0c},   /* com14 */
583         {0x41, 0x40},   /* com16 */
584         {0x72, 0x00},
585         {0x73, 0x01},
586         {0x74, 0x3a},
587         {0x75, 0x35},
588         {0x76, 0x01},
589         {0xc7, 0x80},   /* com24 */
590         {0x03, 0x1b},   /* vref */
591         {0x17, 0x1d},   /* hstart */
592         {0x18, 0xbd},   /* hstop */
593         {0x19, 0x01},   /* vstrt */
594         {0x1a, 0x81},   /* vstop */
595         {0x32, 0xff},   /* href */
596         {0xc0, 0xe2},
597 };
598
599 static const u8 ov965x_start_1_xga[][2] = {
600         {0x12, 0x02},   /* com7 */
601         {0x36, 0xf8},   /* aref3 */
602         {0x69, 0x02},   /* hv */
603         {0x8c, 0x89},   /* com22 */
604         {0x14, 0x28},   /* com9 */
605         {0x3e, 0x0c},   /* com14 */
606         {0x41, 0x40},   /* com16 */
607         {0x72, 0x00},
608         {0x73, 0x01},
609         {0x74, 0x3a},
610         {0x75, 0x35},
611         {0x76, 0x01},
612         {0xc7, 0x80},   /* com24 */
613         {0x03, 0x1b},   /* vref */
614         {0x17, 0x1d},   /* hstart */
615         {0x18, 0xbd},   /* hstop */
616         {0x19, 0x01},   /* vstrt */
617         {0x1a, 0x81},   /* vstop */
618         {0x32, 0xff},   /* href */
619         {0xc0, 0xe2},
620 };
621
622 static const u8 ov965x_start_1_sxga[][2] = {
623         {0x12, 0x02},   /* com7 */
624         {0x36, 0xf8},   /* aref3 */
625         {0x69, 0x02},   /* hv */
626         {0x8c, 0x89},   /* com22 */
627         {0x14, 0x28},   /* com9 */
628         {0x3e, 0x0c},   /* com14 */
629         {0x41, 0x40},   /* com16 */
630         {0x72, 0x00},
631         {0x73, 0x01},
632         {0x74, 0x3a},
633         {0x75, 0x35},
634         {0x76, 0x01},
635         {0xc7, 0x80},   /* com24 */
636         {0x03, 0x1b},   /* vref */
637         {0x17, 0x1d},   /* hstart */
638         {0x18, 0x02},   /* hstop */
639         {0x19, 0x01},   /* vstrt */
640         {0x1a, 0x81},   /* vstop */
641         {0x32, 0xff},   /* href */
642         {0xc0, 0xe2},
643 };
644
645 static const u8 bridge_start_qvga[][2] = {
646         {0x94, 0xaa},
647         {0xf1, 0x60},
648         {0xe5, 0x04},
649         {0xc0, 0x50},
650         {0xc1, 0x3c},
651         {0x8c, 0x00},
652         {0x8d, 0x1c},
653         {0x34, 0x05},
654
655         {0xc2, 0x4c},
656         {0xc3, 0xf9},
657         {0xda, 0x00},
658         {0x50, 0x00},
659         {0x51, 0xa0},
660         {0x52, 0x78},
661         {0x53, 0x00},
662         {0x54, 0x00},
663         {0x55, 0x00},
664         {0x57, 0x00},
665         {0x5c, 0x00},
666         {0x5a, 0x50},
667         {0x5b, 0x3c},
668         {0x35, 0x02},
669         {0xd9, 0x10},
670         {0x94, 0x11},
671 };
672
673 static const u8 bridge_start_vga[][2] = {
674         {0x94, 0xaa},
675         {0xf1, 0x60},
676         {0xe5, 0x04},
677         {0xc0, 0x50},
678         {0xc1, 0x3c},
679         {0x8c, 0x00},
680         {0x8d, 0x1c},
681         {0x34, 0x05},
682         {0xc2, 0x0c},
683         {0xc3, 0xf9},
684         {0xda, 0x01},
685         {0x50, 0x00},
686         {0x51, 0xa0},
687         {0x52, 0x3c},
688         {0x53, 0x00},
689         {0x54, 0x00},
690         {0x55, 0x00},
691         {0x57, 0x00},
692         {0x5c, 0x00},
693         {0x5a, 0xa0},
694         {0x5b, 0x78},
695         {0x35, 0x02},
696         {0xd9, 0x10},
697         {0x94, 0x11},
698 };
699
700 static const u8 bridge_start_svga[][2] = {
701         {0x94, 0xaa},
702         {0xf1, 0x60},
703         {0xe5, 0x04},
704         {0xc0, 0xa0},
705         {0xc1, 0x80},
706         {0x8c, 0x00},
707         {0x8d, 0x1c},
708         {0x34, 0x05},
709         {0xc2, 0x4c},
710         {0xc3, 0xf9},
711         {0x50, 0x00},
712         {0x51, 0x40},
713         {0x52, 0x00},
714         {0x53, 0x00},
715         {0x54, 0x00},
716         {0x55, 0x88},
717         {0x57, 0x00},
718         {0x5c, 0x00},
719         {0x5a, 0xc8},
720         {0x5b, 0x96},
721         {0x35, 0x02},
722         {0xd9, 0x10},
723         {0xda, 0x00},
724         {0x94, 0x11},
725 };
726
727 static const u8 bridge_start_xga[][2] = {
728         {0x94, 0xaa},
729         {0xf1, 0x60},
730         {0xe5, 0x04},
731         {0xc0, 0xa0},
732         {0xc1, 0x80},
733         {0x8c, 0x00},
734         {0x8d, 0x1c},
735         {0x34, 0x05},
736         {0xc2, 0x4c},
737         {0xc3, 0xf9},
738         {0x50, 0x00},
739         {0x51, 0x40},
740         {0x52, 0x00},
741         {0x53, 0x00},
742         {0x54, 0x00},
743         {0x55, 0x88},
744         {0x57, 0x00},
745         {0x5c, 0x01},
746         {0x5a, 0x00},
747         {0x5b, 0xc0},
748         {0x35, 0x02},
749         {0xd9, 0x10},
750         {0xda, 0x01},
751         {0x94, 0x11},
752 };
753
754 static const u8 bridge_start_sxga[][2] = {
755         {0x94, 0xaa},
756         {0xf1, 0x60},
757         {0xe5, 0x04},
758         {0xc0, 0xa0},
759         {0xc1, 0x80},
760         {0x8c, 0x00},
761         {0x8d, 0x1c},
762         {0x34, 0x05},
763         {0xc2, 0x0c},
764         {0xc3, 0xf9},
765         {0xda, 0x00},
766         {0x35, 0x02},
767         {0xd9, 0x10},
768         {0x94, 0x11},
769 };
770
771 static const u8 ov965x_start_2_qvga[][2] = {
772         {0x3b, 0xe4},   /* com11 - night mode 1/4 frame rate */
773         {0x1e, 0x04},   /* mvfp */
774         {0x13, 0xe0},   /* com8 */
775         {0x00, 0x00},
776         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
777         {0x11, 0x01},   /* clkrc */
778         {0x6b, 0x5a},   /* dblv */
779         {0x6a, 0x02},   /* 50 Hz banding filter */
780         {0xc5, 0x03},   /* 60 Hz banding filter */
781         {0xa2, 0x96},   /* bd50 */
782         {0xa3, 0x7d},   /* bd60 */
783
784         {0xff, 0x13},   /* read 13, write ff 00 */
785         {0x13, 0xe7},
786         {0x3a, 0x80},   /* tslb - yuyv */
787 };
788
789 static const u8 ov965x_start_2_vga[][2] = {
790         {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
791         {0x1e, 0x04},   /* mvfp */
792         {0x13, 0xe0},   /* com8 */
793         {0x00, 0x00},
794         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
795         {0x11, 0x03},   /* clkrc */
796         {0x6b, 0x5a},   /* dblv */
797         {0x6a, 0x05},   /* 50 Hz banding filter */
798         {0xc5, 0x07},   /* 60 Hz banding filter */
799         {0xa2, 0x4b},   /* bd50 */
800         {0xa3, 0x3e},   /* bd60 */
801
802         {0x2d, 0x00},   /* advfl */
803 };
804
805 static const u8 ov965x_start_2_svga[][2] = {    /* same for xga */
806         {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
807         {0x1e, 0x04},   /* mvfp */
808         {0x13, 0xe0},   /* com8 */
809         {0x00, 0x00},
810         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
811         {0x11, 0x01},   /* clkrc */
812         {0x6b, 0x5a},   /* dblv */
813         {0x6a, 0x0c},   /* 50 Hz banding filter */
814         {0xc5, 0x0f},   /* 60 Hz banding filter */
815         {0xa2, 0x4e},   /* bd50 */
816         {0xa3, 0x41},   /* bd60 */
817 };
818
819 static const u8 ov965x_start_2_sxga[][2] = {
820         {0x13, 0xe0},   /* com8 */
821         {0x00, 0x00},
822         {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
823         {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
824         {0x1e, 0x04},   /* mvfp */
825         {0x11, 0x01},   /* clkrc */
826         {0x6b, 0x5a},   /* dblv */
827         {0x6a, 0x0c},   /* 50 Hz banding filter */
828         {0xc5, 0x0f},   /* 60 Hz banding filter */
829         {0xa2, 0x4e},   /* bd50 */
830         {0xa3, 0x41},   /* bd60 */
831 };
832
833 static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
834 {
835         struct usb_device *udev = gspca_dev->dev;
836         int ret;
837
838         if (gspca_dev->usb_err < 0)
839                 return;
840         gspca_dev->usb_buf[0] = val;
841         ret = usb_control_msg(udev,
842                               usb_sndctrlpipe(udev, 0),
843                               0x01,
844                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
845                               0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
846         if (ret < 0) {
847                 pr_err("reg_w failed %d\n", ret);
848                 gspca_dev->usb_err = ret;
849         }
850 }
851
852 static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
853 {
854         PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
855         reg_w_i(gspca_dev, reg, val);
856 }
857
858 static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
859 {
860         struct usb_device *udev = gspca_dev->dev;
861         int ret;
862
863         if (gspca_dev->usb_err < 0)
864                 return 0;
865         ret = usb_control_msg(udev,
866                               usb_rcvctrlpipe(udev, 0),
867                               0x01,
868                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
869                               0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
870         PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
871         if (ret < 0) {
872                 pr_err("reg_r err %d\n", ret);
873                 gspca_dev->usb_err = ret;
874         }
875         return gspca_dev->usb_buf[0];
876 }
877
878 static int sccb_check_status(struct gspca_dev *gspca_dev)
879 {
880         u8 data;
881         int i;
882
883         for (i = 0; i < 5; i++) {
884                 data = reg_r(gspca_dev, OV534_REG_STATUS);
885
886                 switch (data) {
887                 case 0x00:
888                         return 1;
889                 case 0x04:
890                         return 0;
891                 case 0x03:
892                         break;
893                 default:
894                         PDEBUG(D_USBI|D_USBO,
895                                 "sccb status 0x%02x, attempt %d/5",
896                                 data, i + 1);
897                 }
898         }
899         return 0;
900 }
901
902 static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
903 {
904         PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
905         reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
906         reg_w_i(gspca_dev, OV534_REG_WRITE, val);
907         reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
908
909         if (!sccb_check_status(gspca_dev))
910                 pr_err("sccb_write failed\n");
911 }
912
913 static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
914 {
915         reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
916         reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
917         if (!sccb_check_status(gspca_dev))
918                 pr_err("sccb_read failed 1\n");
919
920         reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
921         if (!sccb_check_status(gspca_dev))
922                 pr_err("sccb_read failed 2\n");
923
924         return reg_r(gspca_dev, OV534_REG_READ);
925 }
926
927 /* output a bridge sequence (reg - val) */
928 static void reg_w_array(struct gspca_dev *gspca_dev,
929                         const u8 (*data)[2], int len)
930 {
931         while (--len >= 0) {
932                 reg_w(gspca_dev, (*data)[0], (*data)[1]);
933                 data++;
934         }
935 }
936
937 /* output a sensor sequence (reg - val) */
938 static void sccb_w_array(struct gspca_dev *gspca_dev,
939                         const u8 (*data)[2], int len)
940 {
941         while (--len >= 0) {
942                 if ((*data)[0] != 0xff) {
943                         sccb_write(gspca_dev, (*data)[0], (*data)[1]);
944                 } else {
945                         sccb_read(gspca_dev, (*data)[1]);
946                         sccb_write(gspca_dev, 0xff, 0x00);
947                 }
948                 data++;
949         }
950 }
951
952 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
953  * (direction and output)? */
954 static void set_led(struct gspca_dev *gspca_dev, int status)
955 {
956         u8 data;
957
958         PDEBUG(D_CONF, "led status: %d", status);
959
960         data = reg_r(gspca_dev, 0x21);
961         data |= 0x80;
962         reg_w(gspca_dev, 0x21, data);
963
964         data = reg_r(gspca_dev, 0x23);
965         if (status)
966                 data |= 0x80;
967         else
968                 data &= ~0x80;
969
970         reg_w(gspca_dev, 0x23, data);
971
972         if (!status) {
973                 data = reg_r(gspca_dev, 0x21);
974                 data &= ~0x80;
975                 reg_w(gspca_dev, 0x21, data);
976         }
977 }
978
979 static void setbrightness(struct gspca_dev *gspca_dev)
980 {
981         struct sd *sd = (struct sd *) gspca_dev;
982         u8 val;
983
984         if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS))
985                 return;
986         val = sd->ctrls[BRIGHTNESS].val;
987         if (val < 8)
988                 val = 15 - val;         /* f .. 8 */
989         else
990                 val = val - 8;          /* 0 .. 7 */
991         sccb_write(gspca_dev, 0x55,     /* brtn - brightness adjustment */
992                         0x0f | (val << 4));
993 }
994
995 static void setcontrast(struct gspca_dev *gspca_dev)
996 {
997         struct sd *sd = (struct sd *) gspca_dev;
998
999         if (gspca_dev->ctrl_dis & (1 << CONTRAST))
1000                 return;
1001         sccb_write(gspca_dev, 0x56,     /* cnst1 - contrast 1 ctrl coeff */
1002                         sd->ctrls[CONTRAST].val << 4);
1003 }
1004
1005 static void setautogain(struct gspca_dev *gspca_dev)
1006 {
1007         struct sd *sd = (struct sd *) gspca_dev;
1008         u8 val;
1009
1010         if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
1011                 return;
1012 /*fixme: should adjust agc/awb/aec by different controls */
1013         val = sccb_read(gspca_dev, 0x13);               /* com8 */
1014         sccb_write(gspca_dev, 0xff, 0x00);
1015         if (sd->ctrls[AUTOGAIN].val)
1016                 val |= 0x05;            /* agc & aec */
1017         else
1018                 val &= 0xfa;
1019         sccb_write(gspca_dev, 0x13, val);
1020 }
1021
1022 static void setexposure(struct gspca_dev *gspca_dev)
1023 {
1024         struct sd *sd = (struct sd *) gspca_dev;
1025         u8 val;
1026         static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1027
1028         if (gspca_dev->ctrl_dis & (1 << EXPOSURE))
1029                 return;
1030         sccb_write(gspca_dev, 0x10,                     /* aec[9:2] */
1031                         expo[sd->ctrls[EXPOSURE].val]);
1032
1033         val = sccb_read(gspca_dev, 0x13);               /* com8 */
1034         sccb_write(gspca_dev, 0xff, 0x00);
1035         sccb_write(gspca_dev, 0x13, val);
1036
1037         val = sccb_read(gspca_dev, 0xa1);               /* aech */
1038         sccb_write(gspca_dev, 0xff, 0x00);
1039         sccb_write(gspca_dev, 0xa1, val & 0xe0);        /* aec[15:10] = 0 */
1040 }
1041
1042 static void setsharpness(struct gspca_dev *gspca_dev)
1043 {
1044         struct sd *sd = (struct sd *) gspca_dev;
1045         s8 val;
1046
1047         if (gspca_dev->ctrl_dis & (1 << SHARPNESS))
1048                 return;
1049         val = sd->ctrls[SHARPNESS].val;
1050         if (val < 0) {                          /* auto */
1051                 val = sccb_read(gspca_dev, 0x42);       /* com17 */
1052                 sccb_write(gspca_dev, 0xff, 0x00);
1053                 sccb_write(gspca_dev, 0x42, val | 0x40);
1054                                 /* Edge enhancement strength auto adjust */
1055                 return;
1056         }
1057         if (val != 0)
1058                 val = 1 << (val - 1);
1059         sccb_write(gspca_dev, 0x3f,     /* edge - edge enhance. factor */
1060                         val);
1061         val = sccb_read(gspca_dev, 0x42);               /* com17 */
1062         sccb_write(gspca_dev, 0xff, 0x00);
1063         sccb_write(gspca_dev, 0x42, val & 0xbf);
1064 }
1065
1066 static void setsatur(struct gspca_dev *gspca_dev)
1067 {
1068         struct sd *sd = (struct sd *) gspca_dev;
1069         u8 val1, val2, val3;
1070         static const u8 matrix[5][2] = {
1071                 {0x14, 0x38},
1072                 {0x1e, 0x54},
1073                 {0x28, 0x70},
1074                 {0x32, 0x8c},
1075                 {0x48, 0x90}
1076         };
1077
1078         if (gspca_dev->ctrl_dis & (1 << SATUR))
1079                 return;
1080         val1 = matrix[sd->ctrls[SATUR].val][0];
1081         val2 = matrix[sd->ctrls[SATUR].val][1];
1082         val3 = val1 + val2;
1083         sccb_write(gspca_dev, 0x4f, val3);      /* matrix coeff */
1084         sccb_write(gspca_dev, 0x50, val3);
1085         sccb_write(gspca_dev, 0x51, 0x00);
1086         sccb_write(gspca_dev, 0x52, val1);
1087         sccb_write(gspca_dev, 0x53, val2);
1088         sccb_write(gspca_dev, 0x54, val3);
1089         sccb_write(gspca_dev, 0x58, 0x1a);      /* mtxs - coeff signs */
1090
1091         val1 = sccb_read(gspca_dev, 0x41);      /* com16 */
1092         sccb_write(gspca_dev, 0xff, 0x00);
1093         sccb_write(gspca_dev, 0x41, val1);
1094 }
1095
1096 static void setlightfreq(struct gspca_dev *gspca_dev)
1097 {
1098         struct sd *sd = (struct sd *) gspca_dev;
1099         u8 val;
1100
1101         if (gspca_dev->ctrl_dis & (1 << LIGHTFREQ))
1102                 return;
1103         val = sccb_read(gspca_dev, 0x13);               /* com8 */
1104         sccb_write(gspca_dev, 0xff, 0x00);
1105         if (sd->ctrls[LIGHTFREQ].val == 0) {
1106                 sccb_write(gspca_dev, 0x13, val & 0xdf);
1107                 return;
1108         }
1109         sccb_write(gspca_dev, 0x13, val | 0x20);
1110
1111         val = sccb_read(gspca_dev, 0x42);               /* com17 */
1112         sccb_write(gspca_dev, 0xff, 0x00);
1113         if (sd->ctrls[LIGHTFREQ].val == 1)
1114                 val |= 0x01;
1115         else
1116                 val &= 0xfe;
1117         sccb_write(gspca_dev, 0x42, val);
1118 }
1119
1120 /* this function is called at probe time */
1121 static int sd_config(struct gspca_dev *gspca_dev,
1122                      const struct usb_device_id *id)
1123 {
1124         struct sd *sd = (struct sd *) gspca_dev;
1125
1126         gspca_dev->cam.ctrls = sd->ctrls;
1127
1128 #if AUTOGAIN_DEF != 0
1129         gspca_dev->ctrl_inac |= (1 << EXPOSURE);
1130 #endif
1131         return 0;
1132 }
1133
1134 /* this function is called at probe and resume time */
1135 static int sd_init(struct gspca_dev *gspca_dev)
1136 {
1137         struct sd *sd = (struct sd *) gspca_dev;
1138         u16 sensor_id;
1139
1140         /* reset bridge */
1141         reg_w(gspca_dev, 0xe7, 0x3a);
1142         reg_w(gspca_dev, 0xe0, 0x08);
1143         msleep(100);
1144
1145         /* initialize the sensor address */
1146         reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
1147
1148         /* reset sensor */
1149         sccb_write(gspca_dev, 0x12, 0x80);
1150         msleep(10);
1151
1152         /* probe the sensor */
1153         sccb_read(gspca_dev, 0x0a);
1154         sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
1155         sccb_read(gspca_dev, 0x0b);
1156         sensor_id |= sccb_read(gspca_dev, 0x0b);
1157         PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1158
1159         /* initialize */
1160         if ((sensor_id & 0xfff0) == 0x9650) {
1161                 sd->sensor = SENSOR_OV965x;
1162
1163                 gspca_dev->cam.cam_mode = ov965x_mode;
1164                 gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode);
1165
1166                 reg_w_array(gspca_dev, bridge_init,
1167                                 ARRAY_SIZE(bridge_init));
1168                 sccb_w_array(gspca_dev, ov965x_init,
1169                                 ARRAY_SIZE(ov965x_init));
1170                 reg_w_array(gspca_dev, bridge_init_2,
1171                                 ARRAY_SIZE(bridge_init_2));
1172                 sccb_w_array(gspca_dev, ov965x_init_2,
1173                                 ARRAY_SIZE(ov965x_init_2));
1174                 reg_w(gspca_dev, 0xe0, 0x00);
1175                 reg_w(gspca_dev, 0xe0, 0x01);
1176                 set_led(gspca_dev, 0);
1177                 reg_w(gspca_dev, 0xe0, 0x00);
1178         } else if ((sensor_id & 0xfff0) == 0x9710) {
1179                 const char *p;
1180                 int l;
1181
1182                 sd->sensor = SENSOR_OV971x;
1183
1184                 gspca_dev->cam.cam_mode = ov971x_mode;
1185                 gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode);
1186
1187                 /* no control yet */
1188                 gspca_dev->ctrl_dis = (1 << NCTRLS) - 1;
1189
1190                 gspca_dev->cam.bulk = 1;
1191                 gspca_dev->cam.bulk_size = 16384;
1192                 gspca_dev->cam.bulk_nurbs = 2;
1193
1194                 sccb_w_array(gspca_dev, ov971x_init,
1195                                 ARRAY_SIZE(ov971x_init));
1196
1197                 /* set video format on bridge processor */
1198                 /* access bridge processor's video format registers at: 0x00 */
1199                 reg_w(gspca_dev, 0x1c, 0x00);
1200                 /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/
1201                 reg_w(gspca_dev, 0x1d, 0x00);
1202
1203                 /* Will W. specific stuff
1204                  * set VSYNC to
1205                  *      output (0x1f) if first webcam
1206                  *      input (0x17) if 2nd or 3rd webcam */
1207                 p = video_device_node_name(&gspca_dev->vdev);
1208                 l = strlen(p) - 1;
1209                 if (p[l] == '0')
1210                         reg_w(gspca_dev, 0x56, 0x1f);
1211                 else
1212                         reg_w(gspca_dev, 0x56, 0x17);
1213         } else {
1214                 err("Unknown sensor %04x", sensor_id);
1215                 return -EINVAL;
1216         }
1217
1218         return gspca_dev->usb_err;
1219 }
1220
1221 static int sd_start(struct gspca_dev *gspca_dev)
1222 {
1223         struct sd *sd = (struct sd *) gspca_dev;
1224
1225         if (sd->sensor == SENSOR_OV971x)
1226                 return gspca_dev->usb_err;
1227         switch (gspca_dev->curr_mode) {
1228         case QVGA_MODE:                 /* 320x240 */
1229                 sccb_w_array(gspca_dev, ov965x_start_1_vga,
1230                                 ARRAY_SIZE(ov965x_start_1_vga));
1231                 reg_w_array(gspca_dev, bridge_start_qvga,
1232                                 ARRAY_SIZE(bridge_start_qvga));
1233                 sccb_w_array(gspca_dev, ov965x_start_2_qvga,
1234                                 ARRAY_SIZE(ov965x_start_2_qvga));
1235                 break;
1236         case VGA_MODE:                  /* 640x480 */
1237                 sccb_w_array(gspca_dev, ov965x_start_1_vga,
1238                                 ARRAY_SIZE(ov965x_start_1_vga));
1239                 reg_w_array(gspca_dev, bridge_start_vga,
1240                                 ARRAY_SIZE(bridge_start_vga));
1241                 sccb_w_array(gspca_dev, ov965x_start_2_vga,
1242                                 ARRAY_SIZE(ov965x_start_2_vga));
1243                 break;
1244         case SVGA_MODE:                 /* 800x600 */
1245                 sccb_w_array(gspca_dev, ov965x_start_1_svga,
1246                                 ARRAY_SIZE(ov965x_start_1_svga));
1247                 reg_w_array(gspca_dev, bridge_start_svga,
1248                                 ARRAY_SIZE(bridge_start_svga));
1249                 sccb_w_array(gspca_dev, ov965x_start_2_svga,
1250                                 ARRAY_SIZE(ov965x_start_2_svga));
1251                 break;
1252         case XGA_MODE:                  /* 1024x768 */
1253                 sccb_w_array(gspca_dev, ov965x_start_1_xga,
1254                                 ARRAY_SIZE(ov965x_start_1_xga));
1255                 reg_w_array(gspca_dev, bridge_start_xga,
1256                                 ARRAY_SIZE(bridge_start_xga));
1257                 sccb_w_array(gspca_dev, ov965x_start_2_svga,
1258                                 ARRAY_SIZE(ov965x_start_2_svga));
1259                 break;
1260         default:
1261 /*      case SXGA_MODE:                  * 1280x1024 */
1262                 sccb_w_array(gspca_dev, ov965x_start_1_sxga,
1263                                 ARRAY_SIZE(ov965x_start_1_sxga));
1264                 reg_w_array(gspca_dev, bridge_start_sxga,
1265                                 ARRAY_SIZE(bridge_start_sxga));
1266                 sccb_w_array(gspca_dev, ov965x_start_2_sxga,
1267                                 ARRAY_SIZE(ov965x_start_2_sxga));
1268                 break;
1269         }
1270         setlightfreq(gspca_dev);
1271         setautogain(gspca_dev);
1272         setbrightness(gspca_dev);
1273         setcontrast(gspca_dev);
1274         setexposure(gspca_dev);
1275         setsharpness(gspca_dev);
1276         setsatur(gspca_dev);
1277
1278         reg_w(gspca_dev, 0xe0, 0x00);
1279         reg_w(gspca_dev, 0xe0, 0x00);
1280         set_led(gspca_dev, 1);
1281         return gspca_dev->usb_err;
1282 }
1283
1284 static void sd_stopN(struct gspca_dev *gspca_dev)
1285 {
1286         reg_w(gspca_dev, 0xe0, 0x01);
1287         set_led(gspca_dev, 0);
1288         reg_w(gspca_dev, 0xe0, 0x00);
1289 }
1290
1291 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1292 #define UVC_STREAM_EOH  (1 << 7)
1293 #define UVC_STREAM_ERR  (1 << 6)
1294 #define UVC_STREAM_STI  (1 << 5)
1295 #define UVC_STREAM_RES  (1 << 4)
1296 #define UVC_STREAM_SCR  (1 << 3)
1297 #define UVC_STREAM_PTS  (1 << 2)
1298 #define UVC_STREAM_EOF  (1 << 1)
1299 #define UVC_STREAM_FID  (1 << 0)
1300
1301 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1302                         u8 *data, int len)
1303 {
1304         struct sd *sd = (struct sd *) gspca_dev;
1305         __u32 this_pts;
1306         u8 this_fid;
1307         int remaining_len = len;
1308         int payload_len;
1309
1310         payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1311         do {
1312                 len = min(remaining_len, payload_len);
1313
1314                 /* Payloads are prefixed with a UVC-style header.  We
1315                    consider a frame to start when the FID toggles, or the PTS
1316                    changes.  A frame ends when EOF is set, and we've received
1317                    the correct number of bytes. */
1318
1319                 /* Verify UVC header.  Header length is always 12 */
1320                 if (data[0] != 12 || len < 12) {
1321                         PDEBUG(D_PACK, "bad header");
1322                         goto discard;
1323                 }
1324
1325                 /* Check errors */
1326                 if (data[1] & UVC_STREAM_ERR) {
1327                         PDEBUG(D_PACK, "payload error");
1328                         goto discard;
1329                 }
1330
1331                 /* Extract PTS and FID */
1332                 if (!(data[1] & UVC_STREAM_PTS)) {
1333                         PDEBUG(D_PACK, "PTS not present");
1334                         goto discard;
1335                 }
1336                 this_pts = (data[5] << 24) | (data[4] << 16)
1337                                                 | (data[3] << 8) | data[2];
1338                 this_fid = data[1] & UVC_STREAM_FID;
1339
1340                 /* If PTS or FID has changed, start a new frame. */
1341                 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1342                         if (gspca_dev->last_packet_type == INTER_PACKET)
1343                                 gspca_frame_add(gspca_dev, LAST_PACKET,
1344                                                 NULL, 0);
1345                         sd->last_pts = this_pts;
1346                         sd->last_fid = this_fid;
1347                         gspca_frame_add(gspca_dev, FIRST_PACKET,
1348                                         data + 12, len - 12);
1349                 /* If this packet is marked as EOF, end the frame */
1350                 } else if (data[1] & UVC_STREAM_EOF) {
1351                         sd->last_pts = 0;
1352                         gspca_frame_add(gspca_dev, LAST_PACKET,
1353                                         data + 12, len - 12);
1354                 } else {
1355
1356                         /* Add the data from this payload */
1357                         gspca_frame_add(gspca_dev, INTER_PACKET,
1358                                         data + 12, len - 12);
1359                 }
1360
1361                 /* Done this payload */
1362                 goto scan_next;
1363
1364 discard:
1365                 /* Discard data until a new frame starts. */
1366                 gspca_dev->last_packet_type = DISCARD_PACKET;
1367
1368 scan_next:
1369                 remaining_len -= len;
1370                 data += len;
1371         } while (remaining_len > 0);
1372 }
1373
1374 static int sd_querymenu(struct gspca_dev *gspca_dev,
1375                         struct v4l2_querymenu *menu)
1376 {
1377         switch (menu->id) {
1378         case V4L2_CID_POWER_LINE_FREQUENCY:
1379                 switch (menu->index) {
1380                 case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1381                         strcpy((char *) menu->name, "NoFliker");
1382                         return 0;
1383                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1384                         strcpy((char *) menu->name, "50 Hz");
1385                         return 0;
1386                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1387                         strcpy((char *) menu->name, "60 Hz");
1388                         return 0;
1389                 }
1390                 break;
1391         }
1392         return -EINVAL;
1393 }
1394
1395 /* sub-driver description */
1396 static const struct sd_desc sd_desc = {
1397         .name     = MODULE_NAME,
1398         .ctrls    = sd_ctrls,
1399         .nctrls   = NCTRLS,
1400         .config   = sd_config,
1401         .init     = sd_init,
1402         .start    = sd_start,
1403         .stopN    = sd_stopN,
1404         .pkt_scan = sd_pkt_scan,
1405         .querymenu = sd_querymenu,
1406 };
1407
1408 /* -- module initialisation -- */
1409 static const struct usb_device_id device_table[] = {
1410         {USB_DEVICE(0x05a9, 0x8065)},
1411         {USB_DEVICE(0x06f8, 0x3003)},
1412         {}
1413 };
1414
1415 MODULE_DEVICE_TABLE(usb, device_table);
1416
1417 /* -- device connect -- */
1418 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1419 {
1420         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1421                                 THIS_MODULE);
1422 }
1423
1424 static struct usb_driver sd_driver = {
1425         .name       = MODULE_NAME,
1426         .id_table   = device_table,
1427         .probe      = sd_probe,
1428         .disconnect = gspca_disconnect,
1429 #ifdef CONFIG_PM
1430         .suspend    = gspca_suspend,
1431         .resume     = gspca_resume,
1432 #endif
1433 };
1434
1435 /* -- module insert / remove -- */
1436 static int __init sd_mod_init(void)
1437 {
1438         return usb_register(&sd_driver);
1439 }
1440
1441 static void __exit sd_mod_exit(void)
1442 {
1443         usb_deregister(&sd_driver);
1444 }
1445
1446 module_init(sd_mod_init);
1447 module_exit(sd_mod_exit);