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