]> err.no Git - linux-2.6/blob - drivers/media/video/gspca/t613.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[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 MAX_GAMMA 0x10          /* 0 to 15 */
32
33 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
34
35 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
36 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
37 MODULE_LICENSE("GPL");
38
39 struct sd {
40         struct gspca_dev gspca_dev;     /* !! must be the first item */
41
42         unsigned char brightness;
43         unsigned char contrast;
44         unsigned char colors;
45         unsigned char autogain;
46         unsigned char gamma;
47         unsigned char sharpness;
48         unsigned char freq;
49         unsigned char whitebalance;
50         unsigned char mirror;
51         unsigned char effect;
52 };
53
54 /* V4L2 controls supported by the driver */
55 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
56 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
57 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
58 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
59 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
60 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
61 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_querymenu(struct gspca_dev *gspca_dev,
76                         struct v4l2_querymenu *menu);
77
78 static struct ctrl sd_ctrls[] = {
79 #define SD_BRIGHTNESS 0
80         {
81          {
82           .id = V4L2_CID_BRIGHTNESS,
83           .type = V4L2_CTRL_TYPE_INTEGER,
84           .name = "Brightness",
85           .minimum = 0,
86           .maximum = 0x0f,
87           .step = 1,
88           .default_value = 0x09,
89           },
90          .set = sd_setbrightness,
91          .get = sd_getbrightness,
92          },
93 #define SD_CONTRAST 1
94         {
95          {
96           .id = V4L2_CID_CONTRAST,
97           .type = V4L2_CTRL_TYPE_INTEGER,
98           .name = "Contrast",
99           .minimum = 0,
100           .maximum = 0x0d,
101           .step = 1,
102           .default_value = 0x07,
103           },
104          .set = sd_setcontrast,
105          .get = sd_getcontrast,
106          },
107 #define SD_COLOR 2
108         {
109          {
110           .id = V4L2_CID_SATURATION,
111           .type = V4L2_CTRL_TYPE_INTEGER,
112           .name = "Color",
113           .minimum = 0,
114           .maximum = 0x0f,
115           .step = 1,
116           .default_value = 0x05,
117           },
118          .set = sd_setcolors,
119          .get = sd_getcolors,
120          },
121 #define SD_GAMMA 3
122         {
123          {
124           .id = V4L2_CID_GAMMA, /* (gamma on win) */
125           .type = V4L2_CTRL_TYPE_INTEGER,
126           .name = "Gamma (Untested)",
127           .minimum = 0,
128           .maximum = MAX_GAMMA,
129           .step = 1,
130           .default_value = 0x09,
131           },
132          .set = sd_setgamma,
133          .get = sd_getgamma,
134          },
135 #define SD_AUTOGAIN 4
136         {
137          {
138           .id = V4L2_CID_GAIN,  /* here, i activate only the lowlight,
139                                  * some apps dont bring up the
140                                  * backligth_compensation control) */
141           .type = V4L2_CTRL_TYPE_INTEGER,
142           .name = "Low Light",
143           .minimum = 0,
144           .maximum = 1,
145           .step = 1,
146           .default_value = 0x01,
147           },
148          .set = sd_setlowlight,
149          .get = sd_getlowlight,
150          },
151 #define SD_MIRROR 5
152         {
153          {
154           .id = V4L2_CID_HFLIP,
155           .type = V4L2_CTRL_TYPE_BOOLEAN,
156           .name = "Mirror Image",
157           .minimum = 0,
158           .maximum = 1,
159           .step = 1,
160           .default_value = 0,
161           },
162          .set = sd_setflip,
163          .get = sd_getflip
164         },
165 #define SD_LIGHTFREQ 6
166         {
167          {
168           .id = V4L2_CID_POWER_LINE_FREQUENCY,
169           .type = V4L2_CTRL_TYPE_MENU,
170           .name = "Light Frequency Filter",
171           .minimum = 1,         /* 1 -> 0x50, 2->0x60 */
172           .maximum = 2,
173           .step = 1,
174           .default_value = 1,
175           },
176          .set = sd_setfreq,
177          .get = sd_getfreq},
178
179 #define SD_WHITE_BALANCE 7
180         {
181          {
182           .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
183           .type = V4L2_CTRL_TYPE_INTEGER,
184           .name = "White Balance",
185           .minimum = 0,
186           .maximum = 1,
187           .step = 1,
188           .default_value = 1,
189           },
190          .set = sd_setwhitebalance,
191          .get = sd_getwhitebalance
192         },
193 #define SD_SHARPNESS 8          /* (aka definition on win) */
194         {
195          {
196           .id = V4L2_CID_SHARPNESS,
197           .type = V4L2_CTRL_TYPE_INTEGER,
198           .name = "Sharpness",
199           .minimum = 0,
200           .maximum = MAX_GAMMA, /* 0 to 16 */
201           .step = 1,
202           .default_value = 0x06,
203           },
204          .set = sd_setsharpness,
205          .get = sd_getsharpness,
206          },
207 #define SD_EFFECTS 9
208         {
209          {
210           .id = V4L2_CID_EFFECTS,
211           .type = V4L2_CTRL_TYPE_MENU,
212           .name = "Webcam Effects",
213           .minimum = 0,
214           .maximum = 4,
215           .step = 1,
216           .default_value = 0,
217           },
218          .set = sd_seteffect,
219          .get = sd_geteffect
220         },
221 };
222
223 static char *effects_control[] = {
224         "Normal",
225         "Emboss",               /* disabled */
226         "Monochrome",
227         "Sepia",
228         "Sketch",
229         "Sun Effect",           /* disabled */
230         "Negative",
231 };
232
233 static struct v4l2_pix_format vga_mode_t16[] = {
234         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
235                 .bytesperline = 160,
236                 .sizeimage = 160 * 120 * 4 / 8 + 590,
237                 .colorspace = V4L2_COLORSPACE_JPEG,
238                 .priv = 4},
239         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
240                 .bytesperline = 176,
241                 .sizeimage = 176 * 144 * 3 / 8 + 590,
242                 .colorspace = V4L2_COLORSPACE_JPEG,
243                 .priv = 3},
244         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
245                 .bytesperline = 320,
246                 .sizeimage = 320 * 240 * 3 / 8 + 590,
247                 .colorspace = V4L2_COLORSPACE_JPEG,
248                 .priv = 2},
249         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
250                 .bytesperline = 352,
251                 .sizeimage = 352 * 288 * 3 / 8 + 590,
252                 .colorspace = V4L2_COLORSPACE_JPEG,
253                 .priv = 1},
254         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
255                 .bytesperline = 640,
256                 .sizeimage = 640 * 480 * 3 / 8 + 590,
257                 .colorspace = V4L2_COLORSPACE_JPEG,
258                 .priv = 0},
259 };
260
261 #define T16_OFFSET_DATA 631
262 #define MAX_EFFECTS 7
263 /* easily done by soft, this table could be removed,
264  * i keep it here just in case */
265 static const __u8 effects_table[MAX_EFFECTS][6] = {
266         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},   /* Normal */
267         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},   /* Repujar */
268         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},   /* Monochrome */
269         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},   /* Sepia */
270         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},   /* Croquis */
271         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},   /* Sun Effect */
272         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},   /* Negative */
273 };
274
275 static const __u8 gamma_table[MAX_GAMMA][34] = {
276         {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
277          0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
278          0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
279          0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
280          0xa0, 0xff},
281         {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
282          0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
283          0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
284          0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
285          0xa0, 0xff},
286         {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
287          0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
288          0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
289          0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
290          0xa0, 0xff},
291         {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
292          0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
293          0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
294          0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
295          0xa0, 0xff},
296         {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
297          0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
298          0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
299          0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
300          0xa0, 0xff},
301         {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
302          0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
303          0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
304          0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
305          0xa0, 0xff},
306         {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
307          0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
308          0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
309          0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
310          0xa0, 0xff},
311         {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
312          0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
313          0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
314          0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
315          0xa0, 0xff},
316         {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
317          0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
318          0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
319          0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
320          0xa0, 0xff},
321         {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
322          0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
323          0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
324          0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
325          0xa0, 0xff},
326         {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
327          0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
328          0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
329          0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
330          0xa0, 0xff},
331         {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
332          0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
333          0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
334          0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
335          0xa0, 0xff},
336         {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
337          0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
338          0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
339          0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
340          0xA0, 0xFF},
341         {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
342          0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
343          0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
344          0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
345          0xa0, 0xff},
346         {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
347          0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
348          0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
349          0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
350          0xa0, 0xff},
351         {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
352          0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
353          0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
354          0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
355          0xA0, 0xFF}
356 };
357
358 static const __u8 tas5130a_sensor_init[][8] = {
359         {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
360         {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
361         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
362         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
363         {},
364 };
365
366 /* read 1 byte */
367 static int reg_r_1(struct gspca_dev *gspca_dev,
368                    __u16 index)
369 {
370         usb_control_msg(gspca_dev->dev,
371                         usb_rcvctrlpipe(gspca_dev->dev, 0),
372                         0,              /* request */
373                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
374                         0,              /* value */
375                         index,
376                         gspca_dev->usb_buf, 1, 500);
377         return gspca_dev->usb_buf[0];
378 }
379
380 static void reg_w(struct gspca_dev *gspca_dev,
381                         __u16 value,
382                         __u16 index,
383                         const __u8 *buffer, __u16 len)
384 {
385         if (buffer == NULL) {
386                 usb_control_msg(gspca_dev->dev,
387                                 usb_sndctrlpipe(gspca_dev->dev, 0),
388                                 0,
389                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
390                                 value, index,
391                                 NULL, 0, 500);
392                 return;
393         }
394         if (len <= USB_BUF_SZ) {
395                 memcpy(gspca_dev->usb_buf, buffer, len);
396                 usb_control_msg(gspca_dev->dev,
397                                 usb_sndctrlpipe(gspca_dev->dev, 0),
398                                 0,
399                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
400                                 value, index,
401                                 gspca_dev->usb_buf, len, 500);
402         } else {
403                 __u8 *tmpbuf;
404
405                 tmpbuf = kmalloc(len, GFP_KERNEL);
406                 memcpy(tmpbuf, buffer, len);
407                 usb_control_msg(gspca_dev->dev,
408                                 usb_sndctrlpipe(gspca_dev->dev, 0),
409                                 0,
410                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
411                                 value, index,
412                                 tmpbuf, len, 500);
413                 kfree(tmpbuf);
414         }
415 }
416
417 /* this function is called at probe time */
418 static int sd_config(struct gspca_dev *gspca_dev,
419                      const struct usb_device_id *id)
420 {
421         struct sd *sd = (struct sd *) gspca_dev;
422         struct cam *cam;
423
424         cam = &gspca_dev->cam;
425         cam->epaddr = 0x01;
426
427         cam->cam_mode = vga_mode_t16;
428         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
429
430         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
431         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
432         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
433         sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
434         sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
435         sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
436         sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
437         sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
438         sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
439         return 0;
440 }
441
442 static int init_default_parameters(struct gspca_dev *gspca_dev)
443 {
444         /* some of this registers are not really neded, because
445          * they are overriden by setbrigthness, setcontrast, etc,
446          * but wont hurt anyway, and can help someone with similar webcam
447          * to see the initial parameters.*/
448         int i = 0;
449         __u8 test_byte;
450
451         static const __u8 read_indexs[] =
452                 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
453                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
454         static const __u8 n1[6] =
455                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
456         static const __u8 n2[2] =
457                         {0x08, 0x00};
458         static const __u8 nset[6] =
459                 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
460         static const __u8 n3[6] =
461                         {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
462         static const __u8 n4[0x46] =
463                 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
464                  0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
465                  0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
466                  0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
467                  0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
468                  0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
469                  0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
470                  0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
471                  0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
472         static const __u8 nset4[18] = {
473                 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
474                 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
475                 0xe8, 0xe0
476         };
477         /* ojo puede ser 0xe6 en vez de 0xe9 */
478         static const __u8 nset2[20] = {
479                 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
480                 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
481                 0xd8, 0xc8, 0xd9, 0xfc
482         };
483         static const __u8 missing[8] =
484                 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
485         static const __u8 nset3[18] = {
486                 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
487                 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
488                 0xcf, 0xe0
489         };
490         static const __u8 nset5[4] =
491                 { 0x8f, 0x24, 0xc3, 0x00 };     /* bright */
492         static const __u8 nset6[34] = {
493                 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
494                 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
495                 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
496                 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
497                 0xa0, 0xff
498         };                      /* Gamma */
499         static const __u8 nset7[4] =
500                         { 0x66, 0xca, 0xa8, 0xf8 };     /* 50/60 Hz */
501         static const __u8 nset9[4] =
502                         { 0x0b, 0x04, 0x0a, 0x78 };
503         static const __u8 nset8[6] =
504                         { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
505         static const __u8 nset10[6] =
506                         { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
507
508         reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
509         reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
510         reg_r_1(gspca_dev, 0x0063);
511         reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
512
513         while (read_indexs[i] != 0x00) {
514                 test_byte = reg_r_1(gspca_dev, read_indexs[i]);
515                 PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
516                        test_byte);
517                 i++;
518         }
519
520         reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
521         reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
522         reg_r_1(gspca_dev, 0x0080);
523         reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
524         reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
525         reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
526         reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
527         reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
528         reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
529         reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
530         reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
531         reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
532         reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
533         reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
534         reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
535
536         reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
537
538         reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
539         reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
540         reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
541
542         reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
543         reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
544         reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
545         reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
546
547         reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
548         reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
549         reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
550         reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
551
552         return 0;
553 }
554
555 /* this function is called at probe and resume time */
556 static int sd_init(struct gspca_dev *gspca_dev)
557 {
558         init_default_parameters(gspca_dev);
559         return 0;
560 }
561
562 static void setbrightness(struct gspca_dev *gspca_dev)
563 {
564         struct sd *sd = (struct sd *) gspca_dev;
565         unsigned int brightness;
566         __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
567         brightness = sd->brightness;
568
569         if (brightness < 7) {
570                 set6[3] = 0x70 - (brightness * 0xa);
571         } else {
572                 set6[1] = 0x24;
573                 set6[3] = 0x00 + ((brightness - 7) * 0xa);
574         }
575
576         reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
577 }
578
579 static void setflip(struct gspca_dev *gspca_dev)
580 {
581         struct sd *sd = (struct sd *) gspca_dev;
582
583         __u8 flipcmd[8] =
584             { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
585
586         if (sd->mirror == 1)
587                 flipcmd[3] = 0x01;
588
589         reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
590 }
591
592 static void seteffect(struct gspca_dev *gspca_dev)
593 {
594         struct sd *sd = (struct sd *) gspca_dev;
595
596         reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
597         if (sd->effect == 1 || sd->effect == 5) {
598                 PDEBUG(D_CONF,
599                        "This effect have been disabled for webcam \"safety\"");
600                 return;
601         }
602
603         if (sd->effect == 1 || sd->effect == 4)
604                 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
605         else
606                 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
607 }
608
609 static void setwhitebalance(struct gspca_dev *gspca_dev)
610 {
611         struct sd *sd = (struct sd *) gspca_dev;
612
613         __u8 white_balance[8] =
614             { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
615
616         if (sd->whitebalance == 1)
617                 white_balance[7] = 0x3c;
618
619         reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
620 }
621
622 static void setlightfreq(struct gspca_dev *gspca_dev)
623 {
624         struct sd *sd = (struct sd *) gspca_dev;
625         __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
626
627         if (sd->freq == 2)      /* 60hz */
628                 freq[1] = 0x00;
629
630         reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
631 }
632
633 static void setcontrast(struct gspca_dev *gspca_dev)
634 {
635         struct sd *sd = (struct sd *) gspca_dev;
636         unsigned int contrast = sd->contrast;
637         __u16 reg_to_write = 0x00;
638
639         if (contrast < 7)
640                 reg_to_write = 0x8ea9 - (0x200 * contrast);
641         else
642                 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
643
644         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
645 }
646
647 static void setcolors(struct gspca_dev *gspca_dev)
648 {
649         struct sd *sd = (struct sd *) gspca_dev;
650         __u16 reg_to_write;
651
652         reg_to_write = 0xc0bb + sd->colors * 0x100;
653         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
654 }
655
656 static void setgamma(struct gspca_dev *gspca_dev)
657 {
658 }
659
660 static void setsharpness(struct gspca_dev *gspca_dev)
661 {
662         struct sd *sd = (struct sd *) gspca_dev;
663         __u16 reg_to_write;
664
665         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
666
667         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
668 }
669
670 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
671 {
672         struct sd *sd = (struct sd *) gspca_dev;
673
674         sd->brightness = val;
675         if (gspca_dev->streaming)
676                 setbrightness(gspca_dev);
677         return 0;
678 }
679
680 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
681 {
682         struct sd *sd = (struct sd *) gspca_dev;
683
684         *val = sd->brightness;
685         return *val;
686 }
687
688 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
689 {
690         struct sd *sd = (struct sd *) gspca_dev;
691
692         sd->whitebalance = val;
693         if (gspca_dev->streaming)
694                 setwhitebalance(gspca_dev);
695         return 0;
696 }
697
698 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
699 {
700         struct sd *sd = (struct sd *) gspca_dev;
701
702         *val = sd->whitebalance;
703         return *val;
704 }
705
706 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
707 {
708         struct sd *sd = (struct sd *) gspca_dev;
709
710         sd->mirror = val;
711         if (gspca_dev->streaming)
712                 setflip(gspca_dev);
713         return 0;
714 }
715
716 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
717 {
718         struct sd *sd = (struct sd *) gspca_dev;
719
720         *val = sd->mirror;
721         return *val;
722 }
723
724 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
725 {
726         struct sd *sd = (struct sd *) gspca_dev;
727
728         sd->effect = val;
729         if (gspca_dev->streaming)
730                 seteffect(gspca_dev);
731         return 0;
732 }
733
734 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
735 {
736         struct sd *sd = (struct sd *) gspca_dev;
737
738         *val = sd->effect;
739         return *val;
740 }
741
742 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
743 {
744         struct sd *sd = (struct sd *) gspca_dev;
745
746         sd->contrast = val;
747         if (gspca_dev->streaming)
748                 setcontrast(gspca_dev);
749         return 0;
750 }
751
752 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
753 {
754         struct sd *sd = (struct sd *) gspca_dev;
755
756         *val = sd->contrast;
757         return *val;
758 }
759
760 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
761 {
762         struct sd *sd = (struct sd *) gspca_dev;
763
764         sd->colors = val;
765         if (gspca_dev->streaming)
766                 setcolors(gspca_dev);
767         return 0;
768 }
769
770 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
771 {
772         struct sd *sd = (struct sd *) gspca_dev;
773
774         *val = sd->colors;
775         return 0;
776 }
777
778 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
779 {
780         struct sd *sd = (struct sd *) gspca_dev;
781
782         sd->gamma = val;
783         if (gspca_dev->streaming)
784                 setgamma(gspca_dev);
785         return 0;
786 }
787
788 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
789 {
790         struct sd *sd = (struct sd *) gspca_dev;
791         *val = sd->gamma;
792         return 0;
793 }
794
795 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
796 {
797         struct sd *sd = (struct sd *) gspca_dev;
798
799         sd->freq = val;
800         if (gspca_dev->streaming)
801                 setlightfreq(gspca_dev);
802         return 0;
803 }
804
805 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
806 {
807         struct sd *sd = (struct sd *) gspca_dev;
808
809         *val = sd->freq;
810         return 0;
811 }
812
813 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
814 {
815         struct sd *sd = (struct sd *) gspca_dev;
816
817         sd->sharpness = val;
818         if (gspca_dev->streaming)
819                 setsharpness(gspca_dev);
820         return 0;
821 }
822
823 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
824 {
825         struct sd *sd = (struct sd *) gspca_dev;
826
827         *val = sd->sharpness;
828         return 0;
829 }
830
831 /* Low Light set  here......*/
832 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
833 {
834         struct sd *sd = (struct sd *) gspca_dev;
835
836         sd->autogain = val;
837         if (val != 0)
838                 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
839         else
840                 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
841         return 0;
842 }
843
844 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
845 {
846         struct sd *sd = (struct sd *) gspca_dev;
847
848         *val = sd->autogain;
849         return 0;
850 }
851
852 static void sd_start(struct gspca_dev *gspca_dev)
853 {
854         int mode;
855
856         static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
857         __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
858         static const __u8 t3[] =
859                 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
860                   0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
861         static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
862
863         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
864         switch (mode) {
865         case 1:         /* 352x288 */
866                 t2[1] = 0x40;
867                 break;
868         case 2:         /* 320x240 */
869                 t2[1] = 0x10;
870                 break;
871         case 3:         /* 176x144 */
872                 t2[1] = 0x50;
873                 break;
874         case 4:         /* 160x120 */
875                 t2[1] = 0x20;
876                 break;
877         default:        /* 640x480 (0x00) */
878                 break;
879         }
880
881         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
882         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
883         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
884         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
885         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
886                 /* just in case and to keep sync with logs  (for mine) */
887         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
888         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
889                 /* just in case and to keep sync with logs  (for mine) */
890         reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
891         reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
892         reg_r_1(gspca_dev, 0x0012);
893         reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
894         reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
895         reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
896         /* restart on each start, just in case, sometimes regs goes wrong
897          * when using controls from app */
898         setbrightness(gspca_dev);
899         setcontrast(gspca_dev);
900         setcolors(gspca_dev);
901 }
902
903 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
904                         struct gspca_frame *frame,      /* target */
905                         __u8 *data,                     /* isoc packet */
906                         int len)                        /* iso packet length */
907 {
908         int sof = 0;
909         static __u8 ffd9[] = { 0xff, 0xd9 };
910
911         if (data[0] == 0x5a) {
912                 /* Control Packet, after this came the header again,
913                  * but extra bytes came in the packet before this,
914                  * sometimes an EOF arrives, sometimes not... */
915                 return;
916         }
917
918         if (data[len - 1] == 0xff && data[len] == 0xd9) {
919                 /* Just in case, i have seen packets with the marker,
920                  * other's do not include it... */
921                 data += 2;
922                 len -= 4;
923         } else if (data[2] == 0xff && data[3] == 0xd8) {
924                 sof = 1;
925                 data += 2;
926                 len -= 2;
927         } else {
928                 data += 2;
929                 len -= 2;
930         }
931
932         if (sof) {
933                 /* extra bytes....., could be processed too but would be
934                  * a waste of time, right now leave the application and
935                  * libjpeg do it for ourserlves.. */
936                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
937                                         ffd9, 2);
938                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
939                 return;
940         }
941
942         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
943 }
944
945 static int sd_querymenu(struct gspca_dev *gspca_dev,
946                         struct v4l2_querymenu *menu)
947 {
948         switch (menu->id) {
949         case V4L2_CID_POWER_LINE_FREQUENCY:
950                 switch (menu->index) {
951                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
952                         strcpy((char *) menu->name, "50 Hz");
953                         return 0;
954                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
955                         strcpy((char *) menu->name, "60 Hz");
956                         return 0;
957                 }
958                 break;
959         case V4L2_CID_EFFECTS:
960                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
961                         strncpy((char *) menu->name,
962                                 effects_control[menu->index], 32);
963                         return 0;
964                 }
965                 break;
966         }
967         return -EINVAL;
968 }
969
970 /* sub-driver description */
971 static const struct sd_desc sd_desc = {
972         .name = MODULE_NAME,
973         .ctrls = sd_ctrls,
974         .nctrls = ARRAY_SIZE(sd_ctrls),
975         .config = sd_config,
976         .init = sd_init,
977         .start = sd_start,
978         .pkt_scan = sd_pkt_scan,
979         .querymenu = sd_querymenu,
980 };
981
982 /* -- module initialisation -- */
983 static const __devinitdata struct usb_device_id device_table[] = {
984         {USB_DEVICE(0x17a1, 0x0128)},
985         {}
986 };
987 MODULE_DEVICE_TABLE(usb, device_table);
988
989 /* -- device connect -- */
990 static int sd_probe(struct usb_interface *intf,
991                     const struct usb_device_id *id)
992 {
993         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
994                                THIS_MODULE);
995 }
996
997 static struct usb_driver sd_driver = {
998         .name = MODULE_NAME,
999         .id_table = device_table,
1000         .probe = sd_probe,
1001         .disconnect = gspca_disconnect,
1002 #ifdef CONFIG_PM
1003         .suspend = gspca_suspend,
1004         .resume = gspca_resume,
1005 #endif
1006 };
1007
1008 /* -- module insert / remove -- */
1009 static int __init sd_mod_init(void)
1010 {
1011         if (usb_register(&sd_driver) < 0)
1012                 return -1;
1013         PDEBUG(D_PROBE, "registered");
1014         return 0;
1015 }
1016 static void __exit sd_mod_exit(void)
1017 {
1018         usb_deregister(&sd_driver);
1019         PDEBUG(D_PROBE, "deregistered");
1020 }
1021
1022 module_init(sd_mod_init);
1023 module_exit(sd_mod_exit);