]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/media/video/gspca/t613.c
8e89024b913544b060796c6798642f15347ba70b
[karo-tx-linux.git] / 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 V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
32
33 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
34 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
35 MODULE_LICENSE("GPL");
36
37 struct sd {
38         struct gspca_dev gspca_dev;     /* !! must be the first item */
39
40         u8 brightness;
41         u8 contrast;
42         u8 colors;
43         u8 autogain;
44         u8 gamma;
45         u8 sharpness;
46         u8 freq;
47         u8 whitebalance;
48         u8 mirror;
49         u8 effect;
50
51         u8 sensor;
52 #define SENSOR_TAS5130A 0
53 #define SENSOR_OM6802 1
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         {
82          {
83           .id = V4L2_CID_BRIGHTNESS,
84           .type = V4L2_CTRL_TYPE_INTEGER,
85           .name = "Brightness",
86           .minimum = 0,
87           .maximum = 14,
88           .step = 1,
89 #define BRIGHTNESS_DEF 8
90           .default_value = BRIGHTNESS_DEF,
91           },
92          .set = sd_setbrightness,
93          .get = sd_getbrightness,
94          },
95         {
96          {
97           .id = V4L2_CID_CONTRAST,
98           .type = V4L2_CTRL_TYPE_INTEGER,
99           .name = "Contrast",
100           .minimum = 0,
101           .maximum = 0x0d,
102           .step = 1,
103 #define CONTRAST_DEF 0x07
104           .default_value = CONTRAST_DEF,
105           },
106          .set = sd_setcontrast,
107          .get = sd_getcontrast,
108          },
109         {
110          {
111           .id = V4L2_CID_SATURATION,
112           .type = V4L2_CTRL_TYPE_INTEGER,
113           .name = "Color",
114           .minimum = 0,
115           .maximum = 0x0f,
116           .step = 1,
117 #define COLORS_DEF 0x05
118           .default_value = COLORS_DEF,
119           },
120          .set = sd_setcolors,
121          .get = sd_getcolors,
122          },
123 #define GAMMA_MAX 16
124 #define GAMMA_DEF 10
125         {
126          {
127           .id = V4L2_CID_GAMMA, /* (gamma on win) */
128           .type = V4L2_CTRL_TYPE_INTEGER,
129           .name = "Gamma",
130           .minimum = 0,
131           .maximum = GAMMA_MAX - 1,
132           .step = 1,
133           .default_value = GAMMA_DEF,
134           },
135          .set = sd_setgamma,
136          .get = sd_getgamma,
137          },
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 #define AUTOGAIN_DEF 0x01
149           .default_value = AUTOGAIN_DEF,
150           },
151          .set = sd_setlowlight,
152          .get = sd_getlowlight,
153          },
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 #define MIRROR_DEF 0
163           .default_value = MIRROR_DEF,
164           },
165          .set = sd_setflip,
166          .get = sd_getflip
167         },
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 #define FREQ_DEF 1
177           .default_value = FREQ_DEF,
178           },
179          .set = sd_setfreq,
180          .get = sd_getfreq},
181
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 #define WHITE_BALANCE_DEF 0
191           .default_value = WHITE_BALANCE_DEF,
192           },
193          .set = sd_setwhitebalance,
194          .get = sd_getwhitebalance
195         },
196         {
197          {
198           .id = V4L2_CID_SHARPNESS,
199           .type = V4L2_CTRL_TYPE_INTEGER,
200           .name = "Sharpness",
201           .minimum = 0,
202           .maximum = 15,
203           .step = 1,
204 #define SHARPNESS_DEF 0x06
205           .default_value = SHARPNESS_DEF,
206           },
207          .set = sd_setsharpness,
208          .get = sd_getsharpness,
209          },
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 #define EFFECTS_DEF 0
219           .default_value = EFFECTS_DEF,
220           },
221          .set = sd_seteffect,
222          .get = sd_geteffect
223         },
224 };
225
226 static char *effects_control[] = {
227         "Normal",
228         "Emboss",               /* disabled */
229         "Monochrome",
230         "Sepia",
231         "Sketch",
232         "Sun Effect",           /* disabled */
233         "Negative",
234 };
235
236 static const struct v4l2_pix_format vga_mode_t16[] = {
237         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
238                 .bytesperline = 160,
239                 .sizeimage = 160 * 120 * 4 / 8 + 590,
240                 .colorspace = V4L2_COLORSPACE_JPEG,
241                 .priv = 4},
242         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
243                 .bytesperline = 176,
244                 .sizeimage = 176 * 144 * 3 / 8 + 590,
245                 .colorspace = V4L2_COLORSPACE_JPEG,
246                 .priv = 3},
247         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
248                 .bytesperline = 320,
249                 .sizeimage = 320 * 240 * 3 / 8 + 590,
250                 .colorspace = V4L2_COLORSPACE_JPEG,
251                 .priv = 2},
252         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253                 .bytesperline = 352,
254                 .sizeimage = 352 * 288 * 3 / 8 + 590,
255                 .colorspace = V4L2_COLORSPACE_JPEG,
256                 .priv = 1},
257         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258                 .bytesperline = 640,
259                 .sizeimage = 640 * 480 * 3 / 8 + 590,
260                 .colorspace = V4L2_COLORSPACE_JPEG,
261                 .priv = 0},
262 };
263
264 /* sensor specific data */
265 struct additional_sensor_data {
266         const u8 data1[10];
267         const u8 data2[9];
268         const u8 data3[9];
269         const u8 data4[4];
270         const u8 data5[6];
271         const u8 stream[4];
272 };
273
274 const static struct additional_sensor_data sensor_data[] = {
275     {                           /* TAS5130A */
276         .data1 =
277                 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
278                  0xc8, 0xfc},
279         .data2 =
280                 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
281                  0xe0},
282         .data4 =        /* Freq (50/60Hz). Splitted for test purpose */
283                 {0x66, 0x00, 0xa8, 0xe8},
284         .data5 =
285                 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
286         .stream =
287                 {0x0b, 0x04, 0x0a, 0x40},
288     },
289     {                           /* OM6802 */
290         .data1 =
291                 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
292                  0xb3, 0xfc},
293         .data2 =
294                 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
295                  0xff},
296         .data4 =        /*Freq (50/60Hz). Splitted for test purpose */
297                 {0x66, 0xca, 0xa8, 0xf0 },
298         .data5 =        /* this could be removed later */
299                 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
300         .stream =
301                 {0x0b, 0x04, 0x0a, 0x78},
302     }
303 };
304
305 #define MAX_EFFECTS 7
306 /* easily done by soft, this table could be removed,
307  * i keep it here just in case */
308 static const u8 effects_table[MAX_EFFECTS][6] = {
309         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},   /* Normal */
310         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},   /* Repujar */
311         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},   /* Monochrome */
312         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},   /* Sepia */
313         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},   /* Croquis */
314         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},   /* Sun Effect */
315         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},   /* Negative */
316 };
317
318 static const u8 gamma_table[GAMMA_MAX][17] = {
319         {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9,        /* 0 */
320          0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
321          0xff},
322         {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad,        /* 1 */
323          0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
324          0xff},
325         {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6,        /* 2 */
326          0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
327          0xff},
328         {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e,        /* 3 */
329          0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
330          0xff},
331         {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95,        /* 4 */
332          0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
333          0xff},
334         {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87,        /* 5 */
335          0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
336          0xff},
337         {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67,        /* 6 */
338          0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
339          0xff},
340         {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70,        /* 7 */
341          0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
342          0xff},
343         {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79,        /* 8 */
344          0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
345          0xff},
346         {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84,        /* 9 */
347          0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
348          0xff},
349         {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e,        /* 10 */
350          0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
351          0xff},
352         {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B,        /* 11 */
353          0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
354          0xff},
355         {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,        /* 12 */
356          0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
357          0xff},
358         {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,        /* 13 */
359          0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
360          0xff},
361         {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,        /* 14 */
362          0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
363          0xff},
364         {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,        /* 15 */
365          0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
366          0xff}
367 };
368
369 static const u8 tas5130a_sensor_init[][8] = {
370         {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
371         {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
372         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
373         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
374         {},
375 };
376
377 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
378
379 /* read 1 byte */
380 static u8 reg_r(struct gspca_dev *gspca_dev,
381                    u16 index)
382 {
383         usb_control_msg(gspca_dev->dev,
384                         usb_rcvctrlpipe(gspca_dev->dev, 0),
385                         0,              /* request */
386                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
387                         0,              /* value */
388                         index,
389                         gspca_dev->usb_buf, 1, 500);
390         return gspca_dev->usb_buf[0];
391 }
392
393 static void reg_w(struct gspca_dev *gspca_dev,
394                   u16 index)
395 {
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_DEVICE,
400                         0, index,
401                         NULL, 0, 500);
402 }
403
404 static void reg_w_buf(struct gspca_dev *gspca_dev,
405                   const u8 *buffer, u16 len)
406 {
407         if (len <= USB_BUF_SZ) {
408                 memcpy(gspca_dev->usb_buf, 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_DEVICE,
413                                 0x01, 0,
414                                 gspca_dev->usb_buf, len, 500);
415         } else {
416                 u8 *tmpbuf;
417
418                 tmpbuf = kmalloc(len, GFP_KERNEL);
419                 memcpy(tmpbuf, buffer, len);
420                 usb_control_msg(gspca_dev->dev,
421                                 usb_sndctrlpipe(gspca_dev->dev, 0),
422                                 0,
423                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
424                                 0x01, 0,
425                                 tmpbuf, len, 500);
426                 kfree(tmpbuf);
427         }
428 }
429
430 /* write values to consecutive registers */
431 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
432                         u8 reg,
433                         const u8 *buffer, u16 len)
434 {
435         int i;
436         u8 *p, *tmpbuf;
437
438         if (len * 2 <= USB_BUF_SZ)
439                 p = tmpbuf = gspca_dev->usb_buf;
440         else
441                 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
442         i = len;
443         while (--i >= 0) {
444                 *p++ = reg++;
445                 *p++ = *buffer++;
446         }
447         usb_control_msg(gspca_dev->dev,
448                         usb_sndctrlpipe(gspca_dev->dev, 0),
449                         0,
450                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
451                         0x01, 0,
452                         tmpbuf, len * 2, 500);
453         if (len * 2 > USB_BUF_SZ)
454                 kfree(tmpbuf);
455 }
456
457 /* Reported as OM6802*/
458 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
459 {
460         int i;
461         const u8 *p;
462         u8 byte;
463         u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
464         static const u8 sensor_init[] = {
465                 0xdf, 0x6d,
466                 0xdd, 0x18,
467                 0x5a, 0xe0,
468                 0x5c, 0x07,
469                 0x5d, 0xb0,
470                 0x5e, 0x1e,
471                 0x60, 0x71,
472                 0xef, 0x00,
473                 0xe9, 0x00,
474                 0xea, 0x00,
475                 0x90, 0x24,
476                 0x91, 0xb2,
477                 0x82, 0x32,
478                 0xfd, 0x41,
479                 0x00                    /* table end */
480         };
481
482         reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
483         msleep(5);
484         i = 4;
485         while (--i > 0) {
486                 byte = reg_r(gspca_dev, 0x0060);
487                 if (!(byte & 0x01))
488                         break;
489                 msleep(100);
490         }
491         byte = reg_r(gspca_dev, 0x0063);
492         if (byte != 0x17) {
493                 err("Bad sensor reset %02x", byte);
494                 /* continue? */
495         }
496
497         p = sensor_init;
498         while (*p != 0) {
499                 val[1] = *p++;
500                 val[3] = *p++;
501                 if (*p == 0)
502                         reg_w(gspca_dev, 0x3c80);
503                 reg_w_buf(gspca_dev, val, sizeof val);
504                 i = 4;
505                 while (--i >= 0) {
506                         msleep(15);
507                         byte = reg_r(gspca_dev, 0x60);
508                         if (!(byte & 0x01))
509                                 break;
510                 }
511         }
512         msleep(15);
513         reg_w(gspca_dev, 0x3c80);
514 }
515
516 /* this function is called at probe time */
517 static int sd_config(struct gspca_dev *gspca_dev,
518                      const struct usb_device_id *id)
519 {
520         struct sd *sd = (struct sd *) gspca_dev;
521         struct cam *cam;
522
523         cam = &gspca_dev->cam;
524
525         cam->cam_mode = vga_mode_t16;
526         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
527
528         sd->brightness = BRIGHTNESS_DEF;
529         sd->contrast = CONTRAST_DEF;
530         sd->colors = COLORS_DEF;
531         sd->gamma = GAMMA_DEF;
532         sd->autogain = AUTOGAIN_DEF;
533         sd->mirror = MIRROR_DEF;
534         sd->freq = FREQ_DEF;
535         sd->whitebalance = WHITE_BALANCE_DEF;
536         sd->sharpness = SHARPNESS_DEF;
537         sd->effect = EFFECTS_DEF;
538         return 0;
539 }
540
541 static void setbrightness(struct gspca_dev *gspca_dev)
542 {
543         struct sd *sd = (struct sd *) gspca_dev;
544         unsigned int brightness;
545         u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
546
547         brightness = sd->brightness;
548         if (brightness < 7) {
549                 set6[1] = 0x26;
550                 set6[3] = 0x70 - brightness * 0x10;
551         } else {
552                 set6[3] = 0x00 + ((brightness - 7) * 0x10);
553         }
554
555         reg_w_buf(gspca_dev, set6, sizeof set6);
556 }
557
558 static void setcontrast(struct gspca_dev *gspca_dev)
559 {
560         struct sd *sd = (struct sd *) gspca_dev;
561         unsigned int contrast = sd->contrast;
562         u16 reg_to_write;
563
564         if (contrast < 7)
565                 reg_to_write = 0x8ea9 - contrast * 0x200;
566         else
567                 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
568
569         reg_w(gspca_dev, reg_to_write);
570 }
571
572 static void setcolors(struct gspca_dev *gspca_dev)
573 {
574         struct sd *sd = (struct sd *) gspca_dev;
575         u16 reg_to_write;
576
577         reg_to_write = 0x80bb + sd->colors * 0x100;     /* was 0xc0 */
578         reg_w(gspca_dev, reg_to_write);
579 }
580
581 static void setgamma(struct gspca_dev *gspca_dev)
582 {
583         struct sd *sd = (struct sd *) gspca_dev;
584
585         PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
586         reg_w_ixbuf(gspca_dev, 0x90,
587                 gamma_table[sd->gamma], sizeof gamma_table[0]);
588 }
589
590 static void setwhitebalance(struct gspca_dev *gspca_dev)
591 {
592         struct sd *sd = (struct sd *) gspca_dev;
593
594         u8 white_balance[8] =
595                 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
596
597         if (sd->whitebalance)
598                 white_balance[7] = 0x3c;
599
600         reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
601 }
602
603 static void setsharpness(struct gspca_dev *gspca_dev)
604 {
605         struct sd *sd = (struct sd *) gspca_dev;
606         u16 reg_to_write;
607
608         reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
609
610         reg_w(gspca_dev, reg_to_write);
611 }
612
613 /* this function is called at probe and resume time */
614 static int sd_init(struct gspca_dev *gspca_dev)
615 {
616         /* some of this registers are not really neded, because
617          * they are overriden by setbrigthness, setcontrast, etc,
618          * but wont hurt anyway, and can help someone with similar webcam
619          * to see the initial parameters.*/
620         struct sd *sd = (struct sd *) gspca_dev;
621         int i;
622         u8 byte, test_byte;
623
624         static const u8 read_indexs[] =
625                 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
626                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
627         static const u8 n1[] =
628                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
629         static const u8 n2[] =
630                         {0x08, 0x00};
631         static const u8 n3[] =
632                         {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
633         static const u8 n4[] =
634                 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
635                  0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
636                  0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
637                  0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
638                  0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
639                  0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
640                  0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
641                  0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
642                  0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
643         static const u8 nset8[6] =
644                         { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
645         static const u8 nset9[4] =
646                         { 0x0b, 0x04, 0x0a, 0x78 };
647
648         byte = reg_r(gspca_dev, 0x06);
649         test_byte = reg_r(gspca_dev, 0x07);
650         if (byte == 0x08 && test_byte == 0x07) {
651                 PDEBUG(D_CONF, "sensor om6802");
652                 sd->sensor = SENSOR_OM6802;
653         } else if (byte == 0x08 && test_byte == 0x01) {
654                 PDEBUG(D_CONF, "sensor tas5130a");
655                 sd->sensor = SENSOR_TAS5130A;
656         } else {
657                 PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
658                 sd->sensor = SENSOR_TAS5130A;
659         }
660
661         reg_w_buf(gspca_dev, n1, sizeof n1);
662         test_byte = 0;
663         i = 5;
664         while (--i >= 0) {
665                 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
666                 test_byte = reg_r(gspca_dev, 0x0063);
667                 msleep(100);
668                 if (test_byte == 0x17)
669                         break;          /* OK */
670         }
671         if (i < 0) {
672                 err("Bad sensor reset %02x", test_byte);
673 /*              return -EIO; */
674 /*fixme: test - continue */
675         }
676         reg_w_buf(gspca_dev, n2, sizeof n2);
677
678         i = 0;
679         while (read_indexs[i] != 0x00) {
680                 test_byte = reg_r(gspca_dev, read_indexs[i]);
681                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
682                        test_byte);
683                 i++;
684         }
685
686         reg_w_buf(gspca_dev, n3, sizeof n3);
687         reg_w_buf(gspca_dev, n4, sizeof n4);
688         reg_r(gspca_dev, 0x0080);
689         reg_w(gspca_dev, 0x2c80);
690
691         reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
692                         sizeof sensor_data[sd->sensor].data1);
693         reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
694                         sizeof sensor_data[sd->sensor].data2);
695         reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
696                         sizeof sensor_data[sd->sensor].data2);
697
698         reg_w(gspca_dev, 0x3880);
699         reg_w(gspca_dev, 0x3880);
700         reg_w(gspca_dev, 0x338e);
701
702         setbrightness(gspca_dev);
703         setcontrast(gspca_dev);
704         setgamma(gspca_dev);
705         setcolors(gspca_dev);
706         setsharpness(gspca_dev);
707         setwhitebalance(gspca_dev);
708
709         reg_w(gspca_dev, 0x2087);       /* tied to white balance? */
710         reg_w(gspca_dev, 0x2088);
711         reg_w(gspca_dev, 0x2089);
712
713         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
714                         sizeof sensor_data[sd->sensor].data4);
715         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
716                         sizeof sensor_data[sd->sensor].data5);
717         reg_w_buf(gspca_dev, nset8, sizeof nset8);
718         reg_w_buf(gspca_dev, nset9, sizeof nset9);
719
720         reg_w(gspca_dev, 0x2880);
721
722         reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
723                         sizeof sensor_data[sd->sensor].data1);
724         reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
725                         sizeof sensor_data[sd->sensor].data2);
726         reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
727                         sizeof sensor_data[sd->sensor].data2);
728
729         return 0;
730 }
731
732 static void setflip(struct gspca_dev *gspca_dev)
733 {
734         struct sd *sd = (struct sd *) gspca_dev;
735         u8 flipcmd[8] =
736                 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
737
738         if (sd->mirror)
739                 flipcmd[3] = 0x01;
740
741         reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
742 }
743
744 static void seteffect(struct gspca_dev *gspca_dev)
745 {
746         struct sd *sd = (struct sd *) gspca_dev;
747
748         reg_w_buf(gspca_dev, effects_table[sd->effect],
749                                 sizeof effects_table[0]);
750         if (sd->effect == 1 || sd->effect == 5) {
751                 PDEBUG(D_CONF,
752                        "This effect have been disabled for webcam \"safety\"");
753                 return;
754         }
755
756         if (sd->effect == 1 || sd->effect == 4)
757                 reg_w(gspca_dev, 0x4aa6);
758         else
759                 reg_w(gspca_dev, 0xfaa6);
760 }
761
762 static void setlightfreq(struct gspca_dev *gspca_dev)
763 {
764         struct sd *sd = (struct sd *) gspca_dev;
765         u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
766
767         if (sd->freq == 2)      /* 60hz */
768                 freq[1] = 0x00;
769
770         reg_w_buf(gspca_dev, freq, sizeof freq);
771 }
772
773 /* Is this really needed?
774  * i added some module parameters for test with some users */
775 static void poll_sensor(struct gspca_dev *gspca_dev)
776 {
777         struct sd *sd = (struct sd *) gspca_dev;
778         static const u8 poll1[] =
779                 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
780                  0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
781                  0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
782                  0x60, 0x14};
783         static const u8 poll2[] =
784                 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
785                  0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
786         static const u8 poll3[] =
787                 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
788         static const u8 poll4[] =
789                 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
790                  0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
791                  0xc2, 0x80, 0xc3, 0x10};
792
793         if (sd->sensor != SENSOR_TAS5130A) {
794                 PDEBUG(D_STREAM, "[Sensor requires polling]");
795                 reg_w_buf(gspca_dev, poll1, sizeof poll1);
796                 reg_w_buf(gspca_dev, poll2, sizeof poll2);
797                 reg_w_buf(gspca_dev, poll3, sizeof poll3);
798                 reg_w_buf(gspca_dev, poll4, sizeof poll4);
799         }
800 }
801
802 static int sd_start(struct gspca_dev *gspca_dev)
803 {
804         struct sd *sd = (struct sd *) gspca_dev;
805         int i, mode;
806         u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
807         static const u8 t3[] =
808                 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
809
810         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
811         switch (mode) {
812         case 0:         /* 640x480 (0x00) */
813                 break;
814         case 1:         /* 352x288 */
815                 t2[1] = 0x40;
816                 break;
817         case 2:         /* 320x240 */
818                 t2[1] = 0x10;
819                 break;
820         case 3:         /* 176x144 */
821                 t2[1] = 0x50;
822                 break;
823         default:
824 /*      case 4:          * 160x120 */
825                 t2[1] = 0x20;
826                 break;
827         }
828
829         if (sd->sensor == SENSOR_TAS5130A) {
830                 i = 0;
831                 while (tas5130a_sensor_init[i][0] != 0) {
832                         reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
833                                          sizeof tas5130a_sensor_init[0]);
834                         i++;
835                 }
836                 reg_w(gspca_dev, 0x3c80);
837                 /* just in case and to keep sync with logs (for mine) */
838                 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
839                                  sizeof tas5130a_sensor_init[0]);
840                 reg_w(gspca_dev, 0x3c80);
841         } else {
842                 om6802_sensor_init(gspca_dev);
843         }
844         reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
845                         sizeof sensor_data[sd->sensor].data4);
846         reg_r(gspca_dev, 0x0012);
847         reg_w_buf(gspca_dev, t2, sizeof t2);
848         reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
849         reg_w(gspca_dev, 0x0013);
850         msleep(15);
851         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
852                         sizeof sensor_data[sd->sensor].stream);
853         poll_sensor(gspca_dev);
854
855         /* restart on each start, just in case, sometimes regs goes wrong
856          * when using controls from app */
857         setbrightness(gspca_dev);
858         setcontrast(gspca_dev);
859         setcolors(gspca_dev);
860         return 0;
861 }
862
863 static void sd_stopN(struct gspca_dev *gspca_dev)
864 {
865         struct sd *sd = (struct sd *) gspca_dev;
866
867         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
868                         sizeof sensor_data[sd->sensor].stream);
869         msleep(20);
870         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
871                         sizeof sensor_data[sd->sensor].stream);
872         msleep(20);
873         reg_w(gspca_dev, 0x0309);
874 }
875
876 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
877                         struct gspca_frame *frame,      /* target */
878                         u8 *data,                       /* isoc packet */
879                         int len)                        /* iso packet length */
880 {
881         static u8 ffd9[] = { 0xff, 0xd9 };
882
883         if (data[0] == 0x5a) {
884                 /* Control Packet, after this came the header again,
885                  * but extra bytes came in the packet before this,
886                  * sometimes an EOF arrives, sometimes not... */
887                 return;
888         }
889         data += 2;
890         len -= 2;
891         if (data[0] == 0xff && data[1] == 0xd8) {
892                 /* extra bytes....., could be processed too but would be
893                  * a waste of time, right now leave the application and
894                  * libjpeg do it for ourserlves.. */
895                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
896                                         ffd9, 2);
897                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
898                 return;
899         }
900
901         if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
902                 /* Just in case, i have seen packets with the marker,
903                  * other's do not include it... */
904                 len -= 2;
905         }
906         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
907 }
908
909 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
910 {
911         struct sd *sd = (struct sd *) gspca_dev;
912
913         sd->brightness = val;
914         if (gspca_dev->streaming)
915                 setbrightness(gspca_dev);
916         return 0;
917 }
918
919 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
920 {
921         struct sd *sd = (struct sd *) gspca_dev;
922
923         *val = sd->brightness;
924         return *val;
925 }
926
927 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
928 {
929         struct sd *sd = (struct sd *) gspca_dev;
930
931         sd->whitebalance = val;
932         if (gspca_dev->streaming)
933                 setwhitebalance(gspca_dev);
934         return 0;
935 }
936
937 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
938 {
939         struct sd *sd = (struct sd *) gspca_dev;
940
941         *val = sd->whitebalance;
942         return *val;
943 }
944
945 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
946 {
947         struct sd *sd = (struct sd *) gspca_dev;
948
949         sd->mirror = val;
950         if (gspca_dev->streaming)
951                 setflip(gspca_dev);
952         return 0;
953 }
954
955 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
956 {
957         struct sd *sd = (struct sd *) gspca_dev;
958
959         *val = sd->mirror;
960         return *val;
961 }
962
963 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
964 {
965         struct sd *sd = (struct sd *) gspca_dev;
966
967         sd->effect = val;
968         if (gspca_dev->streaming)
969                 seteffect(gspca_dev);
970         return 0;
971 }
972
973 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
974 {
975         struct sd *sd = (struct sd *) gspca_dev;
976
977         *val = sd->effect;
978         return *val;
979 }
980
981 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
982 {
983         struct sd *sd = (struct sd *) gspca_dev;
984
985         sd->contrast = val;
986         if (gspca_dev->streaming)
987                 setcontrast(gspca_dev);
988         return 0;
989 }
990
991 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
992 {
993         struct sd *sd = (struct sd *) gspca_dev;
994
995         *val = sd->contrast;
996         return *val;
997 }
998
999 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1000 {
1001         struct sd *sd = (struct sd *) gspca_dev;
1002
1003         sd->colors = val;
1004         if (gspca_dev->streaming)
1005                 setcolors(gspca_dev);
1006         return 0;
1007 }
1008
1009 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1010 {
1011         struct sd *sd = (struct sd *) gspca_dev;
1012
1013         *val = sd->colors;
1014         return 0;
1015 }
1016
1017 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1018 {
1019         struct sd *sd = (struct sd *) gspca_dev;
1020
1021         sd->gamma = val;
1022         if (gspca_dev->streaming)
1023                 setgamma(gspca_dev);
1024         return 0;
1025 }
1026
1027 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1028 {
1029         struct sd *sd = (struct sd *) gspca_dev;
1030
1031         *val = sd->gamma;
1032         return 0;
1033 }
1034
1035 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1036 {
1037         struct sd *sd = (struct sd *) gspca_dev;
1038
1039         sd->freq = val;
1040         if (gspca_dev->streaming)
1041                 setlightfreq(gspca_dev);
1042         return 0;
1043 }
1044
1045 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1046 {
1047         struct sd *sd = (struct sd *) gspca_dev;
1048
1049         *val = sd->freq;
1050         return 0;
1051 }
1052
1053 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1054 {
1055         struct sd *sd = (struct sd *) gspca_dev;
1056
1057         sd->sharpness = val;
1058         if (gspca_dev->streaming)
1059                 setsharpness(gspca_dev);
1060         return 0;
1061 }
1062
1063 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1064 {
1065         struct sd *sd = (struct sd *) gspca_dev;
1066
1067         *val = sd->sharpness;
1068         return 0;
1069 }
1070
1071 /* Low Light set  here......*/
1072 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1073 {
1074         struct sd *sd = (struct sd *) gspca_dev;
1075
1076         sd->autogain = val;
1077         if (val != 0)
1078                 reg_w(gspca_dev, 0xf48e);
1079         else
1080                 reg_w(gspca_dev, 0xb48e);
1081         return 0;
1082 }
1083
1084 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1085 {
1086         struct sd *sd = (struct sd *) gspca_dev;
1087
1088         *val = sd->autogain;
1089         return 0;
1090 }
1091
1092 static int sd_querymenu(struct gspca_dev *gspca_dev,
1093                         struct v4l2_querymenu *menu)
1094 {
1095         switch (menu->id) {
1096         case V4L2_CID_POWER_LINE_FREQUENCY:
1097                 switch (menu->index) {
1098                 case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1099                         strcpy((char *) menu->name, "50 Hz");
1100                         return 0;
1101                 case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1102                         strcpy((char *) menu->name, "60 Hz");
1103                         return 0;
1104                 }
1105                 break;
1106         case V4L2_CID_EFFECTS:
1107                 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1108                         strncpy((char *) menu->name,
1109                                 effects_control[menu->index], 32);
1110                         return 0;
1111                 }
1112                 break;
1113         }
1114         return -EINVAL;
1115 }
1116
1117 /* sub-driver description */
1118 static const struct sd_desc sd_desc = {
1119         .name = MODULE_NAME,
1120         .ctrls = sd_ctrls,
1121         .nctrls = ARRAY_SIZE(sd_ctrls),
1122         .config = sd_config,
1123         .init = sd_init,
1124         .start = sd_start,
1125         .stopN = sd_stopN,
1126         .pkt_scan = sd_pkt_scan,
1127         .querymenu = sd_querymenu,
1128 };
1129
1130 /* -- module initialisation -- */
1131 static const __devinitdata struct usb_device_id device_table[] = {
1132         {USB_DEVICE(0x17a1, 0x0128)},
1133         {}
1134 };
1135 MODULE_DEVICE_TABLE(usb, device_table);
1136
1137 /* -- device connect -- */
1138 static int sd_probe(struct usb_interface *intf,
1139                     const struct usb_device_id *id)
1140 {
1141         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1142                                THIS_MODULE);
1143 }
1144
1145 static struct usb_driver sd_driver = {
1146         .name = MODULE_NAME,
1147         .id_table = device_table,
1148         .probe = sd_probe,
1149         .disconnect = gspca_disconnect,
1150 #ifdef CONFIG_PM
1151         .suspend = gspca_suspend,
1152         .resume = gspca_resume,
1153 #endif
1154 };
1155
1156 /* -- module insert / remove -- */
1157 static int __init sd_mod_init(void)
1158 {
1159         int ret;
1160         ret = usb_register(&sd_driver);
1161         if (ret < 0)
1162                 return ret;
1163         PDEBUG(D_PROBE, "registered");
1164         return 0;
1165 }
1166 static void __exit sd_mod_exit(void)
1167 {
1168         usb_deregister(&sd_driver);
1169         PDEBUG(D_PROBE, "deregistered");
1170 }
1171
1172 module_init(sd_mod_init);
1173 module_exit(sd_mod_exit);