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