V4L/DVB (8825): gspca: More controls for pac73xx and new webcam 093a:2624.
[linux-2.6] / drivers / media / video / gspca / pac7311.c
1 /*
2  *              Pixart PAC7311 library
3  *              Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 /* Some documentation about various registers as determined by trial and error.
23    When the register addresses differ between the 7202 and the 7311 the 2
24    different addresses are written as 7302addr/7311addr, when one of the 2
25    addresses is a - sign that register description is not valid for the
26    matching IC.
27
28    Register page 1:
29
30    Address      Description
31    -/0x08       Unknown compressor related, must always be 8 except when not
32                 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33    -/0x1b       Auto white balance related, bit 0 is AWB enable (inverted)
34                 bits 345 seem to toggle per color gains on/off (inverted)
35    0x78         Global control, bit 6 controls the LED (inverted)
36    -/0x80       JPEG compression ratio ? Best not touched
37
38    Register page 3/4:
39
40    Address      Description
41    0x02         Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42                 the 7302, so one of 3, 6, 9, ...
43    -/0x0f       Master gain 1-245, low value = high gain
44    0x10/-       Master gain 0-31
45    -/0x10       Another gain 0-15, limited influence (1-2x gain I guess)
46    0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47    -/0x27       Seems to toggle various gains on / off, Setting bit 7 seems to
48                 completely disable the analog amplification block. Set to 0x68
49                 for max gain, 0x14 for minimal gain.
50 */
51
52 #define MODULE_NAME "pac7311"
53
54 #include "gspca.h"
55
56 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
57 MODULE_DESCRIPTION("Pixart PAC7311");
58 MODULE_LICENSE("GPL");
59
60 /* specific webcam descriptor */
61 struct sd {
62         struct gspca_dev gspca_dev;             /* !! must be the first item */
63
64         unsigned char brightness;
65         unsigned char contrast;
66         unsigned char colors;
67         unsigned char gain;
68         unsigned char exposure;
69         unsigned char autogain;
70         __u8 hflip;
71         __u8 vflip;
72
73         __u8 sensor;
74 #define SENSOR_PAC7302 0
75 #define SENSOR_PAC7311 1
76
77         u8 sof_read;
78         u8 autogain_ignore_frames;
79
80         atomic_t avg_lum;
81 };
82
83 /* V4L2 controls supported by the driver */
84 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
97 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
98 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
100
101 static struct ctrl sd_ctrls[] = {
102 /* This control is pac7302 only */
103 #define BRIGHTNESS_IDX 0
104         {
105             {
106                 .id      = V4L2_CID_BRIGHTNESS,
107                 .type    = V4L2_CTRL_TYPE_INTEGER,
108                 .name    = "Brightness",
109                 .minimum = 0,
110 #define BRIGHTNESS_MAX 0x20
111                 .maximum = BRIGHTNESS_MAX,
112                 .step    = 1,
113 #define BRIGHTNESS_DEF 0x10
114                 .default_value = BRIGHTNESS_DEF,
115             },
116             .set = sd_setbrightness,
117             .get = sd_getbrightness,
118         },
119 /* This control is for both the 7302 and the 7311 */
120         {
121             {
122                 .id      = V4L2_CID_CONTRAST,
123                 .type    = V4L2_CTRL_TYPE_INTEGER,
124                 .name    = "Contrast",
125                 .minimum = 0,
126 #define CONTRAST_MAX 255
127                 .maximum = CONTRAST_MAX,
128                 .step    = 1,
129 #define CONTRAST_DEF 127
130                 .default_value = CONTRAST_DEF,
131             },
132             .set = sd_setcontrast,
133             .get = sd_getcontrast,
134         },
135 /* This control is pac7302 only */
136 #define SATURATION_IDX 2
137         {
138             {
139                 .id      = V4L2_CID_SATURATION,
140                 .type    = V4L2_CTRL_TYPE_INTEGER,
141                 .name    = "Saturation",
142                 .minimum = 0,
143 #define COLOR_MAX 255
144                 .maximum = COLOR_MAX,
145                 .step    = 1,
146 #define COLOR_DEF 127
147                 .default_value = COLOR_DEF,
148             },
149             .set = sd_setcolors,
150             .get = sd_getcolors,
151         },
152 /* All controls below are for both the 7302 and the 7311 */
153         {
154             {
155                 .id      = V4L2_CID_GAIN,
156                 .type    = V4L2_CTRL_TYPE_INTEGER,
157                 .name    = "Gain",
158                 .minimum = 0,
159 #define GAIN_MAX 255
160                 .maximum = GAIN_MAX,
161                 .step    = 1,
162 #define GAIN_DEF 127
163 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
164                 .default_value = GAIN_DEF,
165             },
166             .set = sd_setgain,
167             .get = sd_getgain,
168         },
169         {
170             {
171                 .id      = V4L2_CID_EXPOSURE,
172                 .type    = V4L2_CTRL_TYPE_INTEGER,
173                 .name    = "Exposure",
174                 .minimum = 0,
175 #define EXPOSURE_MAX 255
176                 .maximum = EXPOSURE_MAX,
177                 .step    = 1,
178 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
179 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
180                 .default_value = EXPOSURE_DEF,
181             },
182             .set = sd_setexposure,
183             .get = sd_getexposure,
184         },
185         {
186             {
187                 .id      = V4L2_CID_AUTOGAIN,
188                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
189                 .name    = "Auto Gain",
190                 .minimum = 0,
191                 .maximum = 1,
192                 .step    = 1,
193 #define AUTOGAIN_DEF 1
194                 .default_value = AUTOGAIN_DEF,
195             },
196             .set = sd_setautogain,
197             .get = sd_getautogain,
198         },
199         {
200             {
201                 .id      = V4L2_CID_HFLIP,
202                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
203                 .name    = "Mirror",
204                 .minimum = 0,
205                 .maximum = 1,
206                 .step    = 1,
207 #define HFLIP_DEF 0
208                 .default_value = HFLIP_DEF,
209             },
210             .set = sd_sethflip,
211             .get = sd_gethflip,
212         },
213         {
214             {
215                 .id      = V4L2_CID_VFLIP,
216                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
217                 .name    = "Vflip",
218                 .minimum = 0,
219                 .maximum = 1,
220                 .step    = 1,
221 #define VFLIP_DEF 0
222                 .default_value = VFLIP_DEF,
223             },
224             .set = sd_setvflip,
225             .get = sd_getvflip,
226         },
227 };
228
229 static struct v4l2_pix_format vga_mode[] = {
230         {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
231                 .bytesperline = 160,
232                 .sizeimage = 160 * 120 * 3 / 8 + 590,
233                 .colorspace = V4L2_COLORSPACE_JPEG,
234                 .priv = 2},
235         {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
236                 .bytesperline = 320,
237                 .sizeimage = 320 * 240 * 3 / 8 + 590,
238                 .colorspace = V4L2_COLORSPACE_JPEG,
239                 .priv = 1},
240         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
241                 .bytesperline = 640,
242                 .sizeimage = 640 * 480 * 3 / 8 + 590,
243                 .colorspace = V4L2_COLORSPACE_JPEG,
244                 .priv = 0},
245 };
246
247 /* pac 7302 */
248 static const __u8 probe_7302[] = {
249 /*      index,value */
250         0xff, 0x01,             /* page 1 */
251         0x78, 0x00,             /* deactivate */
252         0xff, 0x01,
253         0x78, 0x40,             /* led off */
254 };
255 static const __u8 start_7302[] = {
256 /*      index, len, [value]* */
257         0xff, 1,        0x00,           /* page 0 */
258         0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
259                         0x00, 0x00, 0x00, 0x00,
260         0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
261                         0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
262                         0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
263         0x26, 2,        0xaa, 0xaa,
264         0x2e, 1,        0x31,
265         0x38, 1,        0x01,
266         0x3a, 3,        0x14, 0xff, 0x5a,
267         0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
268                         0x00, 0x54, 0x11,
269         0x55, 1,        0x00,
270         0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
271         0x6b, 1,        0x00,
272         0x6e, 3,        0x08, 0x06, 0x00,
273         0x72, 3,        0x00, 0xff, 0x00,
274         0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
275                         0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
276                         0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
277         0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
278                         0xd2, 0xeb,
279         0xaf, 1,        0x02,
280         0xb5, 2,        0x08, 0x08,
281         0xb8, 2,        0x08, 0x88,
282         0xc4, 4,        0xae, 0x01, 0x04, 0x01,
283         0xcc, 1,        0x00,
284         0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
285                         0xc1, 0xd7, 0xec,
286         0xdc, 1,        0x01,
287         0xff, 1,        0x01,           /* page 1 */
288         0x12, 3,        0x02, 0x00, 0x01,
289         0x3e, 2,        0x00, 0x00,
290         0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
291         0x7c, 1,        0x00,
292         0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
293                         0x02, 0x00,
294         0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
295         0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
296                         0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
297         0xd8, 1,        0x01,
298         0xdb, 2,        0x00, 0x01,
299         0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
300         0xe6, 4,        0x00, 0x00, 0x00, 0x01,
301         0xeb, 1,        0x00,
302         0xff, 1,        0x02,           /* page 2 */
303         0x22, 1,        0x00,
304         0xff, 1,        0x03,           /* page 3 */
305         0x00, 255,                      /* load the page 3 */
306         0x11, 1,        0x01,
307         0xff, 1,        0x02,           /* page 2 */
308         0x13, 1,        0x00,
309         0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
310         0x27, 2,        0x14, 0x0c,
311         0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
312         0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
313         0x6e, 1,        0x08,
314         0xff, 1,        0x01,           /* page 1 */
315         0x78, 1,        0x00,
316         0, 0                            /* end of sequence */
317 };
318
319 /* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320 static const __u8 page3_7302[] = {
321         0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322         0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323         0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324         0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325         0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326         0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327         0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329         0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330         0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331         0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332         0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334         0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335         0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336         0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337         0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339         0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340         0x00
341 };
342
343 /* pac 7311 */
344 static const __u8 probe_7311[] = {
345         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
346         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
347         0x78, 0x44,     /* Bit_0=start stream, Bit_6=LED */
348         0xff, 0x04,
349         0x27, 0x80,
350         0x28, 0xca,
351         0x29, 0x53,
352         0x2a, 0x0e,
353         0xff, 0x01,
354         0x3e, 0x20,
355 };
356
357 static const __u8 start_7311[] = {
358 /*      index, len, [value]* */
359         0xff, 1,        0x01,           /* page 1 */
360         0x02, 43,       0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
361                         0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
362                         0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
363                         0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
364                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365                         0x00, 0x00, 0x00,
366         0x3e, 42,       0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
367                         0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
368                         0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
369                         0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
370                         0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
371                         0xd0, 0xff,
372         0x78, 6,        0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
373         0x7f, 18,       0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
374                         0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
375                         0x18, 0x20,
376         0x96, 3,        0x01, 0x08, 0x04,
377         0xa0, 4,        0x44, 0x44, 0x44, 0x04,
378         0xf0, 13,       0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379                         0x3f, 0x00, 0x0a, 0x01, 0x00,
380         0xff, 1,        0x04,           /* page 4 */
381         0x00, 254,                      /* load the page 4 */
382         0x11, 1,        0x01,
383         0, 0                            /* end of sequence */
384 };
385
386 /* page 4 - the value 0xaa says skip the index - see reg_w_page() */
387 static const __u8 page4_7311[] = {
388         0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389         0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
390         0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391         0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
392         0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
393         0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394         0x23, 0x28, 0x04, 0x11, 0x00, 0x00
395 };
396
397 static void reg_w_buf(struct gspca_dev *gspca_dev,
398                   __u8 index,
399                   const char *buffer, int len)
400 {
401         memcpy(gspca_dev->usb_buf, buffer, len);
402         usb_control_msg(gspca_dev->dev,
403                         usb_sndctrlpipe(gspca_dev->dev, 0),
404                         1,              /* request */
405                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
406                         0,              /* value */
407                         index, gspca_dev->usb_buf, len,
408                         500);
409 }
410
411
412 static void reg_w(struct gspca_dev *gspca_dev,
413                   __u8 index,
414                   __u8 value)
415 {
416         gspca_dev->usb_buf[0] = value;
417         usb_control_msg(gspca_dev->dev,
418                         usb_sndctrlpipe(gspca_dev->dev, 0),
419                         0,                      /* request */
420                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421                         0, index, gspca_dev->usb_buf, 1,
422                         500);
423 }
424
425 static void reg_w_seq(struct gspca_dev *gspca_dev,
426                 const __u8 *seq, int len)
427 {
428         while (--len >= 0) {
429                 reg_w(gspca_dev, seq[0], seq[1]);
430                 seq += 2;
431         }
432 }
433
434 /* load the beginning of a page */
435 static void reg_w_page(struct gspca_dev *gspca_dev,
436                         const __u8 *page, int len)
437 {
438         int index;
439
440         for (index = 0; index < len; index++) {
441                 if (page[index] == 0xaa)                /* skip this index */
442                         continue;
443                 gspca_dev->usb_buf[0] = page[index];
444                 usb_control_msg(gspca_dev->dev,
445                                 usb_sndctrlpipe(gspca_dev->dev, 0),
446                                 0,                      /* request */
447                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448                                 0, index, gspca_dev->usb_buf, 1,
449                                 500);
450         }
451 }
452
453 /* output a variable sequence */
454 static void reg_w_var(struct gspca_dev *gspca_dev,
455                         const __u8 *seq)
456 {
457         int index, len;
458
459         for (;;) {
460                 index = *seq++;
461                 len = *seq++;
462                 switch (len) {
463                 case 0:
464                         return;
465                 case 254:
466                         reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
467                         break;
468                 case 255:
469                         reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
470                         break;
471                 default:
472                         if (len > 64) {
473                                 PDEBUG(D_ERR|D_STREAM,
474                                         "Incorrect variable sequence");
475                                 return;
476                         }
477                         while (len > 0) {
478                                 if (len < 8) {
479                                         reg_w_buf(gspca_dev, index, seq, len);
480                                         seq += len;
481                                         break;
482                                 }
483                                 reg_w_buf(gspca_dev, index, seq, 8);
484                                 seq += 8;
485                                 index += 8;
486                                 len -= 8;
487                         }
488                 }
489         }
490         /* not reached */
491 }
492
493 /* this function is called at probe time */
494 static int sd_config(struct gspca_dev *gspca_dev,
495                         const struct usb_device_id *id)
496 {
497         struct sd *sd = (struct sd *) gspca_dev;
498         struct cam *cam;
499
500         cam = &gspca_dev->cam;
501         cam->epaddr = 0x05;
502
503         sd->sensor = id->driver_info;
504         if (sd->sensor == SENSOR_PAC7302) {
505                 PDEBUG(D_CONF, "Find Sensor PAC7302");
506                 reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302);
507
508                 cam->cam_mode = &vga_mode[2];   /* only 640x480 */
509                 cam->nmodes = 1;
510         } else {
511                 PDEBUG(D_CONF, "Find Sensor PAC7311");
512                 reg_w_seq(gspca_dev, probe_7311, sizeof probe_7311);
513
514                 cam->cam_mode = vga_mode;
515                 cam->nmodes = ARRAY_SIZE(vga_mode);
516                 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
517                                 | (1 << SATURATION_IDX);
518         }
519
520         sd->brightness = BRIGHTNESS_DEF;
521         sd->contrast = CONTRAST_DEF;
522         sd->colors = COLOR_DEF;
523         sd->gain = GAIN_DEF;
524         sd->exposure = EXPOSURE_DEF;
525         sd->autogain = AUTOGAIN_DEF;
526         sd->hflip = HFLIP_DEF;
527         sd->vflip = VFLIP_DEF;
528         return 0;
529 }
530
531 /* This function is used by pac7302 only */
532 static void setbrightcont(struct gspca_dev *gspca_dev)
533 {
534         struct sd *sd = (struct sd *) gspca_dev;
535         int i, v;
536         static const __u8 max[10] =
537                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
538                  0xd4, 0xec};
539         static const __u8 delta[10] =
540                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
541                  0x11, 0x0b};
542
543         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
544         for (i = 0; i < 10; i++) {
545                 v = max[i];
546                 v += (sd->brightness - BRIGHTNESS_MAX)
547                         * 150 / BRIGHTNESS_MAX;         /* 200 ? */
548                 v -= delta[i] * sd->contrast / CONTRAST_MAX;
549                 if (v < 0)
550                         v = 0;
551                 else if (v > 0xff)
552                         v = 0xff;
553                 reg_w(gspca_dev, 0xa2 + i, v);
554         }
555         reg_w(gspca_dev, 0xdc, 0x01);
556 }
557
558 /* This function is used by pac7311 only */
559 static void setcontrast(struct gspca_dev *gspca_dev)
560 {
561         struct sd *sd = (struct sd *) gspca_dev;
562
563         reg_w(gspca_dev, 0xff, 0x04);
564         reg_w(gspca_dev, 0x10, sd->contrast >> 4);
565         /* load registers to sensor (Bit 0, auto clear) */
566         reg_w(gspca_dev, 0x11, 0x01);
567 }
568
569 /* This function is used by pac7302 only */
570 static void setcolors(struct gspca_dev *gspca_dev)
571 {
572         struct sd *sd = (struct sd *) gspca_dev;
573         int i, v;
574         static const int a[9] =
575                 {217, -212, 0, -101, 170, -67, -38, -315, 355};
576         static const int b[9] =
577                 {19, 106, 0, 19, 106, 1, 19, 106, 1};
578
579         reg_w(gspca_dev, 0xff, 0x03);   /* page 3 */
580         reg_w(gspca_dev, 0x11, 0x01);
581         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
582         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
583         for (i = 0; i < 9; i++) {
584                 v = a[i] * sd->colors / COLOR_MAX + b[i];
585                 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
586                 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
587         }
588         reg_w(gspca_dev, 0xdc, 0x01);
589         PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
590 }
591
592 static void setgain(struct gspca_dev *gspca_dev)
593 {
594         struct sd *sd = (struct sd *) gspca_dev;
595
596         if (sd->sensor == SENSOR_PAC7302) {
597                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
598                 reg_w(gspca_dev, 0x10, sd->gain >> 3);
599         } else {
600                 int gain = GAIN_MAX - sd->gain;
601                 if (gain < 1)
602                         gain = 1;
603                 else if (gain > 245)
604                         gain = 245;
605                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
606                 reg_w(gspca_dev, 0x0e, 0x00);
607                 reg_w(gspca_dev, 0x0f, gain);
608         }
609         /* load registers to sensor (Bit 0, auto clear) */
610         reg_w(gspca_dev, 0x11, 0x01);
611 }
612
613 static void setexposure(struct gspca_dev *gspca_dev)
614 {
615         struct sd *sd = (struct sd *) gspca_dev;
616         __u8 reg;
617
618         /* register 2 of frame 3/4 contains the clock divider configuring the
619            no fps according to the formula: 60 / reg. sd->exposure is the
620            desired exposure time in ms. */
621         reg = 120 * sd->exposure / 1000;
622         if (reg < 2)
623                 reg = 2;
624         else if (reg > 63)
625                 reg = 63;
626
627         if (sd->sensor == SENSOR_PAC7302) {
628                 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
629                    the nearest multiple of 3 */
630                 reg = ((reg + 1) / 3) * 3;
631                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
632                 reg_w(gspca_dev, 0x02, reg);
633         } else {
634                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
635                 reg_w(gspca_dev, 0x02, reg);
636                 /* Page 1 register 8 must always be 0x08 except when not in
637                    640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
638                 reg_w(gspca_dev, 0xff, 0x01);
639                 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
640                                 reg <= 3)
641                         reg_w(gspca_dev, 0x08, 0x09);
642                 else
643                         reg_w(gspca_dev, 0x08, 0x08);
644         }
645         /* load registers to sensor (Bit 0, auto clear) */
646         reg_w(gspca_dev, 0x11, 0x01);
647 }
648
649 static void sethvflip(struct gspca_dev *gspca_dev)
650 {
651         struct sd *sd = (struct sd *) gspca_dev;
652         __u8 data;
653
654         if (sd->sensor == SENSOR_PAC7302) {
655                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
656                 data = (sd->hflip ? 0x08 : 0x00)
657                         | (sd->vflip ? 0x04 : 0x00);
658         } else {
659                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
660                 data = (sd->hflip ? 0x04 : 0x00)
661                         | (sd->vflip ? 0x08 : 0x00);
662         }
663         reg_w(gspca_dev, 0x21, data);
664         /* load registers to sensor (Bit 0, auto clear) */
665         reg_w(gspca_dev, 0x11, 0x01);
666 }
667
668 /* this function is called at probe and resume time */
669 static int sd_init(struct gspca_dev *gspca_dev)
670 {
671         return 0;
672 }
673
674 static void sd_start(struct gspca_dev *gspca_dev)
675 {
676         struct sd *sd = (struct sd *) gspca_dev;
677
678         sd->sof_read = 0;
679
680         if (sd->sensor == SENSOR_PAC7302) {
681                 reg_w_var(gspca_dev, start_7302);
682                 setbrightcont(gspca_dev);
683                 setcolors(gspca_dev);
684         } else {
685                 reg_w_var(gspca_dev, start_7311);
686                 setcontrast(gspca_dev);
687         }
688         setgain(gspca_dev);
689         setexposure(gspca_dev);
690         sethvflip(gspca_dev);
691
692         /* set correct resolution */
693         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
694         case 2:                                 /* 160x120 pac7311 */
695                 reg_w(gspca_dev, 0xff, 0x01);
696                 reg_w(gspca_dev, 0x17, 0x20);
697                 reg_w(gspca_dev, 0x87, 0x10);
698                 break;
699         case 1:                                 /* 320x240 pac7311 */
700                 reg_w(gspca_dev, 0xff, 0x01);
701                 reg_w(gspca_dev, 0x17, 0x30);
702                 reg_w(gspca_dev, 0x87, 0x11);
703                 break;
704         case 0:                                 /* 640x480 */
705                 if (sd->sensor == SENSOR_PAC7302)
706                         break;
707                 reg_w(gspca_dev, 0xff, 0x01);
708                 reg_w(gspca_dev, 0x17, 0x00);
709                 reg_w(gspca_dev, 0x87, 0x12);
710                 break;
711         }
712
713         sd->sof_read = 0;
714         sd->autogain_ignore_frames = 0;
715         atomic_set(&sd->avg_lum, -1);
716
717         /* start stream */
718         reg_w(gspca_dev, 0xff, 0x01);
719         if (sd->sensor == SENSOR_PAC7302)
720                 reg_w(gspca_dev, 0x78, 0x01);
721         else
722                 reg_w(gspca_dev, 0x78, 0x05);
723 }
724
725 static void sd_stopN(struct gspca_dev *gspca_dev)
726 {
727         struct sd *sd = (struct sd *) gspca_dev;
728
729         if (sd->sensor == SENSOR_PAC7302) {
730                 reg_w(gspca_dev, 0xff, 0x01);
731                 reg_w(gspca_dev, 0x78, 0x00);
732                 reg_w(gspca_dev, 0x78, 0x00);
733                 return;
734         }
735         reg_w(gspca_dev, 0xff, 0x04);
736         reg_w(gspca_dev, 0x27, 0x80);
737         reg_w(gspca_dev, 0x28, 0xca);
738         reg_w(gspca_dev, 0x29, 0x53);
739         reg_w(gspca_dev, 0x2a, 0x0e);
740         reg_w(gspca_dev, 0xff, 0x01);
741         reg_w(gspca_dev, 0x3e, 0x20);
742         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
743         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
744         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
745 }
746
747 static void sd_stop0(struct gspca_dev *gspca_dev)
748 {
749         struct sd *sd = (struct sd *) gspca_dev;
750
751         if (sd->sensor == SENSOR_PAC7302) {
752                 reg_w(gspca_dev, 0xff, 0x01);
753                 reg_w(gspca_dev, 0x78, 0x40);
754         }
755 }
756
757 /* Include pac common sof detection functions */
758 #include "pac_common.h"
759
760 static void do_autogain(struct gspca_dev *gspca_dev)
761 {
762         struct sd *sd = (struct sd *) gspca_dev;
763         int avg_lum = atomic_read(&sd->avg_lum);
764         int desired_lum;
765
766         if (avg_lum == -1)
767                 return;
768
769         if (sd->sensor == SENSOR_PAC7302)
770                 desired_lum = 70 + sd->brightness * 2;
771         else
772                 desired_lum = 200;
773
774         if (sd->autogain_ignore_frames > 0)
775                 sd->autogain_ignore_frames--;
776         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
777                         10, GAIN_KNEE, EXPOSURE_KNEE))
778                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
779 }
780
781 static const unsigned char pac7311_jpeg_header1[] = {
782   0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
783 };
784
785 static const unsigned char pac7311_jpeg_header2[] = {
786   0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
787   0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
788 };
789
790 /* this function is run at interrupt level */
791 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
792                         struct gspca_frame *frame,      /* target */
793                         __u8 *data,                     /* isoc packet */
794                         int len)                        /* iso packet length */
795 {
796         struct sd *sd = (struct sd *) gspca_dev;
797         unsigned char *sof;
798
799         sof = pac_find_sof(gspca_dev, data, len);
800         if (sof) {
801                 unsigned char tmpbuf[4];
802                 int n, lum_offset, footer_length;
803
804                 if (sd->sensor == SENSOR_PAC7302) {
805                   lum_offset = 34 + sizeof pac_sof_marker;
806                   footer_length = 74;
807                 } else {
808                   lum_offset = 24 + sizeof pac_sof_marker;
809                   footer_length = 26;
810                 }
811
812                 /* Finish decoding current frame */
813                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
814                 if (n < 0) {
815                         frame->data_end += n;
816                         n = 0;
817                 }
818                 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
819                                         data, n);
820                 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
821                                 frame->data_end[-2] == 0xff &&
822                                 frame->data_end[-1] == 0xd9)
823                         frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
824                                                 NULL, 0);
825
826                 n = sof - data;
827                 len -= n;
828                 data = sof;
829
830                 /* Get average lumination */
831                 if (gspca_dev->last_packet_type == LAST_PACKET &&
832                                 n >= lum_offset) {
833                         if (sd->sensor == SENSOR_PAC7302)
834                                 atomic_set(&sd->avg_lum,
835                                                 (data[-lum_offset] << 8) |
836                                                 data[-lum_offset + 1]);
837                         else
838                                 atomic_set(&sd->avg_lum,
839                                                 data[-lum_offset] +
840                                                 data[-lum_offset + 1]);
841                 } else {
842                         atomic_set(&sd->avg_lum, -1);
843                 }
844
845                 /* Start the new frame with the jpeg header */
846                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
847                         pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
848                 if (sd->sensor == SENSOR_PAC7302) {
849                         /* The PAC7302 has the image rotated 90 degrees */
850                         tmpbuf[0] = gspca_dev->width >> 8;
851                         tmpbuf[1] = gspca_dev->width & 0xff;
852                         tmpbuf[2] = gspca_dev->height >> 8;
853                         tmpbuf[3] = gspca_dev->height & 0xff;
854                 } else {
855                         tmpbuf[0] = gspca_dev->height >> 8;
856                         tmpbuf[1] = gspca_dev->height & 0xff;
857                         tmpbuf[2] = gspca_dev->width >> 8;
858                         tmpbuf[3] = gspca_dev->width & 0xff;
859                 }
860                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
861                 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
862                         pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
863         }
864         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
865 }
866
867 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
868 {
869         struct sd *sd = (struct sd *) gspca_dev;
870
871         sd->brightness = val;
872         if (gspca_dev->streaming)
873                 setbrightcont(gspca_dev);
874         return 0;
875 }
876
877 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
878 {
879         struct sd *sd = (struct sd *) gspca_dev;
880
881         *val = sd->brightness;
882         return 0;
883 }
884
885 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
886 {
887         struct sd *sd = (struct sd *) gspca_dev;
888
889         sd->contrast = val;
890         if (gspca_dev->streaming) {
891                 if (sd->sensor == SENSOR_PAC7302)
892                         setbrightcont(gspca_dev);
893                 else
894                         setcontrast(gspca_dev);
895         }
896         return 0;
897 }
898
899 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
900 {
901         struct sd *sd = (struct sd *) gspca_dev;
902
903         *val = sd->contrast;
904         return 0;
905 }
906
907 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
908 {
909         struct sd *sd = (struct sd *) gspca_dev;
910
911         sd->colors = val;
912         if (gspca_dev->streaming)
913                 setcolors(gspca_dev);
914         return 0;
915 }
916
917 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
918 {
919         struct sd *sd = (struct sd *) gspca_dev;
920
921         *val = sd->colors;
922         return 0;
923 }
924
925 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
926 {
927         struct sd *sd = (struct sd *) gspca_dev;
928
929         sd->gain = val;
930         if (gspca_dev->streaming)
931                 setgain(gspca_dev);
932         return 0;
933 }
934
935 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
936 {
937         struct sd *sd = (struct sd *) gspca_dev;
938
939         *val = sd->gain;
940         return 0;
941 }
942
943 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
944 {
945         struct sd *sd = (struct sd *) gspca_dev;
946
947         sd->exposure = val;
948         if (gspca_dev->streaming)
949                 setexposure(gspca_dev);
950         return 0;
951 }
952
953 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
954 {
955         struct sd *sd = (struct sd *) gspca_dev;
956
957         *val = sd->exposure;
958         return 0;
959 }
960
961 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
962 {
963         struct sd *sd = (struct sd *) gspca_dev;
964
965         sd->autogain = val;
966         /* when switching to autogain set defaults to make sure
967            we are on a valid point of the autogain gain /
968            exposure knee graph, and give this change time to
969            take effect before doing autogain. */
970         if (sd->autogain) {
971                 sd->exposure = EXPOSURE_DEF;
972                 sd->gain = GAIN_DEF;
973                 if (gspca_dev->streaming) {
974                         sd->autogain_ignore_frames =
975                                 PAC_AUTOGAIN_IGNORE_FRAMES;
976                         setexposure(gspca_dev);
977                         setgain(gspca_dev);
978                 }
979         }
980
981         return 0;
982 }
983
984 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
985 {
986         struct sd *sd = (struct sd *) gspca_dev;
987
988         *val = sd->autogain;
989         return 0;
990 }
991
992 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
993 {
994         struct sd *sd = (struct sd *) gspca_dev;
995
996         sd->hflip = val;
997         if (gspca_dev->streaming)
998                 sethvflip(gspca_dev);
999         return 0;
1000 }
1001
1002 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1003 {
1004         struct sd *sd = (struct sd *) gspca_dev;
1005
1006         *val = sd->hflip;
1007         return 0;
1008 }
1009
1010 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1011 {
1012         struct sd *sd = (struct sd *) gspca_dev;
1013
1014         sd->vflip = val;
1015         if (gspca_dev->streaming)
1016                 sethvflip(gspca_dev);
1017         return 0;
1018 }
1019
1020 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1021 {
1022         struct sd *sd = (struct sd *) gspca_dev;
1023
1024         *val = sd->vflip;
1025         return 0;
1026 }
1027
1028 /* sub-driver description */
1029 static struct sd_desc sd_desc = {
1030         .name = MODULE_NAME,
1031         .ctrls = sd_ctrls,
1032         .nctrls = ARRAY_SIZE(sd_ctrls),
1033         .config = sd_config,
1034         .init = sd_init,
1035         .start = sd_start,
1036         .stopN = sd_stopN,
1037         .stop0 = sd_stop0,
1038         .pkt_scan = sd_pkt_scan,
1039         .dq_callback = do_autogain,
1040 };
1041
1042 /* -- module initialisation -- */
1043 static __devinitdata struct usb_device_id device_table[] = {
1044         {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
1045         {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
1046         {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
1047         {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
1048         {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
1049         {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1050         {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1051         {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1052         {}
1053 };
1054 MODULE_DEVICE_TABLE(usb, device_table);
1055
1056 /* -- device connect -- */
1057 static int sd_probe(struct usb_interface *intf,
1058                         const struct usb_device_id *id)
1059 {
1060         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1061                                 THIS_MODULE);
1062 }
1063
1064 static struct usb_driver sd_driver = {
1065         .name = MODULE_NAME,
1066         .id_table = device_table,
1067         .probe = sd_probe,
1068         .disconnect = gspca_disconnect,
1069 #ifdef CONFIG_PM
1070         .suspend = gspca_suspend,
1071         .resume = gspca_resume,
1072 #endif
1073 };
1074
1075 /* -- module insert / remove -- */
1076 static int __init sd_mod_init(void)
1077 {
1078         if (usb_register(&sd_driver) < 0)
1079                 return -1;
1080         PDEBUG(D_PROBE, "registered");
1081         return 0;
1082 }
1083 static void __exit sd_mod_exit(void)
1084 {
1085         usb_deregister(&sd_driver);
1086         PDEBUG(D_PROBE, "deregistered");
1087 }
1088
1089 module_init(sd_mod_init);
1090 module_exit(sd_mod_exit);