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