Merge branch 'linus' into x86/gart
[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 + 3)
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 * 3 / 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 <= sizeof gspca_dev->usb_buf) {
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 static void setbrightness(struct gspca_dev *gspca_dev)
556 {
557         struct sd *sd = (struct sd *) gspca_dev;
558         unsigned int brightness;
559         __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
560         brightness = sd->brightness;
561
562         if (brightness < 7) {
563                 set6[3] = 0x70 - (brightness * 0xa);
564         } else {
565                 set6[1] = 0x24;
566                 set6[3] = 0x00 + ((brightness - 7) * 0xa);
567         }
568
569         reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
570 }
571
572 static void setflip(struct gspca_dev *gspca_dev)
573 {
574         struct sd *sd = (struct sd *) gspca_dev;
575
576         __u8 flipcmd[8] =
577             { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
578
579         if (sd->mirror == 1)
580                 flipcmd[3] = 0x01;
581
582         reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
583 }
584
585 static void seteffect(struct gspca_dev *gspca_dev)
586 {
587         struct sd *sd = (struct sd *) gspca_dev;
588
589         reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
590         if (sd->effect == 1 || sd->effect == 5) {
591                 PDEBUG(D_CONF,
592                        "This effect have been disabled for webcam \"safety\"");
593                 return;
594         }
595
596         if (sd->effect == 1 || sd->effect == 4)
597                 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
598         else
599                 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
600 }
601
602 static void setwhitebalance(struct gspca_dev *gspca_dev)
603 {
604         struct sd *sd = (struct sd *) gspca_dev;
605
606         __u8 white_balance[8] =
607             { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
608
609         if (sd->whitebalance == 1)
610                 white_balance[7] = 0x3c;
611
612         reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
613 }
614
615 static void setlightfreq(struct gspca_dev *gspca_dev)
616 {
617         struct sd *sd = (struct sd *) gspca_dev;
618         __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
619
620         if (sd->freq == 2)      /* 60hz */
621                 freq[1] = 0x00;
622
623         reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
624 }
625
626 static void setcontrast(struct gspca_dev *gspca_dev)
627 {
628         struct sd *sd = (struct sd *) gspca_dev;
629         unsigned int contrast = sd->contrast;
630         __u16 reg_to_write = 0x00;
631
632         if (contrast < 7)
633                 reg_to_write = 0x8ea9 - (0x200 * contrast);
634         else
635                 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
636
637         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
638 }
639
640 static void setcolors(struct gspca_dev *gspca_dev)
641 {
642         struct sd *sd = (struct sd *) gspca_dev;
643         __u16 reg_to_write;
644
645         reg_to_write = 0xc0bb + sd->colors * 0x100;
646         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
647 }
648
649 static void setgamma(struct gspca_dev *gspca_dev)
650 {
651 }
652
653 static void setsharpness(struct gspca_dev *gspca_dev)
654 {
655         struct sd *sd = (struct sd *) gspca_dev;
656         __u16 reg_to_write;
657
658         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
659
660         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
661 }
662
663 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
664 {
665         struct sd *sd = (struct sd *) gspca_dev;
666
667         sd->brightness = val;
668         if (gspca_dev->streaming)
669                 setbrightness(gspca_dev);
670         return 0;
671 }
672
673 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
674 {
675         struct sd *sd = (struct sd *) gspca_dev;
676
677         *val = sd->brightness;
678         return *val;
679 }
680
681 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
682 {
683         struct sd *sd = (struct sd *) gspca_dev;
684
685         sd->whitebalance = val;
686         if (gspca_dev->streaming)
687                 setwhitebalance(gspca_dev);
688         return 0;
689 }
690
691 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
692 {
693         struct sd *sd = (struct sd *) gspca_dev;
694
695         *val = sd->whitebalance;
696         return *val;
697 }
698
699 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
700 {
701         struct sd *sd = (struct sd *) gspca_dev;
702
703         sd->mirror = val;
704         if (gspca_dev->streaming)
705                 setflip(gspca_dev);
706         return 0;
707 }
708
709 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
710 {
711         struct sd *sd = (struct sd *) gspca_dev;
712
713         *val = sd->mirror;
714         return *val;
715 }
716
717 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
718 {
719         struct sd *sd = (struct sd *) gspca_dev;
720
721         sd->effect = val;
722         if (gspca_dev->streaming)
723                 seteffect(gspca_dev);
724         return 0;
725 }
726
727 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
728 {
729         struct sd *sd = (struct sd *) gspca_dev;
730
731         *val = sd->effect;
732         return *val;
733 }
734
735 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
736 {
737         struct sd *sd = (struct sd *) gspca_dev;
738
739         sd->contrast = val;
740         if (gspca_dev->streaming)
741                 setcontrast(gspca_dev);
742         return 0;
743 }
744
745 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
746 {
747         struct sd *sd = (struct sd *) gspca_dev;
748
749         *val = sd->contrast;
750         return *val;
751 }
752
753 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
754 {
755         struct sd *sd = (struct sd *) gspca_dev;
756
757         sd->colors = val;
758         if (gspca_dev->streaming)
759                 setcolors(gspca_dev);
760         return 0;
761 }
762
763 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
764 {
765         struct sd *sd = (struct sd *) gspca_dev;
766
767         *val = sd->colors;
768         return 0;
769 }
770
771 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
772 {
773         struct sd *sd = (struct sd *) gspca_dev;
774
775         sd->gamma = val;
776         if (gspca_dev->streaming)
777                 setgamma(gspca_dev);
778         return 0;
779 }
780
781 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
782 {
783         struct sd *sd = (struct sd *) gspca_dev;
784         *val = sd->gamma;
785         return 0;
786 }
787
788 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
789 {
790         struct sd *sd = (struct sd *) gspca_dev;
791
792         sd->freq = val;
793         if (gspca_dev->streaming)
794                 setlightfreq(gspca_dev);
795         return 0;
796 }
797
798 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
799 {
800         struct sd *sd = (struct sd *) gspca_dev;
801
802         *val = sd->freq;
803         return 0;
804 }
805
806 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
807 {
808         struct sd *sd = (struct sd *) gspca_dev;
809
810         sd->sharpness = val;
811         if (gspca_dev->streaming)
812                 setsharpness(gspca_dev);
813         return 0;
814 }
815
816 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
817 {
818         struct sd *sd = (struct sd *) gspca_dev;
819
820         *val = sd->sharpness;
821         return 0;
822 }
823
824 /* Low Light set  here......*/
825 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
826 {
827         struct sd *sd = (struct sd *) gspca_dev;
828
829         sd->autogain = val;
830         if (val != 0)
831                 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
832         else
833                 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
834         return 0;
835 }
836
837 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
838 {
839         struct sd *sd = (struct sd *) gspca_dev;
840
841         *val = sd->autogain;
842         return 0;
843 }
844
845 static void sd_start(struct gspca_dev *gspca_dev)
846 {
847         int mode;
848
849         static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
850         __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
851         static const __u8 t3[] =
852                 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
853                   0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
854         static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
855
856         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
857         switch (mode) {
858         case 1:         /* 352x288 */
859                 t2[1] = 0x40;
860                 break;
861         case 2:         /* 320x240 */
862                 t2[1] = 0x10;
863                 break;
864         case 3:         /* 176x144 */
865                 t2[1] = 0x50;
866                 break;
867         case 4:         /* 160x120 */
868                 t2[1] = 0x20;
869                 break;
870         default:        /* 640x480 (0x00) */
871                 break;
872         }
873
874         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
875         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
876         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
877         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
878         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
879                 /* just in case and to keep sync with logs  (for mine) */
880         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
881         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
882                 /* just in case and to keep sync with logs  (for mine) */
883         reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
884         reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
885         reg_r_1(gspca_dev, 0x0012);
886         reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
887         reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
888         reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
889         /* restart on each start, just in case, sometimes regs goes wrong
890          * when using controls from app */
891         setbrightness(gspca_dev);
892         setcontrast(gspca_dev);
893         setcolors(gspca_dev);
894 }
895
896 static void sd_stopN(struct gspca_dev *gspca_dev)
897 {
898 }
899
900 static void sd_stop0(struct gspca_dev *gspca_dev)
901 {
902 }
903
904 static void sd_close(struct gspca_dev *gspca_dev)
905 {
906 }
907
908 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
909                         struct gspca_frame *frame,      /* target */
910                         __u8 *data,                     /* isoc packet */
911                         int len)                        /* iso packet length */
912 {
913         int sof = 0;
914         static __u8 ffd9[] = { 0xff, 0xd9 };
915
916         if (data[0] == 0x5a) {
917                 /* Control Packet, after this came the header again,
918                  * but extra bytes came in the packet before this,
919                  * sometimes an EOF arrives, sometimes not... */
920                 return;
921         }
922
923         if (data[len - 1] == 0xff && data[len] == 0xd9) {
924                 /* Just in case, i have seen packets with the marker,
925                  * other's do not include it... */
926                 data += 2;
927                 len -= 4;
928         } else if (data[2] == 0xff && data[3] == 0xd8) {
929                 sof = 1;
930                 data += 2;
931                 len -= 2;
932         } else {
933                 data += 2;
934                 len -= 2;
935         }
936
937         if (sof) {
938                 /* extra bytes....., could be processed too but would be
939                  * a waste of time, right now leave the application and
940                  * libjpeg do it for ourserlves.. */
941                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
942                                         ffd9, 2);
943                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
944                 return;
945         }
946
947         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
948 }
949
950 static int sd_querymenu(struct gspca_dev *gspca_dev,
951                         struct v4l2_querymenu *menu)
952 {
953         switch (menu->id) {
954         case V4L2_CID_POWER_LINE_FREQUENCY:
955                 switch (menu->index) {
956                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
957                         strcpy((char *) menu->name, "50 Hz");
958                         return 0;
959                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
960                         strcpy((char *) menu->name, "60 Hz");
961                         return 0;
962                 }
963                 break;
964         case V4L2_CID_EFFECTS:
965                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
966                         strncpy((char *) menu->name,
967                                 effects_control[menu->index], 32);
968                         return 0;
969                 }
970                 break;
971         }
972         return -EINVAL;
973 }
974
975 /* this function is called at open time */
976 static int sd_open(struct gspca_dev *gspca_dev)
977 {
978         init_default_parameters(gspca_dev);
979         return 0;
980 }
981
982 /* sub-driver description */
983 static const struct sd_desc sd_desc = {
984         .name = MODULE_NAME,
985         .ctrls = sd_ctrls,
986         .nctrls = ARRAY_SIZE(sd_ctrls),
987         .config = sd_config,
988         .open = sd_open,
989         .start = sd_start,
990         .stopN = sd_stopN,
991         .stop0 = sd_stop0,
992         .close = sd_close,
993         .pkt_scan = sd_pkt_scan,
994         .querymenu = sd_querymenu,
995 };
996
997 /* -- module initialisation -- */
998 static const __devinitdata struct usb_device_id device_table[] = {
999         {USB_DEVICE(0x17a1, 0x0128)},
1000         {}
1001 };
1002 MODULE_DEVICE_TABLE(usb, device_table);
1003
1004 /* -- device connect -- */
1005 static int sd_probe(struct usb_interface *intf,
1006                     const struct usb_device_id *id)
1007 {
1008         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1009                                THIS_MODULE);
1010 }
1011
1012 static struct usb_driver sd_driver = {
1013         .name = MODULE_NAME,
1014         .id_table = device_table,
1015         .probe = sd_probe,
1016         .disconnect = gspca_disconnect,
1017 };
1018
1019 /* -- module insert / remove -- */
1020 static int __init sd_mod_init(void)
1021 {
1022         if (usb_register(&sd_driver) < 0)
1023                 return -1;
1024         PDEBUG(D_PROBE, "registered");
1025         return 0;
1026 }
1027 static void __exit sd_mod_exit(void)
1028 {
1029         usb_deregister(&sd_driver);
1030         PDEBUG(D_PROBE, "deregistered");
1031 }
1032
1033 module_init(sd_mod_init);
1034 module_exit(sd_mod_exit);