d0c208c6a69062537c5b322150e41067dd13fa2e
[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 };
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 const 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                         u8 *data,                       /* isoc packet */
942                         int len)                        /* iso packet length */
943 {
944         static u8 ffd9[] = { 0xff, 0xd9 };
945
946         if (data[0] == 0x5a) {
947                 /* Control Packet, after this came the header again,
948                  * but extra bytes came in the packet before this,
949                  * sometimes an EOF arrives, sometimes not... */
950                 return;
951         }
952         data += 2;
953         len -= 2;
954         if (data[0] == 0xff && data[1] == 0xd8) {
955                 /* extra bytes....., could be processed too but would be
956                  * a waste of time, right now leave the application and
957                  * libjpeg do it for ourserlves.. */
958                 gspca_frame_add(gspca_dev, LAST_PACKET,
959                                         ffd9, 2);
960                 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
961                 return;
962         }
963
964         if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
965                 /* Just in case, i have seen packets with the marker,
966                  * other's do not include it... */
967                 len -= 2;
968         }
969         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
970 }
971
972 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
973 {
974         struct sd *sd = (struct sd *) gspca_dev;
975
976         sd->brightness = val;
977         if (gspca_dev->streaming)
978                 setbrightness(gspca_dev);
979         return 0;
980 }
981
982 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
983 {
984         struct sd *sd = (struct sd *) gspca_dev;
985
986         *val = sd->brightness;
987         return *val;
988 }
989
990 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
991 {
992         struct sd *sd = (struct sd *) gspca_dev;
993
994         sd->whitebalance = val;
995         if (gspca_dev->streaming)
996                 setwhitebalance(gspca_dev);
997         return 0;
998 }
999
1000 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1001 {
1002         struct sd *sd = (struct sd *) gspca_dev;
1003
1004         *val = sd->whitebalance;
1005         return *val;
1006 }
1007
1008 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
1009 {
1010         struct sd *sd = (struct sd *) gspca_dev;
1011
1012         sd->mirror = val;
1013         if (gspca_dev->streaming)
1014                 setflip(gspca_dev);
1015         return 0;
1016 }
1017
1018 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
1019 {
1020         struct sd *sd = (struct sd *) gspca_dev;
1021
1022         *val = sd->mirror;
1023         return *val;
1024 }
1025
1026 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
1027 {
1028         struct sd *sd = (struct sd *) gspca_dev;
1029
1030         sd->effect = val;
1031         if (gspca_dev->streaming)
1032                 seteffect(gspca_dev);
1033         return 0;
1034 }
1035
1036 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
1037 {
1038         struct sd *sd = (struct sd *) gspca_dev;
1039
1040         *val = sd->effect;
1041         return *val;
1042 }
1043
1044 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1045 {
1046         struct sd *sd = (struct sd *) gspca_dev;
1047
1048         sd->contrast = val;
1049         if (gspca_dev->streaming)
1050                 setcontrast(gspca_dev);
1051         return 0;
1052 }
1053
1054 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1055 {
1056         struct sd *sd = (struct sd *) gspca_dev;
1057
1058         *val = sd->contrast;
1059         return *val;
1060 }
1061
1062 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1063 {
1064         struct sd *sd = (struct sd *) gspca_dev;
1065
1066         sd->colors = val;
1067         if (gspca_dev->streaming)
1068                 setcolors(gspca_dev);
1069         return 0;
1070 }
1071
1072 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1073 {
1074         struct sd *sd = (struct sd *) gspca_dev;
1075
1076         *val = sd->colors;
1077         return 0;
1078 }
1079
1080 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1081 {
1082         struct sd *sd = (struct sd *) gspca_dev;
1083
1084         sd->gamma = val;
1085         if (gspca_dev->streaming)
1086                 setgamma(gspca_dev);
1087         return 0;
1088 }
1089
1090 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1091 {
1092         struct sd *sd = (struct sd *) gspca_dev;
1093
1094         *val = sd->gamma;
1095         return 0;
1096 }
1097
1098 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1099 {
1100         struct sd *sd = (struct sd *) gspca_dev;
1101
1102         sd->freq = val;
1103         if (gspca_dev->streaming)
1104                 setlightfreq(gspca_dev);
1105         return 0;
1106 }
1107
1108 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1109 {
1110         struct sd *sd = (struct sd *) gspca_dev;
1111
1112         *val = sd->freq;
1113         return 0;
1114 }
1115
1116 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1117 {
1118         struct sd *sd = (struct sd *) gspca_dev;
1119
1120         sd->sharpness = val;
1121         if (gspca_dev->streaming)
1122                 setsharpness(gspca_dev);
1123         return 0;
1124 }
1125
1126 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1127 {
1128         struct sd *sd = (struct sd *) gspca_dev;
1129
1130         *val = sd->sharpness;
1131         return 0;
1132 }
1133
1134 /* Low Light set  here......*/
1135 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1136 {
1137         struct sd *sd = (struct sd *) gspca_dev;
1138
1139         sd->autogain = val;
1140         if (val != 0)
1141                 reg_w(gspca_dev, 0xf48e);
1142         else
1143                 reg_w(gspca_dev, 0xb48e);
1144         return 0;
1145 }
1146
1147 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1148 {
1149         struct sd *sd = (struct sd *) gspca_dev;
1150
1151         *val = sd->autogain;
1152         return 0;
1153 }
1154
1155 static int sd_querymenu(struct gspca_dev *gspca_dev,
1156                         struct v4l2_querymenu *menu)
1157 {
1158         switch (menu->id) {
1159         case V4L2_CID_POWER_LINE_FREQUENCY:
1160                 switch (menu->index) {
1161                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1162                         strcpy((char *) menu->name, "50 Hz");
1163                         return 0;
1164                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1165                         strcpy((char *) menu->name, "60 Hz");
1166                         return 0;
1167                 }
1168                 break;
1169         case V4L2_CID_EFFECTS:
1170                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1171                         strncpy((char *) menu->name,
1172                                 effects_control[menu->index], 32);
1173                         return 0;
1174                 }
1175                 break;
1176         }
1177         return -EINVAL;
1178 }
1179
1180 /* sub-driver description */
1181 static const struct sd_desc sd_desc = {
1182         .name = MODULE_NAME,
1183         .ctrls = sd_ctrls,
1184         .nctrls = ARRAY_SIZE(sd_ctrls),
1185         .config = sd_config,
1186         .init = sd_init,
1187         .start = sd_start,
1188         .stopN = sd_stopN,
1189         .pkt_scan = sd_pkt_scan,
1190         .querymenu = sd_querymenu,
1191 };
1192
1193 /* -- module initialisation -- */
1194 static const __devinitdata struct usb_device_id device_table[] = {
1195         {USB_DEVICE(0x17a1, 0x0128)},
1196         {}
1197 };
1198 MODULE_DEVICE_TABLE(usb, device_table);
1199
1200 /* -- device connect -- */
1201 static int sd_probe(struct usb_interface *intf,
1202                     const struct usb_device_id *id)
1203 {
1204         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1205                                THIS_MODULE);
1206 }
1207
1208 static struct usb_driver sd_driver = {
1209         .name = MODULE_NAME,
1210         .id_table = device_table,
1211         .probe = sd_probe,
1212         .disconnect = gspca_disconnect,
1213 #ifdef CONFIG_PM
1214         .suspend = gspca_suspend,
1215         .resume = gspca_resume,
1216 #endif
1217 };
1218
1219 /* -- module insert / remove -- */
1220 static int __init sd_mod_init(void)
1221 {
1222         int ret;
1223         ret = usb_register(&sd_driver);
1224         if (ret < 0)
1225                 return ret;
1226         PDEBUG(D_PROBE, "registered");
1227         return 0;
1228 }
1229 static void __exit sd_mod_exit(void)
1230 {
1231         usb_deregister(&sd_driver);
1232         PDEBUG(D_PROBE, "deregistered");
1233 }
1234
1235 module_init(sd_mod_init);
1236 module_exit(sd_mod_exit);