]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/t613.c
V4L/DVB (10333): gspca - main and many subdrivers: Remove the epaddr variable.
[linux-2.6-omap-h63xx.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         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 const 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
542         cam->cam_mode = vga_mode_t16;
543         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
544
545         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
546         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
547         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
548         sd->gamma = GAMMA_DEF;
549         sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
550         sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
551         sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
552         sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
553         sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
554         return 0;
555 }
556
557 static void setbrightness(struct gspca_dev *gspca_dev)
558 {
559         struct sd *sd = (struct sd *) gspca_dev;
560         unsigned int brightness;
561         __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
562
563         brightness = sd->brightness;
564         if (brightness < 7) {
565                 set6[1] = 0x26;
566                 set6[3] = 0x70 - brightness * 0x10;
567         } else {
568                 set6[3] = 0x00 + ((brightness - 7) * 0x10);
569         }
570
571         reg_w_buf(gspca_dev, set6, sizeof set6);
572 }
573
574 static void setcontrast(struct gspca_dev *gspca_dev)
575 {
576         struct sd *sd = (struct sd *) gspca_dev;
577         unsigned int contrast = sd->contrast;
578         __u16 reg_to_write;
579
580         if (contrast < 7)
581                 reg_to_write = 0x8ea9 - contrast * 0x200;
582         else
583                 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
584
585         reg_w(gspca_dev, reg_to_write);
586 }
587
588 static void setcolors(struct gspca_dev *gspca_dev)
589 {
590         struct sd *sd = (struct sd *) gspca_dev;
591         __u16 reg_to_write;
592
593         reg_to_write = 0x80bb + sd->colors * 0x100;     /* was 0xc0 */
594         reg_w(gspca_dev, reg_to_write);
595 }
596
597 static void setgamma(struct gspca_dev *gspca_dev)
598 {
599         struct sd *sd = (struct sd *) gspca_dev;
600
601         PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
602         reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
603 }
604
605 static void setwhitebalance(struct gspca_dev *gspca_dev)
606 {
607         struct sd *sd = (struct sd *) gspca_dev;
608
609         __u8 white_balance[8] =
610                 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
611
612         if (sd->whitebalance)
613                 white_balance[7] = 0x3c;
614
615         reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
616 }
617
618 static void setsharpness(struct gspca_dev *gspca_dev)
619 {
620         struct sd *sd = (struct sd *) gspca_dev;
621         __u16 reg_to_write;
622
623         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
624
625         reg_w(gspca_dev, reg_to_write);
626 }
627
628 /* this function is called at probe and resume time */
629 static int sd_init(struct gspca_dev *gspca_dev)
630 {
631         /* some of this registers are not really neded, because
632          * they are overriden by setbrigthness, setcontrast, etc,
633          * but wont hurt anyway, and can help someone with similar webcam
634          * to see the initial parameters.*/
635         struct sd *sd = (struct sd *) gspca_dev;
636         int i;
637         __u8 byte, test_byte;
638
639         static const __u8 read_indexs[] =
640                 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
641                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
642         static const __u8 n1[] =
643                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
644         static const __u8 n2[] =
645                         {0x08, 0x00};
646         static const __u8 n3[] =
647                         {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
648         static const __u8 n4[] =
649                 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
650                  0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
651                  0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
652                  0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
653                  0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
654                  0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
655                  0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
656                  0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
657                  0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
658         static const __u8 nset9[4] =
659                         { 0x0b, 0x04, 0x0a, 0x78 };
660         static const __u8 nset8[6] =
661                         { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
662
663         byte = reg_r(gspca_dev, 0x06);
664         test_byte = reg_r(gspca_dev, 0x07);
665         if (byte == 0x08 && test_byte == 0x07) {
666                 PDEBUG(D_CONF, "sensor om6802");
667                 sd->sensor = SENSOR_OM6802;
668         } else if (byte == 0x08 && test_byte == 0x01) {
669                 PDEBUG(D_CONF, "sensor tas5130a");
670                 sd->sensor = SENSOR_TAS5130A;
671         } else {
672                 PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
673                 sd->sensor = SENSOR_TAS5130A;
674         }
675
676         reg_w_buf(gspca_dev, n1, sizeof n1);
677         test_byte = 0;
678         i = 5;
679         while (--i >= 0) {
680                 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
681                 test_byte = reg_r(gspca_dev, 0x0063);
682                 msleep(100);
683                 if (test_byte == 0x17)
684                         break;          /* OK */
685         }
686         if (i < 0) {
687                 err("Bad sensor reset %02x", test_byte);
688 /*              return -EIO; */
689 /*fixme: test - continue */
690         }
691         reg_w_buf(gspca_dev, n2, sizeof n2);
692
693         i = 0;
694         while (read_indexs[i] != 0x00) {
695                 test_byte = reg_r(gspca_dev, read_indexs[i]);
696                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
697                        test_byte);
698                 i++;
699         }
700
701         reg_w_buf(gspca_dev, n3, sizeof n3);
702         reg_w_buf(gspca_dev, n4, sizeof n4);
703         reg_r(gspca_dev, 0x0080);
704         reg_w(gspca_dev, 0x2c80);
705
706         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
707                         sizeof sensor_data[sd->sensor].data1);
708         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
709                         sizeof sensor_data[sd->sensor].data3);
710         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
711                         sizeof sensor_data[sd->sensor].data2);
712
713         reg_w(gspca_dev, 0x3880);
714         reg_w(gspca_dev, 0x3880);
715         reg_w(gspca_dev, 0x338e);
716
717         setbrightness(gspca_dev);
718         setcontrast(gspca_dev);
719         setgamma(gspca_dev);
720         setcolors(gspca_dev);
721         setsharpness(gspca_dev);
722         setwhitebalance(gspca_dev);
723
724         reg_w(gspca_dev, 0x2087);       /* tied to white balance? */
725         reg_w(gspca_dev, 0x2088);
726         reg_w(gspca_dev, 0x2089);
727
728         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
729                         sizeof sensor_data[sd->sensor].data4);
730         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
731                         sizeof sensor_data[sd->sensor].data5);
732         reg_w_buf(gspca_dev, nset8, sizeof nset8);
733         reg_w_buf(gspca_dev, nset9, sizeof nset9);
734
735         reg_w(gspca_dev, 0x2880);
736
737         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
738                         sizeof sensor_data[sd->sensor].data1);
739         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
740                         sizeof sensor_data[sd->sensor].data3);
741         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
742                         sizeof sensor_data[sd->sensor].data2);
743
744         return 0;
745 }
746
747 static void setflip(struct gspca_dev *gspca_dev)
748 {
749         struct sd *sd = (struct sd *) gspca_dev;
750         __u8 flipcmd[8] =
751                 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
752
753         if (sd->mirror)
754                 flipcmd[3] = 0x01;
755
756         reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
757 }
758
759 static void seteffect(struct gspca_dev *gspca_dev)
760 {
761         struct sd *sd = (struct sd *) gspca_dev;
762
763         reg_w_buf(gspca_dev, effects_table[sd->effect],
764                                 sizeof effects_table[0]);
765         if (sd->effect == 1 || sd->effect == 5) {
766                 PDEBUG(D_CONF,
767                        "This effect have been disabled for webcam \"safety\"");
768                 return;
769         }
770
771         if (sd->effect == 1 || sd->effect == 4)
772                 reg_w(gspca_dev, 0x4aa6);
773         else
774                 reg_w(gspca_dev, 0xfaa6);
775 }
776
777 static void setlightfreq(struct gspca_dev *gspca_dev)
778 {
779         struct sd *sd = (struct sd *) gspca_dev;
780         __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
781
782         if (sd->freq == 2)      /* 60hz */
783                 freq[1] = 0x00;
784
785         reg_w_buf(gspca_dev, freq, sizeof freq);
786 }
787
788 /* Is this really needed?
789  * i added some module parameters for test with some users */
790 static void poll_sensor(struct gspca_dev *gspca_dev)
791 {
792         struct sd *sd = (struct sd *) gspca_dev;
793         static const __u8 poll1[] =
794                 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
795                  0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
796                  0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
797                  0x60, 0x14};
798         static const __u8 poll2[] =
799                 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
800                  0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
801         static const __u8 poll3[] =
802                 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
803         static const __u8 poll4[] =
804                 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
805                  0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
806                  0xc2, 0x80, 0xc3, 0x10};
807
808         if (sd->sensor != SENSOR_TAS5130A) {
809                 PDEBUG(D_STREAM, "[Sensor requires polling]");
810                 reg_w_buf(gspca_dev, poll1, sizeof poll1);
811                 reg_w_buf(gspca_dev, poll2, sizeof poll2);
812                 reg_w_buf(gspca_dev, poll3, sizeof poll3);
813                 reg_w_buf(gspca_dev, poll4, sizeof poll4);
814         }
815 }
816
817 static int sd_start(struct gspca_dev *gspca_dev)
818 {
819         struct sd *sd = (struct sd *) gspca_dev;
820         int i, mode;
821         __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
822         static const __u8 t3[] =
823                 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
824                   0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
825
826         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
827         switch (mode) {
828         case 1:         /* 352x288 */
829                 t2[1] = 0x40;
830                 break;
831         case 2:         /* 320x240 */
832                 t2[1] = 0x10;
833                 break;
834         case 3:         /* 176x144 */
835                 t2[1] = 0x50;
836                 break;
837         case 4:         /* 160x120 */
838                 t2[1] = 0x20;
839                 break;
840         default:        /* 640x480 (0x00) */
841                 break;
842         }
843
844         if (sd->sensor == SENSOR_TAS5130A) {
845                 i = 0;
846                 while (tas5130a_sensor_init[i][0] != 0) {
847                         reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
848                                          sizeof tas5130a_sensor_init[0]);
849                         i++;
850                 }
851                 reg_w(gspca_dev, 0x3c80);
852                 /* just in case and to keep sync with logs (for mine) */
853                 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
854                                  sizeof tas5130a_sensor_init[0]);
855                 reg_w(gspca_dev, 0x3c80);
856         } else {
857                 om6802_sensor_init(gspca_dev);
858         }
859         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
860                         sizeof sensor_data[sd->sensor].data4);
861         reg_r(gspca_dev, 0x0012);
862         reg_w_buf(gspca_dev, t2, sizeof t2);
863         reg_w_buf(gspca_dev, t3, sizeof t3);
864         reg_w(gspca_dev, 0x0013);
865         msleep(15);
866         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
867                         sizeof sensor_data[sd->sensor].stream);
868         poll_sensor(gspca_dev);
869
870         /* restart on each start, just in case, sometimes regs goes wrong
871          * when using controls from app */
872         setbrightness(gspca_dev);
873         setcontrast(gspca_dev);
874         setcolors(gspca_dev);
875         return 0;
876 }
877
878 static void sd_stopN(struct gspca_dev *gspca_dev)
879 {
880         struct sd *sd = (struct sd *) gspca_dev;
881
882         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
883                         sizeof sensor_data[sd->sensor].stream);
884         msleep(20);
885         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
886                         sizeof sensor_data[sd->sensor].stream);
887         msleep(20);
888         reg_w(gspca_dev, 0x0309);
889 }
890
891 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
892                         struct gspca_frame *frame,      /* target */
893                         __u8 *data,                     /* isoc packet */
894                         int len)                        /* iso packet length */
895 {
896         static __u8 ffd9[] = { 0xff, 0xd9 };
897
898         if (data[0] == 0x5a) {
899                 /* Control Packet, after this came the header again,
900                  * but extra bytes came in the packet before this,
901                  * sometimes an EOF arrives, sometimes not... */
902                 return;
903         }
904         data += 2;
905         len -= 2;
906         if (data[0] == 0xff && data[1] == 0xd8) {
907                 /* extra bytes....., could be processed too but would be
908                  * a waste of time, right now leave the application and
909                  * libjpeg do it for ourserlves.. */
910                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
911                                         ffd9, 2);
912                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
913                 return;
914         }
915
916         if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
917                 /* Just in case, i have seen packets with the marker,
918                  * other's do not include it... */
919                 len -= 2;
920         }
921         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
922 }
923
924 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
925 {
926         struct sd *sd = (struct sd *) gspca_dev;
927
928         sd->brightness = val;
929         if (gspca_dev->streaming)
930                 setbrightness(gspca_dev);
931         return 0;
932 }
933
934 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
935 {
936         struct sd *sd = (struct sd *) gspca_dev;
937
938         *val = sd->brightness;
939         return *val;
940 }
941
942 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
943 {
944         struct sd *sd = (struct sd *) gspca_dev;
945
946         sd->whitebalance = val;
947         if (gspca_dev->streaming)
948                 setwhitebalance(gspca_dev);
949         return 0;
950 }
951
952 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
953 {
954         struct sd *sd = (struct sd *) gspca_dev;
955
956         *val = sd->whitebalance;
957         return *val;
958 }
959
960 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
961 {
962         struct sd *sd = (struct sd *) gspca_dev;
963
964         sd->mirror = val;
965         if (gspca_dev->streaming)
966                 setflip(gspca_dev);
967         return 0;
968 }
969
970 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
971 {
972         struct sd *sd = (struct sd *) gspca_dev;
973
974         *val = sd->mirror;
975         return *val;
976 }
977
978 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
979 {
980         struct sd *sd = (struct sd *) gspca_dev;
981
982         sd->effect = val;
983         if (gspca_dev->streaming)
984                 seteffect(gspca_dev);
985         return 0;
986 }
987
988 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
989 {
990         struct sd *sd = (struct sd *) gspca_dev;
991
992         *val = sd->effect;
993         return *val;
994 }
995
996 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
997 {
998         struct sd *sd = (struct sd *) gspca_dev;
999
1000         sd->contrast = val;
1001         if (gspca_dev->streaming)
1002                 setcontrast(gspca_dev);
1003         return 0;
1004 }
1005
1006 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1007 {
1008         struct sd *sd = (struct sd *) gspca_dev;
1009
1010         *val = sd->contrast;
1011         return *val;
1012 }
1013
1014 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1015 {
1016         struct sd *sd = (struct sd *) gspca_dev;
1017
1018         sd->colors = val;
1019         if (gspca_dev->streaming)
1020                 setcolors(gspca_dev);
1021         return 0;
1022 }
1023
1024 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1025 {
1026         struct sd *sd = (struct sd *) gspca_dev;
1027
1028         *val = sd->colors;
1029         return 0;
1030 }
1031
1032 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1033 {
1034         struct sd *sd = (struct sd *) gspca_dev;
1035
1036         sd->gamma = val;
1037         if (gspca_dev->streaming)
1038                 setgamma(gspca_dev);
1039         return 0;
1040 }
1041
1042 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1043 {
1044         struct sd *sd = (struct sd *) gspca_dev;
1045
1046         *val = sd->gamma;
1047         return 0;
1048 }
1049
1050 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1051 {
1052         struct sd *sd = (struct sd *) gspca_dev;
1053
1054         sd->freq = val;
1055         if (gspca_dev->streaming)
1056                 setlightfreq(gspca_dev);
1057         return 0;
1058 }
1059
1060 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1061 {
1062         struct sd *sd = (struct sd *) gspca_dev;
1063
1064         *val = sd->freq;
1065         return 0;
1066 }
1067
1068 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1069 {
1070         struct sd *sd = (struct sd *) gspca_dev;
1071
1072         sd->sharpness = val;
1073         if (gspca_dev->streaming)
1074                 setsharpness(gspca_dev);
1075         return 0;
1076 }
1077
1078 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1079 {
1080         struct sd *sd = (struct sd *) gspca_dev;
1081
1082         *val = sd->sharpness;
1083         return 0;
1084 }
1085
1086 /* Low Light set  here......*/
1087 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1088 {
1089         struct sd *sd = (struct sd *) gspca_dev;
1090
1091         sd->autogain = val;
1092         if (val != 0)
1093                 reg_w(gspca_dev, 0xf48e);
1094         else
1095                 reg_w(gspca_dev, 0xb48e);
1096         return 0;
1097 }
1098
1099 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1100 {
1101         struct sd *sd = (struct sd *) gspca_dev;
1102
1103         *val = sd->autogain;
1104         return 0;
1105 }
1106
1107 static int sd_querymenu(struct gspca_dev *gspca_dev,
1108                         struct v4l2_querymenu *menu)
1109 {
1110         switch (menu->id) {
1111         case V4L2_CID_POWER_LINE_FREQUENCY:
1112                 switch (menu->index) {
1113                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1114                         strcpy((char *) menu->name, "50 Hz");
1115                         return 0;
1116                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1117                         strcpy((char *) menu->name, "60 Hz");
1118                         return 0;
1119                 }
1120                 break;
1121         case V4L2_CID_EFFECTS:
1122                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1123                         strncpy((char *) menu->name,
1124                                 effects_control[menu->index], 32);
1125                         return 0;
1126                 }
1127                 break;
1128         }
1129         return -EINVAL;
1130 }
1131
1132 /* sub-driver description */
1133 static const struct sd_desc sd_desc = {
1134         .name = MODULE_NAME,
1135         .ctrls = sd_ctrls,
1136         .nctrls = ARRAY_SIZE(sd_ctrls),
1137         .config = sd_config,
1138         .init = sd_init,
1139         .start = sd_start,
1140         .stopN = sd_stopN,
1141         .pkt_scan = sd_pkt_scan,
1142         .querymenu = sd_querymenu,
1143 };
1144
1145 /* -- module initialisation -- */
1146 static const __devinitdata struct usb_device_id device_table[] = {
1147         {USB_DEVICE(0x17a1, 0x0128)},
1148         {}
1149 };
1150 MODULE_DEVICE_TABLE(usb, device_table);
1151
1152 /* -- device connect -- */
1153 static int sd_probe(struct usb_interface *intf,
1154                     const struct usb_device_id *id)
1155 {
1156         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1157                                THIS_MODULE);
1158 }
1159
1160 static struct usb_driver sd_driver = {
1161         .name = MODULE_NAME,
1162         .id_table = device_table,
1163         .probe = sd_probe,
1164         .disconnect = gspca_disconnect,
1165 #ifdef CONFIG_PM
1166         .suspend = gspca_suspend,
1167         .resume = gspca_resume,
1168 #endif
1169 };
1170
1171 /* -- module insert / remove -- */
1172 static int __init sd_mod_init(void)
1173 {
1174         if (usb_register(&sd_driver) < 0)
1175                 return -1;
1176         PDEBUG(D_PROBE, "registered");
1177         return 0;
1178 }
1179 static void __exit sd_mod_exit(void)
1180 {
1181         usb_deregister(&sd_driver);
1182         PDEBUG(D_PROBE, "deregistered");
1183 }
1184
1185 module_init(sd_mod_init);
1186 module_exit(sd_mod_exit);