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