Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[pandora-kernel.git] / drivers / media / video / gspca / t613.c
1 /*
2  * T613 subdriver
3  *
4  * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *Notes: * t613  + tas5130A
21  *      * Focus to light do not balance well as in win.
22  *        Quality in win is not good, but its kinda better.
23  *       * Fix some "extraneous bytes", most of apps will show the image anyway
24  *       * Gamma table, is there, but its really doing something?
25  *       * 7~8 Fps, its ok, max on win its 10.
26  *                      Costantino Leandro
27  */
28
29 #define MODULE_NAME "t613"
30
31 #include <linux/slab.h>
32 #include "gspca.h"
33
34 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
35
36 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
37 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
38 MODULE_LICENSE("GPL");
39
40 struct sd {
41         struct gspca_dev gspca_dev;     /* !! must be the first item */
42
43         u8 brightness;
44         u8 contrast;
45         u8 colors;
46         u8 autogain;
47         u8 gamma;
48         u8 sharpness;
49         u8 freq;
50         u8 red_gain;
51         u8 blue_gain;
52         u8 green_gain;
53         u8 awb; /* set default r/g/b and activate */
54         u8 mirror;
55         u8 effect;
56
57         u8 sensor;
58 };
59 enum sensors {
60         SENSOR_OM6802,
61         SENSOR_OTHER,
62         SENSOR_TAS5130A,
63         SENSOR_LT168G,          /* must verify if this is the actual model */
64 };
65
66 /* V4L2 controls supported by the driver */
67 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
81
82 static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
90
91 static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
92 static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
93 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
94 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
95 static int sd_querymenu(struct gspca_dev *gspca_dev,
96                         struct v4l2_querymenu *menu);
97
98 static const struct ctrl sd_ctrls[] = {
99         {
100          {
101           .id = V4L2_CID_BRIGHTNESS,
102           .type = V4L2_CTRL_TYPE_INTEGER,
103           .name = "Brightness",
104           .minimum = 0,
105           .maximum = 14,
106           .step = 1,
107 #define BRIGHTNESS_DEF 8
108           .default_value = BRIGHTNESS_DEF,
109           },
110          .set = sd_setbrightness,
111          .get = sd_getbrightness,
112          },
113         {
114          {
115           .id = V4L2_CID_CONTRAST,
116           .type = V4L2_CTRL_TYPE_INTEGER,
117           .name = "Contrast",
118           .minimum = 0,
119           .maximum = 0x0d,
120           .step = 1,
121 #define CONTRAST_DEF 0x07
122           .default_value = CONTRAST_DEF,
123           },
124          .set = sd_setcontrast,
125          .get = sd_getcontrast,
126          },
127         {
128          {
129           .id = V4L2_CID_SATURATION,
130           .type = V4L2_CTRL_TYPE_INTEGER,
131           .name = "Color",
132           .minimum = 0,
133           .maximum = 0x0f,
134           .step = 1,
135 #define COLORS_DEF 0x05
136           .default_value = COLORS_DEF,
137           },
138          .set = sd_setcolors,
139          .get = sd_getcolors,
140          },
141 #define GAMMA_MAX 16
142 #define GAMMA_DEF 10
143         {
144          {
145           .id = V4L2_CID_GAMMA, /* (gamma on win) */
146           .type = V4L2_CTRL_TYPE_INTEGER,
147           .name = "Gamma",
148           .minimum = 0,
149           .maximum = GAMMA_MAX - 1,
150           .step = 1,
151           .default_value = GAMMA_DEF,
152           },
153          .set = sd_setgamma,
154          .get = sd_getgamma,
155          },
156         {
157          {
158           .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight,
159                                  * some apps dont bring up the
160                                  * backligth_compensation control) */
161           .type = V4L2_CTRL_TYPE_INTEGER,
162           .name = "Low Light",
163           .minimum = 0,
164           .maximum = 1,
165           .step = 1,
166 #define AUTOGAIN_DEF 0x01
167           .default_value = AUTOGAIN_DEF,
168           },
169          .set = sd_setlowlight,
170          .get = sd_getlowlight,
171          },
172         {
173          {
174           .id = V4L2_CID_HFLIP,
175           .type = V4L2_CTRL_TYPE_BOOLEAN,
176           .name = "Mirror Image",
177           .minimum = 0,
178           .maximum = 1,
179           .step = 1,
180 #define MIRROR_DEF 0
181           .default_value = MIRROR_DEF,
182           },
183          .set = sd_setmirror,
184          .get = sd_getmirror
185         },
186         {
187          {
188           .id = V4L2_CID_POWER_LINE_FREQUENCY,
189           .type = V4L2_CTRL_TYPE_MENU,
190           .name = "Light Frequency Filter",
191           .minimum = 1,         /* 1 -> 0x50, 2->0x60 */
192           .maximum = 2,
193           .step = 1,
194 #define FREQ_DEF 1
195           .default_value = FREQ_DEF,
196           },
197          .set = sd_setfreq,
198          .get = sd_getfreq},
199
200         {
201          {
202           .id =  V4L2_CID_AUTO_WHITE_BALANCE,
203           .type = V4L2_CTRL_TYPE_INTEGER,
204           .name = "Auto White Balance",
205           .minimum = 0,
206           .maximum = 1,
207           .step = 1,
208 #define AWB_DEF 0
209           .default_value = AWB_DEF,
210           },
211          .set = sd_setawb,
212          .get = sd_getawb
213         },
214         {
215          {
216           .id = V4L2_CID_SHARPNESS,
217           .type = V4L2_CTRL_TYPE_INTEGER,
218           .name = "Sharpness",
219           .minimum = 0,
220           .maximum = 15,
221           .step = 1,
222 #define SHARPNESS_DEF 0x06
223           .default_value = SHARPNESS_DEF,
224           },
225          .set = sd_setsharpness,
226          .get = sd_getsharpness,
227          },
228         {
229          {
230           .id = V4L2_CID_EFFECTS,
231           .type = V4L2_CTRL_TYPE_MENU,
232           .name = "Webcam Effects",
233           .minimum = 0,
234           .maximum = 4,
235           .step = 1,
236 #define EFFECTS_DEF 0
237           .default_value = EFFECTS_DEF,
238           },
239          .set = sd_seteffect,
240          .get = sd_geteffect
241         },
242         {
243          {
244             .id      = V4L2_CID_BLUE_BALANCE,
245             .type    = V4L2_CTRL_TYPE_INTEGER,
246             .name    = "Blue Balance",
247             .minimum = 0x10,
248             .maximum = 0x40,
249             .step    = 1,
250 #define BLUE_GAIN_DEF 0x20
251             .default_value = BLUE_GAIN_DEF,
252          },
253         .set = sd_setblue_gain,
254         .get = sd_getblue_gain,
255         },
256         {
257          {
258             .id      = V4L2_CID_RED_BALANCE,
259             .type    = V4L2_CTRL_TYPE_INTEGER,
260             .name    = "Red Balance",
261             .minimum = 0x10,
262             .maximum = 0x40,
263             .step    = 1,
264 #define RED_GAIN_DEF 0x20
265             .default_value = RED_GAIN_DEF,
266          },
267         .set = sd_setred_gain,
268         .get = sd_getred_gain,
269         },
270         {
271          {
272             .id      = V4L2_CID_GAIN,
273             .type    = V4L2_CTRL_TYPE_INTEGER,
274             .name    = "Gain",
275             .minimum = 0x10,
276             .maximum = 0x40,
277             .step    = 1,
278 #define GAIN_DEF  0x20
279             .default_value = GAIN_DEF,
280          },
281         .set = sd_setgain,
282         .get = sd_getgain,
283         },
284 };
285
286 static const struct v4l2_pix_format vga_mode_t16[] = {
287         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
288                 .bytesperline = 160,
289                 .sizeimage = 160 * 120 * 4 / 8 + 590,
290                 .colorspace = V4L2_COLORSPACE_JPEG,
291                 .priv = 4},
292         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
293                 .bytesperline = 176,
294                 .sizeimage = 176 * 144 * 3 / 8 + 590,
295                 .colorspace = V4L2_COLORSPACE_JPEG,
296                 .priv = 3},
297         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
298                 .bytesperline = 320,
299                 .sizeimage = 320 * 240 * 3 / 8 + 590,
300                 .colorspace = V4L2_COLORSPACE_JPEG,
301                 .priv = 2},
302         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
303                 .bytesperline = 352,
304                 .sizeimage = 352 * 288 * 3 / 8 + 590,
305                 .colorspace = V4L2_COLORSPACE_JPEG,
306                 .priv = 1},
307         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
308                 .bytesperline = 640,
309                 .sizeimage = 640 * 480 * 3 / 8 + 590,
310                 .colorspace = V4L2_COLORSPACE_JPEG,
311                 .priv = 0},
312 };
313
314 /* sensor specific data */
315 struct additional_sensor_data {
316         const u8 n3[6];
317         const u8 *n4, n4sz;
318         const u8 reg80, reg8e;
319         const u8 nset8[6];
320         const u8 data1[10];
321         const u8 data2[9];
322         const u8 data3[9];
323         const u8 data5[6];
324         const u8 stream[4];
325 };
326
327 static const u8 n4_om6802[] = {
328         0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
329         0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
330         0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
331         0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
332         0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
333         0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
334         0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
335         0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
336         0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
337 };
338 static const u8 n4_other[] = {
339         0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
340         0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
341         0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
342         0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
343         0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
344         0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
345         0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
346         0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
347 };
348 static const u8 n4_tas5130a[] = {
349         0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
350         0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
351         0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
352         0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
353         0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
354         0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
355         0xc6, 0xda
356 };
357 static const u8 n4_lt168g[] = {
358         0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
359         0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
360         0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
361         0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
362         0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
363         0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
364         0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
365         0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
366         0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
367 };
368
369 static const struct additional_sensor_data sensor_data[] = {
370 [SENSOR_OM6802] = {
371         .n3 =
372                 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
373         .n4 = n4_om6802,
374         .n4sz = sizeof n4_om6802,
375         .reg80 = 0x3c,
376         .reg8e = 0x33,
377         .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
378         .data1 =
379                 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
380                  0xb3, 0xfc},
381         .data2 =
382                 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
383                  0xff},
384         .data3 =
385                 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
386                  0xff},
387         .data5 =        /* this could be removed later */
388                 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
389         .stream =
390                 {0x0b, 0x04, 0x0a, 0x78},
391     },
392 [SENSOR_OTHER] = {
393         .n3 =
394                 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
395         .n4 = n4_other,
396         .n4sz = sizeof n4_other,
397         .reg80 = 0xac,
398         .reg8e = 0xb8,
399         .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
400         .data1 =
401                 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
402                  0xe8, 0xfc},
403         .data2 =
404                 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
405                  0xd9},
406         .data3 =
407                 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
408                  0xd9},
409         .data5 =
410                 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
411         .stream =
412                 {0x0b, 0x04, 0x0a, 0x00},
413     },
414 [SENSOR_TAS5130A] = {
415         .n3 =
416                 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
417         .n4 = n4_tas5130a,
418         .n4sz = sizeof n4_tas5130a,
419         .reg80 = 0x3c,
420         .reg8e = 0xb4,
421         .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
422         .data1 =
423                 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
424                  0xc8, 0xfc},
425         .data2 =
426                 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
427                  0xe0},
428         .data3 =
429                 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
430                  0xe0},
431         .data5 =
432                 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
433         .stream =
434                 {0x0b, 0x04, 0x0a, 0x40},
435     },
436 [SENSOR_LT168G] = {
437         .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
438         .n4 = n4_lt168g,
439         .n4sz = sizeof n4_lt168g,
440         .reg80 = 0x7c,
441         .reg8e = 0xb3,
442         .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
443         .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
444                  0xb0, 0xf4},
445         .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
446                  0xff},
447         .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
448                  0xff},
449         .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
450         .stream = {0x0b, 0x04, 0x0a, 0x28},
451     },
452 };
453
454 #define MAX_EFFECTS 7
455 /* easily done by soft, this table could be removed,
456  * i keep it here just in case */
457 static char *effects_control[MAX_EFFECTS] = {
458         "Normal",
459         "Emboss",               /* disabled */
460         "Monochrome",
461         "Sepia",
462         "Sketch",
463         "Sun Effect",           /* disabled */
464         "Negative",
465 };
466 static const u8 effects_table[MAX_EFFECTS][6] = {
467         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},   /* Normal */
468         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},   /* Repujar */
469         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},   /* Monochrome */
470         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},   /* Sepia */
471         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},   /* Croquis */
472         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},   /* Sun Effect */
473         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},   /* Negative */
474 };
475
476 static const u8 gamma_table[GAMMA_MAX][17] = {
477 /* gamma table from cam1690.ini */
478         {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21,        /* 0 */
479          0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
480          0xff},
481         {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d,        /* 1 */
482          0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
483          0xff},
484         {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35,        /* 2 */
485          0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
486          0xff},
487         {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f,        /* 3 */
488          0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
489          0xff},
490         {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a,        /* 4 */
491          0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
492          0xff},
493         {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58,        /* 5 */
494          0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
495          0xff},
496         {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67,        /* 6 */
497          0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
498          0xff},
499         {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,        /* 7 */
500          0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
501          0xff},
502         {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79,        /* 8 */
503          0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
504          0xff},
505         {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84,        /* 9 */
506          0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
507          0xff},
508         {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e,        /* 10 */
509          0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
510          0xff},
511         {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b,        /* 11 */
512          0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
513          0xff},
514         {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,        /* 12 */
515          0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
516          0xff},
517         {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,        /* 13 */
518          0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
519          0xff},
520         {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,        /* 14 */
521          0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
522          0xff},
523         {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,        /* 15 */
524          0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
525          0xff}
526 };
527
528 static const u8 tas5130a_sensor_init[][8] = {
529         {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
530         {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
531         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
532 };
533
534 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
535
536 /* read 1 byte */
537 static u8 reg_r(struct gspca_dev *gspca_dev,
538                    u16 index)
539 {
540         usb_control_msg(gspca_dev->dev,
541                         usb_rcvctrlpipe(gspca_dev->dev, 0),
542                         0,              /* request */
543                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
544                         0,              /* value */
545                         index,
546                         gspca_dev->usb_buf, 1, 500);
547         return gspca_dev->usb_buf[0];
548 }
549
550 static void reg_w(struct gspca_dev *gspca_dev,
551                   u16 index)
552 {
553         usb_control_msg(gspca_dev->dev,
554                         usb_sndctrlpipe(gspca_dev->dev, 0),
555                         0,
556                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
557                         0, index,
558                         NULL, 0, 500);
559 }
560
561 static void reg_w_buf(struct gspca_dev *gspca_dev,
562                   const u8 *buffer, u16 len)
563 {
564         if (len <= USB_BUF_SZ) {
565                 memcpy(gspca_dev->usb_buf, buffer, len);
566                 usb_control_msg(gspca_dev->dev,
567                                 usb_sndctrlpipe(gspca_dev->dev, 0),
568                                 0,
569                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
570                                 0x01, 0,
571                                 gspca_dev->usb_buf, len, 500);
572         } else {
573                 u8 *tmpbuf;
574
575                 tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
576                 if (!tmpbuf) {
577                         err("Out of memory");
578                         return;
579                 }
580                 usb_control_msg(gspca_dev->dev,
581                                 usb_sndctrlpipe(gspca_dev->dev, 0),
582                                 0,
583                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
584                                 0x01, 0,
585                                 tmpbuf, len, 500);
586                 kfree(tmpbuf);
587         }
588 }
589
590 /* write values to consecutive registers */
591 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
592                         u8 reg,
593                         const u8 *buffer, u16 len)
594 {
595         int i;
596         u8 *p, *tmpbuf;
597
598         if (len * 2 <= USB_BUF_SZ) {
599                 p = tmpbuf = gspca_dev->usb_buf;
600         } else {
601                 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
602                 if (!tmpbuf) {
603                         err("Out of memory");
604                         return;
605                 }
606         }
607         i = len;
608         while (--i >= 0) {
609                 *p++ = reg++;
610                 *p++ = *buffer++;
611         }
612         usb_control_msg(gspca_dev->dev,
613                         usb_sndctrlpipe(gspca_dev->dev, 0),
614                         0,
615                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
616                         0x01, 0,
617                         tmpbuf, len * 2, 500);
618         if (len * 2 > USB_BUF_SZ)
619                 kfree(tmpbuf);
620 }
621
622 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
623 {
624         int i;
625         const u8 *p;
626         u8 byte;
627         u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
628         static const u8 sensor_init[] = {
629                 0xdf, 0x6d,
630                 0xdd, 0x18,
631                 0x5a, 0xe0,
632                 0x5c, 0x07,
633                 0x5d, 0xb0,
634                 0x5e, 0x1e,
635                 0x60, 0x71,
636                 0xef, 0x00,
637                 0xe9, 0x00,
638                 0xea, 0x00,
639                 0x90, 0x24,
640                 0x91, 0xb2,
641                 0x82, 0x32,
642                 0xfd, 0x41,
643                 0x00                    /* table end */
644         };
645
646         reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
647         msleep(100);
648         i = 4;
649         while (--i > 0) {
650                 byte = reg_r(gspca_dev, 0x0060);
651                 if (!(byte & 0x01))
652                         break;
653                 msleep(100);
654         }
655         byte = reg_r(gspca_dev, 0x0063);
656         if (byte != 0x17) {
657                 err("Bad sensor reset %02x", byte);
658                 /* continue? */
659         }
660
661         p = sensor_init;
662         while (*p != 0) {
663                 val[1] = *p++;
664                 val[3] = *p++;
665                 if (*p == 0)
666                         reg_w(gspca_dev, 0x3c80);
667                 reg_w_buf(gspca_dev, val, sizeof val);
668                 i = 4;
669                 while (--i >= 0) {
670                         msleep(15);
671                         byte = reg_r(gspca_dev, 0x60);
672                         if (!(byte & 0x01))
673                                 break;
674                 }
675         }
676         msleep(15);
677         reg_w(gspca_dev, 0x3c80);
678 }
679
680 /* this function is called at probe time */
681 static int sd_config(struct gspca_dev *gspca_dev,
682                      const struct usb_device_id *id)
683 {
684         struct sd *sd = (struct sd *) gspca_dev;
685         struct cam *cam;
686
687         cam = &gspca_dev->cam;
688
689         cam->cam_mode = vga_mode_t16;
690         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
691
692         sd->brightness = BRIGHTNESS_DEF;
693         sd->contrast = CONTRAST_DEF;
694         sd->colors = COLORS_DEF;
695         sd->gamma = GAMMA_DEF;
696         sd->autogain = AUTOGAIN_DEF;
697         sd->mirror = MIRROR_DEF;
698         sd->freq = FREQ_DEF;
699         sd->awb = AWB_DEF;
700         sd->sharpness = SHARPNESS_DEF;
701         sd->effect = EFFECTS_DEF;
702         sd->red_gain = RED_GAIN_DEF;
703         sd->blue_gain = BLUE_GAIN_DEF;
704         sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF;
705
706         return 0;
707 }
708
709 static void setbrightness(struct gspca_dev *gspca_dev)
710 {
711         struct sd *sd = (struct sd *) gspca_dev;
712         unsigned int brightness;
713         u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
714
715         brightness = sd->brightness;
716         if (brightness < 7) {
717                 set6[1] = 0x26;
718                 set6[3] = 0x70 - brightness * 0x10;
719         } else {
720                 set6[3] = 0x00 + ((brightness - 7) * 0x10);
721         }
722
723         reg_w_buf(gspca_dev, set6, sizeof set6);
724 }
725
726 static void setcontrast(struct gspca_dev *gspca_dev)
727 {
728         struct sd *sd = (struct sd *) gspca_dev;
729         unsigned int contrast = sd->contrast;
730         u16 reg_to_write;
731
732         if (contrast < 7)
733                 reg_to_write = 0x8ea9 - contrast * 0x200;
734         else
735                 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
736
737         reg_w(gspca_dev, reg_to_write);
738 }
739
740 static void setcolors(struct gspca_dev *gspca_dev)
741 {
742         struct sd *sd = (struct sd *) gspca_dev;
743         u16 reg_to_write;
744
745         reg_to_write = 0x80bb + sd->colors * 0x100;     /* was 0xc0 */
746         reg_w(gspca_dev, reg_to_write);
747 }
748
749 static void setgamma(struct gspca_dev *gspca_dev)
750 {
751         struct sd *sd = (struct sd *) gspca_dev;
752
753         PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
754         reg_w_ixbuf(gspca_dev, 0x90,
755                 gamma_table[sd->gamma], sizeof gamma_table[0]);
756 }
757
758 static void setRGB(struct gspca_dev *gspca_dev)
759 {
760         struct sd *sd = (struct sd *) gspca_dev;
761         u8 all_gain_reg[6] =
762                 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00};
763
764         all_gain_reg[1] = sd->red_gain;
765         all_gain_reg[3] = sd->blue_gain;
766         all_gain_reg[5] = sd->green_gain;
767         reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
768 }
769
770 /* Generic fnc for r/b balance, exposure and awb */
771 static void setawb(struct gspca_dev *gspca_dev)
772 {
773         struct sd *sd = (struct sd *) gspca_dev;
774         u16 reg80;
775
776         reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80;
777
778         /* on awb leave defaults values */
779         if (!sd->awb) {
780                 /* shoud we wait here.. */
781                 /* update and reset RGB gains with webcam values */
782                 sd->red_gain = reg_r(gspca_dev, 0x0087);
783                 sd->blue_gain = reg_r(gspca_dev, 0x0088);
784                 sd->green_gain = reg_r(gspca_dev, 0x0089);
785                 reg80 &= ~0x0400;               /* AWB off */
786         }
787         reg_w(gspca_dev, reg80);
788         reg_w(gspca_dev, reg80);
789 }
790
791 static void init_gains(struct gspca_dev *gspca_dev)
792 {
793         struct sd *sd = (struct sd *) gspca_dev;
794         u16 reg80;
795         u8 all_gain_reg[8] =
796                 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00};
797
798         all_gain_reg[1] = sd->red_gain;
799         all_gain_reg[3] = sd->blue_gain;
800         all_gain_reg[5] = sd->green_gain;
801         reg80 = sensor_data[sd->sensor].reg80;
802         if (!sd->awb)
803                 reg80 &= ~0x04;
804         all_gain_reg[7] = reg80;
805         reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
806
807         reg_w(gspca_dev, (sd->red_gain  << 8) + 0x87);
808         reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88);
809         reg_w(gspca_dev, (sd->green_gain  << 8) + 0x89);
810 }
811
812 static void setsharpness(struct gspca_dev *gspca_dev)
813 {
814         struct sd *sd = (struct sd *) gspca_dev;
815         u16 reg_to_write;
816
817         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
818
819         reg_w(gspca_dev, reg_to_write);
820 }
821
822 static void setfreq(struct gspca_dev *gspca_dev)
823 {
824         struct sd *sd = (struct sd *) gspca_dev;
825         u8 reg66;
826         u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
827
828         switch (sd->sensor) {
829         case SENSOR_LT168G:
830                 if (sd->freq != 0)
831                         freq[3] = 0xa8;
832                 reg66 = 0x41;
833                 break;
834         case SENSOR_OM6802:
835                 reg66 = 0xca;
836                 break;
837         default:
838                 reg66 = 0x40;
839                 break;
840         }
841         switch (sd->freq) {
842         case 0:                         /* no flicker */
843                 freq[3] = 0xf0;
844                 break;
845         case 2:                         /* 60Hz */
846                 reg66 &= ~0x40;
847                 break;
848         }
849         freq[1] = reg66;
850
851         reg_w_buf(gspca_dev, freq, sizeof freq);
852 }
853
854 /* this function is called at probe and resume time */
855 static int sd_init(struct gspca_dev *gspca_dev)
856 {
857         /* some of this registers are not really neded, because
858          * they are overriden by setbrigthness, setcontrast, etc,
859          * but wont hurt anyway, and can help someone with similar webcam
860          * to see the initial parameters.*/
861         struct sd *sd = (struct sd *) gspca_dev;
862         const struct additional_sensor_data *sensor;
863         int i;
864         u16 sensor_id;
865         u8 test_byte = 0;
866
867         static const u8 read_indexs[] =
868                 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
869                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
870         static const u8 n1[] =
871                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
872         static const u8 n2[] =
873                         {0x08, 0x00};
874
875         sensor_id = (reg_r(gspca_dev, 0x06) << 8)
876                         | reg_r(gspca_dev, 0x07);
877         switch (sensor_id & 0xff0f) {
878         case 0x0801:
879                 PDEBUG(D_PROBE, "sensor tas5130a");
880                 sd->sensor = SENSOR_TAS5130A;
881                 break;
882         case 0x0802:
883                 PDEBUG(D_PROBE, "sensor lt168g");
884                 sd->sensor = SENSOR_LT168G;
885                 break;
886         case 0x0803:
887                 PDEBUG(D_PROBE, "sensor 'other'");
888                 sd->sensor = SENSOR_OTHER;
889                 break;
890         case 0x0807:
891                 PDEBUG(D_PROBE, "sensor om6802");
892                 sd->sensor = SENSOR_OM6802;
893                 break;
894         default:
895                 err("unknown sensor %04x", sensor_id);
896                 return -EINVAL;
897         }
898
899         if (sd->sensor == SENSOR_OM6802) {
900                 reg_w_buf(gspca_dev, n1, sizeof n1);
901                 i = 5;
902                 while (--i >= 0) {
903                         reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
904                         test_byte = reg_r(gspca_dev, 0x0063);
905                         msleep(100);
906                         if (test_byte == 0x17)
907                                 break;          /* OK */
908                 }
909                 if (i < 0) {
910                         err("Bad sensor reset %02x", test_byte);
911                         return -EIO;
912                 }
913                 reg_w_buf(gspca_dev, n2, sizeof n2);
914         }
915
916         i = 0;
917         while (read_indexs[i] != 0x00) {
918                 test_byte = reg_r(gspca_dev, read_indexs[i]);
919                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
920                        test_byte);
921                 i++;
922         }
923
924         sensor = &sensor_data[sd->sensor];
925         reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
926         reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
927
928         if (sd->sensor == SENSOR_LT168G) {
929                 test_byte = reg_r(gspca_dev, 0x80);
930                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
931                        test_byte);
932                 reg_w(gspca_dev, 0x6c80);
933         }
934
935         reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
936         reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
937         reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
938
939         reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
940         reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
941         reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
942
943         setbrightness(gspca_dev);
944         setcontrast(gspca_dev);
945         setgamma(gspca_dev);
946         setcolors(gspca_dev);
947         setsharpness(gspca_dev);
948         init_gains(gspca_dev);
949         setfreq(gspca_dev);
950
951         reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
952         reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
953         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
954
955         if (sd->sensor == SENSOR_LT168G) {
956                 test_byte = reg_r(gspca_dev, 0x80);
957                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
958                        test_byte);
959                 reg_w(gspca_dev, 0x6c80);
960         }
961
962         reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
963         reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
964         reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
965
966         return 0;
967 }
968
969 static void setmirror(struct gspca_dev *gspca_dev)
970 {
971         struct sd *sd = (struct sd *) gspca_dev;
972         u8 hflipcmd[8] =
973                 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
974
975         if (sd->mirror)
976                 hflipcmd[3] = 0x01;
977
978         reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
979 }
980
981 static void seteffect(struct gspca_dev *gspca_dev)
982 {
983         struct sd *sd = (struct sd *) gspca_dev;
984
985         reg_w_buf(gspca_dev, effects_table[sd->effect],
986                                 sizeof effects_table[0]);
987         if (sd->effect == 1 || sd->effect == 5) {
988                 PDEBUG(D_CONF,
989                        "This effect have been disabled for webcam \"safety\"");
990                 return;
991         }
992
993         if (sd->effect == 1 || sd->effect == 4)
994                 reg_w(gspca_dev, 0x4aa6);
995         else
996                 reg_w(gspca_dev, 0xfaa6);
997 }
998
999 /* Is this really needed?
1000  * i added some module parameters for test with some users */
1001 static void poll_sensor(struct gspca_dev *gspca_dev)
1002 {
1003         static const u8 poll1[] =
1004                 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
1005                  0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
1006                  0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
1007                  0x60, 0x14};
1008         static const u8 poll2[] =
1009                 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
1010                  0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
1011         static const u8 noise03[] =     /* (some differences / ms-drv) */
1012                 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
1013                  0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
1014                  0xc2, 0x80, 0xc3, 0x10};
1015
1016         PDEBUG(D_STREAM, "[Sensor requires polling]");
1017         reg_w_buf(gspca_dev, poll1, sizeof poll1);
1018         reg_w_buf(gspca_dev, poll2, sizeof poll2);
1019         reg_w_buf(gspca_dev, noise03, sizeof noise03);
1020 }
1021
1022 static int sd_start(struct gspca_dev *gspca_dev)
1023 {
1024         struct sd *sd = (struct sd *) gspca_dev;
1025         const struct additional_sensor_data *sensor;
1026         int i, mode;
1027         u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
1028         static const u8 t3[] =
1029                 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
1030
1031         mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1032         switch (mode) {
1033         case 0:         /* 640x480 (0x00) */
1034                 break;
1035         case 1:         /* 352x288 */
1036                 t2[1] = 0x40;
1037                 break;
1038         case 2:         /* 320x240 */
1039                 t2[1] = 0x10;
1040                 break;
1041         case 3:         /* 176x144 */
1042                 t2[1] = 0x50;
1043                 break;
1044         default:
1045 /*      case 4:          * 160x120 */
1046                 t2[1] = 0x20;
1047                 break;
1048         }
1049
1050         switch (sd->sensor) {
1051         case SENSOR_OM6802:
1052                 om6802_sensor_init(gspca_dev);
1053                 break;
1054         case SENSOR_TAS5130A:
1055                 i = 0;
1056                 for (;;) {
1057                         reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
1058                                          sizeof tas5130a_sensor_init[0]);
1059                         if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
1060                                 break;
1061                         i++;
1062                 }
1063                 reg_w(gspca_dev, 0x3c80);
1064                 /* just in case and to keep sync with logs (for mine) */
1065                 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
1066                                  sizeof tas5130a_sensor_init[0]);
1067                 reg_w(gspca_dev, 0x3c80);
1068                 break;
1069         }
1070         sensor = &sensor_data[sd->sensor];
1071         setfreq(gspca_dev);
1072         reg_r(gspca_dev, 0x0012);
1073         reg_w_buf(gspca_dev, t2, sizeof t2);
1074         reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
1075         reg_w(gspca_dev, 0x0013);
1076         msleep(15);
1077         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
1078         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
1079
1080         if (sd->sensor == SENSOR_OM6802)
1081                 poll_sensor(gspca_dev);
1082
1083         return 0;
1084 }
1085
1086 static void sd_stopN(struct gspca_dev *gspca_dev)
1087 {
1088         struct sd *sd = (struct sd *) gspca_dev;
1089
1090         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
1091                         sizeof sensor_data[sd->sensor].stream);
1092         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
1093                         sizeof sensor_data[sd->sensor].stream);
1094         if (sd->sensor == SENSOR_OM6802) {
1095                 msleep(20);
1096                 reg_w(gspca_dev, 0x0309);
1097         }
1098 }
1099
1100 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1101                         u8 *data,                       /* isoc packet */
1102                         int len)                        /* iso packet length */
1103 {
1104         int pkt_type;
1105
1106         if (data[0] == 0x5a) {
1107                 /* Control Packet, after this came the header again,
1108                  * but extra bytes came in the packet before this,
1109                  * sometimes an EOF arrives, sometimes not... */
1110                 return;
1111         }
1112         data += 2;
1113         len -= 2;
1114         if (data[0] == 0xff && data[1] == 0xd8)
1115                 pkt_type = FIRST_PACKET;
1116         else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
1117                 pkt_type = LAST_PACKET;
1118         else
1119                 pkt_type = INTER_PACKET;
1120         gspca_frame_add(gspca_dev, pkt_type, data, len);
1121 }
1122
1123 static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val)
1124 {
1125         struct sd *sd = (struct sd *) gspca_dev;
1126
1127         sd->blue_gain = val;
1128         if (gspca_dev->streaming)
1129                 reg_w(gspca_dev, (val << 8) + 0x88);
1130         return 0;
1131 }
1132
1133 static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val)
1134 {
1135         struct sd *sd = (struct sd *) gspca_dev;
1136
1137         *val = sd->blue_gain;
1138         return 0;
1139 }
1140
1141 static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val)
1142 {
1143         struct sd *sd = (struct sd *) gspca_dev;
1144
1145         sd->red_gain = val;
1146         if (gspca_dev->streaming)
1147                 reg_w(gspca_dev, (val << 8) + 0x87);
1148
1149         return 0;
1150 }
1151
1152 static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val)
1153 {
1154         struct sd *sd = (struct sd *) gspca_dev;
1155
1156         *val = sd->red_gain;
1157         return 0;
1158 }
1159
1160 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1161 {
1162         struct sd *sd = (struct sd *) gspca_dev;
1163         u16 psg, nsg;
1164
1165         psg = sd->red_gain + sd->blue_gain + sd->green_gain;
1166         nsg = val * 3;
1167         sd->red_gain = sd->red_gain * nsg / psg;
1168         if (sd->red_gain > 0x40)
1169                 sd->red_gain = 0x40;
1170         else if (sd->red_gain < 0x10)
1171                 sd->red_gain = 0x10;
1172         sd->blue_gain = sd->blue_gain * nsg / psg;
1173         if (sd->blue_gain > 0x40)
1174                 sd->blue_gain = 0x40;
1175         else if (sd->blue_gain < 0x10)
1176                 sd->blue_gain = 0x10;
1177         sd->green_gain = sd->green_gain * nsg / psg;
1178         if (sd->green_gain > 0x40)
1179                 sd->green_gain = 0x40;
1180         else if (sd->green_gain < 0x10)
1181                 sd->green_gain = 0x10;
1182
1183         if (gspca_dev->streaming)
1184                 setRGB(gspca_dev);
1185         return 0;
1186 }
1187
1188 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1189 {
1190         struct sd *sd = (struct sd *) gspca_dev;
1191
1192         *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3;
1193         return 0;
1194 }
1195
1196 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1197 {
1198         struct sd *sd = (struct sd *) gspca_dev;
1199
1200         sd->brightness = val;
1201         if (gspca_dev->streaming)
1202                 setbrightness(gspca_dev);
1203         return 0;
1204 }
1205
1206 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1207 {
1208         struct sd *sd = (struct sd *) gspca_dev;
1209
1210         *val = sd->brightness;
1211         return *val;
1212 }
1213
1214 static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
1215 {
1216         struct sd *sd = (struct sd *) gspca_dev;
1217
1218         sd->awb = val;
1219         if (gspca_dev->streaming)
1220                 setawb(gspca_dev);
1221         return 0;
1222 }
1223
1224 static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
1225 {
1226         struct sd *sd = (struct sd *) gspca_dev;
1227
1228         *val = sd->awb;
1229         return *val;
1230 }
1231
1232 static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val)
1233 {
1234         struct sd *sd = (struct sd *) gspca_dev;
1235
1236         sd->mirror = val;
1237         if (gspca_dev->streaming)
1238                 setmirror(gspca_dev);
1239         return 0;
1240 }
1241
1242 static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val)
1243 {
1244         struct sd *sd = (struct sd *) gspca_dev;
1245
1246         *val = sd->mirror;
1247         return *val;
1248 }
1249
1250 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
1251 {
1252         struct sd *sd = (struct sd *) gspca_dev;
1253
1254         sd->effect = val;
1255         if (gspca_dev->streaming)
1256                 seteffect(gspca_dev);
1257         return 0;
1258 }
1259
1260 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
1261 {
1262         struct sd *sd = (struct sd *) gspca_dev;
1263
1264         *val = sd->effect;
1265         return *val;
1266 }
1267
1268 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1269 {
1270         struct sd *sd = (struct sd *) gspca_dev;
1271
1272         sd->contrast = val;
1273         if (gspca_dev->streaming)
1274                 setcontrast(gspca_dev);
1275         return 0;
1276 }
1277
1278 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1279 {
1280         struct sd *sd = (struct sd *) gspca_dev;
1281
1282         *val = sd->contrast;
1283         return *val;
1284 }
1285
1286 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1287 {
1288         struct sd *sd = (struct sd *) gspca_dev;
1289
1290         sd->colors = val;
1291         if (gspca_dev->streaming)
1292                 setcolors(gspca_dev);
1293         return 0;
1294 }
1295
1296 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1297 {
1298         struct sd *sd = (struct sd *) gspca_dev;
1299
1300         *val = sd->colors;
1301         return 0;
1302 }
1303
1304 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1305 {
1306         struct sd *sd = (struct sd *) gspca_dev;
1307
1308         sd->gamma = val;
1309         if (gspca_dev->streaming)
1310                 setgamma(gspca_dev);
1311         return 0;
1312 }
1313
1314 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1315 {
1316         struct sd *sd = (struct sd *) gspca_dev;
1317
1318         *val = sd->gamma;
1319         return 0;
1320 }
1321
1322 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1323 {
1324         struct sd *sd = (struct sd *) gspca_dev;
1325
1326         sd->freq = val;
1327         if (gspca_dev->streaming)
1328                 setfreq(gspca_dev);
1329         return 0;
1330 }
1331
1332 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1333 {
1334         struct sd *sd = (struct sd *) gspca_dev;
1335
1336         *val = sd->freq;
1337         return 0;
1338 }
1339
1340 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1341 {
1342         struct sd *sd = (struct sd *) gspca_dev;
1343
1344         sd->sharpness = val;
1345         if (gspca_dev->streaming)
1346                 setsharpness(gspca_dev);
1347         return 0;
1348 }
1349
1350 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1351 {
1352         struct sd *sd = (struct sd *) gspca_dev;
1353
1354         *val = sd->sharpness;
1355         return 0;
1356 }
1357
1358 /* Low Light set  here......*/
1359 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1360 {
1361         struct sd *sd = (struct sd *) gspca_dev;
1362
1363         sd->autogain = val;
1364         if (val != 0)
1365                 reg_w(gspca_dev, 0xf48e);
1366         else
1367                 reg_w(gspca_dev, 0xb48e);
1368         return 0;
1369 }
1370
1371 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1372 {
1373         struct sd *sd = (struct sd *) gspca_dev;
1374
1375         *val = sd->autogain;
1376         return 0;
1377 }
1378
1379 static int sd_querymenu(struct gspca_dev *gspca_dev,
1380                         struct v4l2_querymenu *menu)
1381 {
1382         switch (menu->id) {
1383         case V4L2_CID_POWER_LINE_FREQUENCY:
1384                 switch (menu->index) {
1385                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1386                         strcpy((char *) menu->name, "50 Hz");
1387                         return 0;
1388                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1389                         strcpy((char *) menu->name, "60 Hz");
1390                         return 0;
1391                 }
1392                 break;
1393         case V4L2_CID_EFFECTS:
1394                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1395                         strncpy((char *) menu->name,
1396                                 effects_control[menu->index],
1397                                 sizeof menu->name);
1398                         return 0;
1399                 }
1400                 break;
1401         }
1402         return -EINVAL;
1403 }
1404
1405 /* sub-driver description */
1406 static const struct sd_desc sd_desc = {
1407         .name = MODULE_NAME,
1408         .ctrls = sd_ctrls,
1409         .nctrls = ARRAY_SIZE(sd_ctrls),
1410         .config = sd_config,
1411         .init = sd_init,
1412         .start = sd_start,
1413         .stopN = sd_stopN,
1414         .pkt_scan = sd_pkt_scan,
1415         .querymenu = sd_querymenu,
1416 };
1417
1418 /* -- module initialisation -- */
1419 static const struct usb_device_id device_table[] = {
1420         {USB_DEVICE(0x17a1, 0x0128)},
1421         {}
1422 };
1423 MODULE_DEVICE_TABLE(usb, device_table);
1424
1425 /* -- device connect -- */
1426 static int sd_probe(struct usb_interface *intf,
1427                     const struct usb_device_id *id)
1428 {
1429         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1430                                THIS_MODULE);
1431 }
1432
1433 static struct usb_driver sd_driver = {
1434         .name = MODULE_NAME,
1435         .id_table = device_table,
1436         .probe = sd_probe,
1437         .disconnect = gspca_disconnect,
1438 #ifdef CONFIG_PM
1439         .suspend = gspca_suspend,
1440         .resume = gspca_resume,
1441 #endif
1442 };
1443
1444 /* -- module insert / remove -- */
1445 static int __init sd_mod_init(void)
1446 {
1447         return usb_register(&sd_driver);
1448 }
1449 static void __exit sd_mod_exit(void)
1450 {
1451         usb_deregister(&sd_driver);
1452 }
1453
1454 module_init(sd_mod_init);
1455 module_exit(sd_mod_exit);