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