Merge ../linux-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 + 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->dev_name = (char *) id->driver_info;
426         cam->epaddr = 0x01;
427
428         cam->cam_mode = vga_mode_t16;
429         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
430
431         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
432         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
433         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
434         sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
435         sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
436         sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
437         sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
438         sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
439         sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
440         return 0;
441 }
442
443 static int init_default_parameters(struct gspca_dev *gspca_dev)
444 {
445         /* some of this registers are not really neded, because
446          * they are overriden by setbrigthness, setcontrast, etc,
447          * but wont hurt anyway, and can help someone with similar webcam
448          * to see the initial parameters.*/
449         int i = 0;
450         __u8 test_byte;
451
452         static const __u8 read_indexs[] =
453                 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
454                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
455         static const __u8 n1[6] =
456                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
457         static const __u8 n2[2] =
458                         {0x08, 0x00};
459         static const __u8 nset[6] =
460                 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
461         static const __u8 n3[6] =
462                         {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
463         static const __u8 n4[0x46] =
464                 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
465                  0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
466                  0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
467                  0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
468                  0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
469                  0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
470                  0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
471                  0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
472                  0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
473         static const __u8 nset4[18] = {
474                 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
475                 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
476                 0xe8, 0xe0
477         };
478         /* ojo puede ser 0xe6 en vez de 0xe9 */
479         static const __u8 nset2[20] = {
480                 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
481                 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
482                 0xd8, 0xc8, 0xd9, 0xfc
483         };
484         static const __u8 missing[8] =
485                 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
486         static const __u8 nset3[18] = {
487                 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
488                 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
489                 0xcf, 0xe0
490         };
491         static const __u8 nset5[4] =
492                 { 0x8f, 0x24, 0xc3, 0x00 };     /* bright */
493         static const __u8 nset6[34] = {
494                 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
495                 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
496                 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
497                 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
498                 0xa0, 0xff
499         };                      /* Gamma */
500         static const __u8 nset7[4] =
501                         { 0x66, 0xca, 0xa8, 0xf8 };     /* 50/60 Hz */
502         static const __u8 nset9[4] =
503                         { 0x0b, 0x04, 0x0a, 0x78 };
504         static const __u8 nset8[6] =
505                         { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
506         static const __u8 nset10[6] =
507                         { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
508
509         reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
510         reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
511         reg_r_1(gspca_dev, 0x0063);
512         reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
513
514         while (read_indexs[i] != 0x00) {
515                 test_byte = reg_r_1(gspca_dev, read_indexs[i]);
516                 PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
517                        test_byte);
518                 i++;
519         }
520
521         reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
522         reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
523         reg_r_1(gspca_dev, 0x0080);
524         reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
525         reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
526         reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
527         reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
528         reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
529         reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
530         reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
531         reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
532         reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
533         reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
534         reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
535         reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
536
537         reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
538
539         reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
540         reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
541         reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
542
543         reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
544         reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
545         reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
546         reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
547
548         reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
549         reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
550         reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
551         reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
552
553         return 0;
554 }
555
556 static void setbrightness(struct gspca_dev *gspca_dev)
557 {
558         struct sd *sd = (struct sd *) gspca_dev;
559         unsigned int brightness;
560         __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
561         brightness = sd->brightness;
562
563         if (brightness < 7) {
564                 set6[3] = 0x70 - (brightness * 0xa);
565         } else {
566                 set6[1] = 0x24;
567                 set6[3] = 0x00 + ((brightness - 7) * 0xa);
568         }
569
570         reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
571 }
572
573 static void setflip(struct gspca_dev *gspca_dev)
574 {
575         struct sd *sd = (struct sd *) gspca_dev;
576
577         __u8 flipcmd[8] =
578             { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
579
580         if (sd->mirror == 1)
581                 flipcmd[3] = 0x01;
582
583         reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
584 }
585
586 static void seteffect(struct gspca_dev *gspca_dev)
587 {
588         struct sd *sd = (struct sd *) gspca_dev;
589
590         reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
591         if (sd->effect == 1 || sd->effect == 5) {
592                 PDEBUG(D_CONF,
593                        "This effect have been disabled for webcam \"safety\"");
594                 return;
595         }
596
597         if (sd->effect == 1 || sd->effect == 4)
598                 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
599         else
600                 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
601 }
602
603 static void setwhitebalance(struct gspca_dev *gspca_dev)
604 {
605         struct sd *sd = (struct sd *) gspca_dev;
606
607         __u8 white_balance[8] =
608             { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
609
610         if (sd->whitebalance == 1)
611                 white_balance[7] = 0x3c;
612
613         reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
614 }
615
616 static void setlightfreq(struct gspca_dev *gspca_dev)
617 {
618         struct sd *sd = (struct sd *) gspca_dev;
619         __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
620
621         if (sd->freq == 2)      /* 60hz */
622                 freq[1] = 0x00;
623
624         reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
625 }
626
627 static void setcontrast(struct gspca_dev *gspca_dev)
628 {
629         struct sd *sd = (struct sd *) gspca_dev;
630         unsigned int contrast = sd->contrast;
631         __u16 reg_to_write = 0x00;
632
633         if (contrast < 7)
634                 reg_to_write = 0x8ea9 - (0x200 * contrast);
635         else
636                 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
637
638         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
639 }
640
641 static void setcolors(struct gspca_dev *gspca_dev)
642 {
643         struct sd *sd = (struct sd *) gspca_dev;
644         __u16 reg_to_write;
645
646         reg_to_write = 0xc0bb + sd->colors * 0x100;
647         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
648 }
649
650 static void setgamma(struct gspca_dev *gspca_dev)
651 {
652 }
653
654 static void setsharpness(struct gspca_dev *gspca_dev)
655 {
656         struct sd *sd = (struct sd *) gspca_dev;
657         __u16 reg_to_write;
658
659         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
660
661         reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
662 }
663
664 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
665 {
666         struct sd *sd = (struct sd *) gspca_dev;
667
668         sd->brightness = val;
669         if (gspca_dev->streaming)
670                 setbrightness(gspca_dev);
671         return 0;
672 }
673
674 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
675 {
676         struct sd *sd = (struct sd *) gspca_dev;
677
678         *val = sd->brightness;
679         return *val;
680 }
681
682 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
683 {
684         struct sd *sd = (struct sd *) gspca_dev;
685
686         sd->whitebalance = val;
687         if (gspca_dev->streaming)
688                 setwhitebalance(gspca_dev);
689         return 0;
690 }
691
692 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
693 {
694         struct sd *sd = (struct sd *) gspca_dev;
695
696         *val = sd->whitebalance;
697         return *val;
698 }
699
700 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
701 {
702         struct sd *sd = (struct sd *) gspca_dev;
703
704         sd->mirror = val;
705         if (gspca_dev->streaming)
706                 setflip(gspca_dev);
707         return 0;
708 }
709
710 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
711 {
712         struct sd *sd = (struct sd *) gspca_dev;
713
714         *val = sd->mirror;
715         return *val;
716 }
717
718 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
719 {
720         struct sd *sd = (struct sd *) gspca_dev;
721
722         sd->effect = val;
723         if (gspca_dev->streaming)
724                 seteffect(gspca_dev);
725         return 0;
726 }
727
728 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
729 {
730         struct sd *sd = (struct sd *) gspca_dev;
731
732         *val = sd->effect;
733         return *val;
734 }
735
736 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
737 {
738         struct sd *sd = (struct sd *) gspca_dev;
739
740         sd->contrast = val;
741         if (gspca_dev->streaming)
742                 setcontrast(gspca_dev);
743         return 0;
744 }
745
746 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
747 {
748         struct sd *sd = (struct sd *) gspca_dev;
749
750         *val = sd->contrast;
751         return *val;
752 }
753
754 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
755 {
756         struct sd *sd = (struct sd *) gspca_dev;
757
758         sd->colors = val;
759         if (gspca_dev->streaming)
760                 setcolors(gspca_dev);
761         return 0;
762 }
763
764 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
765 {
766         struct sd *sd = (struct sd *) gspca_dev;
767
768         *val = sd->colors;
769         return 0;
770 }
771
772 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
773 {
774         struct sd *sd = (struct sd *) gspca_dev;
775
776         sd->gamma = val;
777         if (gspca_dev->streaming)
778                 setgamma(gspca_dev);
779         return 0;
780 }
781
782 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
783 {
784         struct sd *sd = (struct sd *) gspca_dev;
785         *val = sd->gamma;
786         return 0;
787 }
788
789 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
790 {
791         struct sd *sd = (struct sd *) gspca_dev;
792
793         sd->freq = val;
794         if (gspca_dev->streaming)
795                 setlightfreq(gspca_dev);
796         return 0;
797 }
798
799 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
800 {
801         struct sd *sd = (struct sd *) gspca_dev;
802
803         *val = sd->freq;
804         return 0;
805 }
806
807 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
808 {
809         struct sd *sd = (struct sd *) gspca_dev;
810
811         sd->sharpness = val;
812         if (gspca_dev->streaming)
813                 setsharpness(gspca_dev);
814         return 0;
815 }
816
817 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
818 {
819         struct sd *sd = (struct sd *) gspca_dev;
820
821         *val = sd->sharpness;
822         return 0;
823 }
824
825 /* Low Light set  here......*/
826 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
827 {
828         struct sd *sd = (struct sd *) gspca_dev;
829
830         sd->autogain = val;
831         if (val != 0)
832                 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
833         else
834                 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
835         return 0;
836 }
837
838 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
839 {
840         struct sd *sd = (struct sd *) gspca_dev;
841
842         *val = sd->autogain;
843         return 0;
844 }
845
846 static void sd_start(struct gspca_dev *gspca_dev)
847 {
848         int mode;
849
850         static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
851         __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
852         static const __u8 t3[] =
853                 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
854                   0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
855         static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
856
857         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
858         switch (mode) {
859         case 1:         /* 352x288 */
860                 t2[1] = 0x40;
861                 break;
862         case 2:         /* 320x240 */
863                 t2[1] = 0x10;
864                 break;
865         case 3:         /* 176x144 */
866                 t2[1] = 0x50;
867                 break;
868         case 4:         /* 160x120 */
869                 t2[1] = 0x20;
870                 break;
871         default:        /* 640x480 (0x00) */
872                 break;
873         }
874
875         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
876         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
877         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
878         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
879         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
880                 /* just in case and to keep sync with logs  (for mine) */
881         reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
882         reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
883                 /* just in case and to keep sync with logs  (for mine) */
884         reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
885         reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
886         reg_r_1(gspca_dev, 0x0012);
887         reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
888         reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
889         reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
890         /* restart on each start, just in case, sometimes regs goes wrong
891          * when using controls from app */
892         setbrightness(gspca_dev);
893         setcontrast(gspca_dev);
894         setcolors(gspca_dev);
895 }
896
897 static void sd_stopN(struct gspca_dev *gspca_dev)
898 {
899 }
900
901 static void sd_stop0(struct gspca_dev *gspca_dev)
902 {
903 }
904
905 static void sd_close(struct gspca_dev *gspca_dev)
906 {
907 }
908
909 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
910                         struct gspca_frame *frame,      /* target */
911                         __u8 *data,                     /* isoc packet */
912                         int len)                        /* iso packet length */
913 {
914         int sof = 0;
915         static __u8 ffd9[] = { 0xff, 0xd9 };
916
917         if (data[0] == 0x5a) {
918                 /* Control Packet, after this came the header again,
919                  * but extra bytes came in the packet before this,
920                  * sometimes an EOF arrives, sometimes not... */
921                 return;
922         }
923
924         if (data[len - 1] == 0xff && data[len] == 0xd9) {
925                 /* Just in case, i have seen packets with the marker,
926                  * other's do not include it... */
927                 data += 2;
928                 len -= 4;
929         } else if (data[2] == 0xff && data[3] == 0xd8) {
930                 sof = 1;
931                 data += 2;
932                 len -= 2;
933         } else {
934                 data += 2;
935                 len -= 2;
936         }
937
938         if (sof) {
939                 /* extra bytes....., could be processed too but would be
940                  * a waste of time, right now leave the application and
941                  * libjpeg do it for ourserlves.. */
942                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
943                                         ffd9, 2);
944                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
945                 return;
946         }
947
948         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
949 }
950
951 static int sd_querymenu(struct gspca_dev *gspca_dev,
952                         struct v4l2_querymenu *menu)
953 {
954         switch (menu->id) {
955         case V4L2_CID_POWER_LINE_FREQUENCY:
956                 switch (menu->index) {
957                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
958                         strcpy((char *) menu->name, "50 Hz");
959                         return 0;
960                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
961                         strcpy((char *) menu->name, "60 Hz");
962                         return 0;
963                 }
964                 break;
965         case V4L2_CID_EFFECTS:
966                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
967                         strncpy((char *) menu->name,
968                                 effects_control[menu->index], 32);
969                         return 0;
970                 }
971                 break;
972         }
973         return -EINVAL;
974 }
975
976 /* this function is called at open time */
977 static int sd_open(struct gspca_dev *gspca_dev)
978 {
979         init_default_parameters(gspca_dev);
980         return 0;
981 }
982
983 /* sub-driver description */
984 static const struct sd_desc sd_desc = {
985         .name = MODULE_NAME,
986         .ctrls = sd_ctrls,
987         .nctrls = ARRAY_SIZE(sd_ctrls),
988         .config = sd_config,
989         .open = sd_open,
990         .start = sd_start,
991         .stopN = sd_stopN,
992         .stop0 = sd_stop0,
993         .close = sd_close,
994         .pkt_scan = sd_pkt_scan,
995         .querymenu = sd_querymenu,
996 };
997
998 /* -- module initialisation -- */
999 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1000 static const __devinitdata struct usb_device_id device_table[] = {
1001         {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
1002         {}
1003 };
1004 MODULE_DEVICE_TABLE(usb, device_table);
1005
1006 /* -- device connect -- */
1007 static int sd_probe(struct usb_interface *intf,
1008                     const struct usb_device_id *id)
1009 {
1010         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1011                                THIS_MODULE);
1012 }
1013
1014 static struct usb_driver sd_driver = {
1015         .name = MODULE_NAME,
1016         .id_table = device_table,
1017         .probe = sd_probe,
1018         .disconnect = gspca_disconnect,
1019 };
1020
1021 /* -- module insert / remove -- */
1022 static int __init sd_mod_init(void)
1023 {
1024         if (usb_register(&sd_driver) < 0)
1025                 return -1;
1026         PDEBUG(D_PROBE, "registered");
1027         return 0;
1028 }
1029 static void __exit sd_mod_exit(void)
1030 {
1031         usb_deregister(&sd_driver);
1032         PDEBUG(D_PROBE, "deregistered");
1033 }
1034
1035 module_init(sd_mod_init);
1036 module_exit(sd_mod_exit);