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