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