bed04cc9a58430a5aef5dafb82befe8173074363
[pandora-kernel.git] / 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 */
48
49 #define MODULE_NAME "pac7311"
50
51 #include "gspca.h"
52
53 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
54 MODULE_DESCRIPTION("Pixart PAC7311");
55 MODULE_LICENSE("GPL");
56
57 /* specific webcam descriptor */
58 struct sd {
59         struct gspca_dev gspca_dev;             /* !! must be the first item */
60
61         unsigned char brightness;
62         unsigned char contrast;
63         unsigned char colors;
64         unsigned char autogain;
65         __u8 hflip;
66         __u8 vflip;
67
68         __u8 sensor;
69 #define SENSOR_PAC7302 0
70 #define SENSOR_PAC7311 1
71
72         u8 sof_read;
73         u8 header_read;
74         u8 autogain_ignore_frames;
75
76         atomic_t avg_lum;
77 };
78
79 /* V4L2 controls supported by the driver */
80 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
81 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
82 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
92
93 static struct ctrl sd_ctrls[] = {
94         {
95             {
96                 .id      = V4L2_CID_BRIGHTNESS,
97                 .type    = V4L2_CTRL_TYPE_INTEGER,
98                 .name    = "Brightness",
99                 .minimum = 0,
100 #define BRIGHTNESS_MAX 0x20
101                 .maximum = BRIGHTNESS_MAX,
102                 .step    = 1,
103 #define BRIGHTNESS_DEF 0x10
104                 .default_value = BRIGHTNESS_DEF,
105             },
106             .set = sd_setbrightness,
107             .get = sd_getbrightness,
108         },
109         {
110             {
111                 .id      = V4L2_CID_CONTRAST,
112                 .type    = V4L2_CTRL_TYPE_INTEGER,
113                 .name    = "Contrast",
114                 .minimum = 0,
115 #define CONTRAST_MAX 255
116                 .maximum = CONTRAST_MAX,
117                 .step    = 1,
118 #define CONTRAST_DEF 127
119                 .default_value = CONTRAST_DEF,
120             },
121             .set = sd_setcontrast,
122             .get = sd_getcontrast,
123         },
124         {
125             {
126                 .id      = V4L2_CID_SATURATION,
127                 .type    = V4L2_CTRL_TYPE_INTEGER,
128                 .name    = "Saturation",
129                 .minimum = 0,
130 #define COLOR_MAX 255
131                 .maximum = COLOR_MAX,
132                 .step    = 1,
133 #define COLOR_DEF 127
134                 .default_value = COLOR_DEF,
135             },
136             .set = sd_setcolors,
137             .get = sd_getcolors,
138         },
139         {
140             {
141                 .id      = V4L2_CID_AUTOGAIN,
142                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
143                 .name    = "Auto Gain",
144                 .minimum = 0,
145                 .maximum = 1,
146                 .step    = 1,
147 #define AUTOGAIN_DEF 1
148                 .default_value = AUTOGAIN_DEF,
149             },
150             .set = sd_setautogain,
151             .get = sd_getautogain,
152         },
153 /* next controls work with pac7302 only */
154         {
155             {
156                 .id      = V4L2_CID_HFLIP,
157                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
158                 .name    = "Mirror",
159                 .minimum = 0,
160                 .maximum = 1,
161                 .step    = 1,
162 #define HFLIP_DEF 0
163                 .default_value = HFLIP_DEF,
164             },
165             .set = sd_sethflip,
166             .get = sd_gethflip,
167         },
168         {
169             {
170                 .id      = V4L2_CID_VFLIP,
171                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
172                 .name    = "Vflip",
173                 .minimum = 0,
174                 .maximum = 1,
175                 .step    = 1,
176 #define VFLIP_DEF 0
177                 .default_value = VFLIP_DEF,
178             },
179             .set = sd_setvflip,
180             .get = sd_getvflip,
181         },
182 };
183
184 static struct v4l2_pix_format vga_mode[] = {
185         {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
186                 .bytesperline = 160,
187                 .sizeimage = 160 * 120 * 3 / 8 + 590,
188                 .colorspace = V4L2_COLORSPACE_JPEG,
189                 .priv = 2},
190         {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
191                 .bytesperline = 320,
192                 .sizeimage = 320 * 240 * 3 / 8 + 590,
193                 .colorspace = V4L2_COLORSPACE_JPEG,
194                 .priv = 1},
195         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
196                 .bytesperline = 640,
197                 .sizeimage = 640 * 480 * 3 / 8 + 590,
198                 .colorspace = V4L2_COLORSPACE_JPEG,
199                 .priv = 0},
200 };
201
202 /* pac 7302 */
203 static const __u8 probe_7302[] = {
204 /*      index,value */
205         0xff, 0x01,             /* page 1 */
206         0x78, 0x00,             /* deactivate */
207         0xff, 0x01,
208         0x78, 0x40,             /* led off */
209 };
210 static const __u8 start_7302[] = {
211 /*      index, len, [value]* */
212         0xff, 1,        0x00,           /* page 0 */
213         0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
214                         0x00, 0x00, 0x00, 0x00,
215         0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
216                         0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
217                         0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
218         0x26, 2,        0xaa, 0xaa,
219         0x2e, 1,        0x31,
220         0x38, 1,        0x01,
221         0x3a, 3,        0x14, 0xff, 0x5a,
222         0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
223                         0x00, 0x54, 0x11,
224         0x55, 1,        0x00,
225         0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
226         0x6b, 1,        0x00,
227         0x6e, 3,        0x08, 0x06, 0x00,
228         0x72, 3,        0x00, 0xff, 0x00,
229         0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
230                         0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
231                         0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
232         0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
233                         0xd2, 0xeb,
234         0xaf, 1,        0x02,
235         0xb5, 2,        0x08, 0x08,
236         0xb8, 2,        0x08, 0x88,
237         0xc4, 4,        0xae, 0x01, 0x04, 0x01,
238         0xcc, 1,        0x00,
239         0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
240                         0xc1, 0xd7, 0xec,
241         0xdc, 1,        0x01,
242         0xff, 1,        0x01,           /* page 1 */
243         0x12, 3,        0x02, 0x00, 0x01,
244         0x3e, 2,        0x00, 0x00,
245         0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
246         0x7c, 1,        0x00,
247         0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
248                         0x02, 0x00,
249         0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
250         0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
251                         0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
252         0xd8, 1,        0x01,
253         0xdb, 2,        0x00, 0x01,
254         0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
255         0xe6, 4,        0x00, 0x00, 0x00, 0x01,
256         0xeb, 1,        0x00,
257         0xff, 1,        0x02,           /* page 2 */
258         0x22, 1,        0x00,
259         0xff, 1,        0x03,           /* page 3 */
260         0x00, 255,                      /* load the page 3 */
261         0x11, 1,        0x01,
262         0xff, 1,        0x02,           /* page 2 */
263         0x13, 1,        0x00,
264         0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
265         0x27, 2,        0x14, 0x0c,
266         0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
267         0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
268         0x6e, 1,        0x08,
269         0xff, 1,        0x01,           /* page 1 */
270         0x78, 1,        0x00,
271         0, 0                            /* end of sequence */
272 };
273
274 /* page 3 - the value 0xaa says skip the index - see reg_w_page() */
275 static const __u8 page3_7302[] = {
276         0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
277         0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
278         0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279         0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
280         0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
281         0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
282         0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
283         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284         0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
285         0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
286         0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287         0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
288         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289         0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
290         0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
291         0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
292         0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
293         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294         0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
295         0x00
296 };
297
298 /* pac 7311 */
299 static const __u8 probe_7311[] = {
300         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
301         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
302         0x78, 0x44,     /* Bit_0=start stream, Bit_6=LED */
303         0xff, 0x04,
304         0x27, 0x80,
305         0x28, 0xca,
306         0x29, 0x53,
307         0x2a, 0x0e,
308         0xff, 0x01,
309         0x3e, 0x20,
310 };
311
312 static const __u8 start_7311[] = {
313 /*      index, len, [value]* */
314         0xff, 1,        0x01,           /* page 1 */
315         0x02, 43,       0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
316                         0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
317                         0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
318                         0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
319                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320                         0x00, 0x00, 0x00,
321         0x3e, 42,       0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
322                         0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
323                         0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
324                         0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
325                         0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
326                         0xd0, 0xff,
327         0x78, 6,        0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
328         0x7f, 18,       0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
329                         0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
330                         0x18, 0x20,
331         0x96, 3,        0x01, 0x08, 0x04,
332         0xa0, 4,        0x44, 0x44, 0x44, 0x04,
333         0xf0, 13,       0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
334                         0x3f, 0x00, 0x0a, 0x01, 0x00,
335         0xff, 1,        0x04,           /* page 4 */
336         0x00, 254,                      /* load the page 4 */
337         0x11, 1,        0x01,
338         0, 0                            /* end of sequence */
339 };
340
341 /* page 4 - the value 0xaa says skip the index - see reg_w_page() */
342 static const __u8 page4_7311[] = {
343         0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
344         0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
345         0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
346         0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
347         0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x01,
348         0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
349         0x23, 0x28, 0x04, 0x11, 0x00, 0x00
350 };
351
352 static void reg_w_buf(struct gspca_dev *gspca_dev,
353                   __u8 index,
354                   const char *buffer, int len)
355 {
356         memcpy(gspca_dev->usb_buf, buffer, len);
357         usb_control_msg(gspca_dev->dev,
358                         usb_sndctrlpipe(gspca_dev->dev, 0),
359                         1,              /* request */
360                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
361                         0,              /* value */
362                         index, gspca_dev->usb_buf, len,
363                         500);
364 }
365
366
367 static void reg_w(struct gspca_dev *gspca_dev,
368                   __u8 index,
369                   __u8 value)
370 {
371         gspca_dev->usb_buf[0] = value;
372         usb_control_msg(gspca_dev->dev,
373                         usb_sndctrlpipe(gspca_dev->dev, 0),
374                         0,                      /* request */
375                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
376                         value, index, gspca_dev->usb_buf, 1,
377                         500);
378 }
379
380 static void reg_w_seq(struct gspca_dev *gspca_dev,
381                 const __u8 *seq, int len)
382 {
383         while (--len >= 0) {
384                 reg_w(gspca_dev, seq[0], seq[1]);
385                 seq += 2;
386         }
387 }
388
389 /* load the beginning of a page */
390 static void reg_w_page(struct gspca_dev *gspca_dev,
391                         const __u8 *page, int len)
392 {
393         int index;
394
395         for (index = 0; index < len; index++) {
396                 if (page[index] == 0xaa)                /* skip this index */
397                         continue;
398                 gspca_dev->usb_buf[0] = page[index];
399                 usb_control_msg(gspca_dev->dev,
400                                 usb_sndctrlpipe(gspca_dev->dev, 0),
401                                 0,                      /* request */
402                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
403                                 0, index, gspca_dev->usb_buf, 1,
404                                 500);
405         }
406 }
407
408 /* output a variable sequence */
409 static void reg_w_var(struct gspca_dev *gspca_dev,
410                         const __u8 *seq)
411 {
412         int index, len;
413
414         for (;;) {
415                 index = *seq++;
416                 len = *seq++;
417                 switch (len) {
418                 case 0:
419                         return;
420                 case 254:
421                         reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
422                         break;
423                 case 255:
424                         reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
425                         break;
426                 default:
427                         if (len > 64) {
428                                 PDEBUG(D_ERR|D_STREAM,
429                                         "Incorrect variable sequence");
430                                 return;
431                         }
432                         while (len > 0) {
433                                 if (len < 8) {
434                                         reg_w_buf(gspca_dev, index, seq, len);
435                                         seq += len;
436                                         break;
437                                 }
438                                 reg_w_buf(gspca_dev, index, seq, 8);
439                                 seq += 8;
440                                 index += 8;
441                                 len -= 8;
442                         }
443                 }
444         }
445         /* not reached */
446 }
447
448 /* this function is called at probe time */
449 static int sd_config(struct gspca_dev *gspca_dev,
450                         const struct usb_device_id *id)
451 {
452         struct sd *sd = (struct sd *) gspca_dev;
453         struct cam *cam;
454
455         cam = &gspca_dev->cam;
456         cam->epaddr = 0x05;
457
458         sd->sensor = id->driver_info;
459         if (sd->sensor == SENSOR_PAC7302) {
460                 PDEBUG(D_CONF, "Find Sensor PAC7302");
461                 reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302);
462
463                 cam->cam_mode = &vga_mode[2];   /* only 640x480 */
464                 cam->nmodes = 1;
465         } else {
466                 PDEBUG(D_CONF, "Find Sensor PAC7311");
467                 reg_w_seq(gspca_dev, probe_7311, sizeof probe_7311);
468
469                 cam->cam_mode = vga_mode;
470                 cam->nmodes = ARRAY_SIZE(vga_mode);
471         }
472
473         sd->brightness = BRIGHTNESS_DEF;
474         sd->contrast = CONTRAST_DEF;
475         sd->colors = COLOR_DEF;
476         sd->autogain = AUTOGAIN_DEF;
477         sd->hflip = HFLIP_DEF;
478         sd->vflip = VFLIP_DEF;
479         return 0;
480 }
481
482 /* rev 12a only */
483 static void setbrightcont(struct gspca_dev *gspca_dev)
484 {
485         struct sd *sd = (struct sd *) gspca_dev;
486         int i, v;
487         static const __u8 max[10] =
488                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
489                  0xd4, 0xec};
490         static const __u8 delta[10] =
491                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
492                  0x11, 0x0b};
493
494         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
495         for (i = 0; i < 10; i++) {
496                 v = max[i];
497                 v += (sd->brightness - BRIGHTNESS_MAX)
498                         * 150 / BRIGHTNESS_MAX;         /* 200 ? */
499                 v -= delta[i] * sd->contrast / CONTRAST_MAX;
500                 if (v < 0)
501                         v = 0;
502                 else if (v > 0xff)
503                         v = 0xff;
504                 reg_w(gspca_dev, 0xa2 + i, v);
505         }
506         reg_w(gspca_dev, 0xdc, 0x01);
507 }
508
509 /* This function is used by pac7302 only */
510 static void setbrightness(struct gspca_dev *gspca_dev)
511 {
512         struct sd *sd = (struct sd *) gspca_dev;
513         int brightness;
514
515         if (sd->sensor == SENSOR_PAC7302) {
516                 setbrightcont(gspca_dev);
517                 return;
518         }
519 /* HDG: this is not brightness but gain, I'll add gain and exposure controls
520    in a next patch */
521         return;
522
523         brightness = BRIGHTNESS_MAX - sd->brightness;
524         reg_w(gspca_dev, 0xff, 0x04);
525         reg_w(gspca_dev, 0x0e, 0x00);
526         reg_w(gspca_dev, 0x0f, brightness);
527         /* load registers to sensor (Bit 0, auto clear) */
528         reg_w(gspca_dev, 0x11, 0x01);
529         PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
530 }
531
532 static void setcontrast(struct gspca_dev *gspca_dev)
533 {
534         struct sd *sd = (struct sd *) gspca_dev;
535
536         if (sd->sensor == SENSOR_PAC7302) {
537                 setbrightcont(gspca_dev);
538                 return;
539         }
540         reg_w(gspca_dev, 0xff, 0x04);
541         reg_w(gspca_dev, 0x10, sd->contrast >> 4);
542         /* load registers to sensor (Bit 0, auto clear) */
543         reg_w(gspca_dev, 0x11, 0x01);
544 }
545
546 /* This function is used by pac7302 only */
547 static void setcolors(struct gspca_dev *gspca_dev)
548 {
549         struct sd *sd = (struct sd *) gspca_dev;
550
551         if (sd->sensor == SENSOR_PAC7302) {
552                 int i, v;
553                 static const int a[9] =
554                         {217, -212, 0, -101, 170, -67, -38, -315, 355};
555                 static const int b[9] =
556                         {19, 106, 0, 19, 106, 1, 19, 106, 1};
557
558                 reg_w(gspca_dev, 0xff, 0x03);   /* page 3 */
559                 reg_w(gspca_dev, 0x11, 0x01);
560                 reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
561                 reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
562                 for (i = 0; i < 9; i++) {
563                         v = a[i] * sd->colors / COLOR_MAX + b[i];
564                         reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
565                         reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
566                 }
567                 reg_w(gspca_dev, 0xdc, 0x01);
568                 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
569         }
570 }
571
572 static void sethvflip(struct gspca_dev *gspca_dev)
573 {
574         struct sd *sd = (struct sd *) gspca_dev;
575         __u8 data;
576
577         if (sd->sensor == SENSOR_PAC7302) {
578                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
579                 data = (sd->hflip ? 0x00 : 0x08)
580                         | (sd->vflip ? 0x04 : 0x00);
581         } else {
582                 reg_w(gspca_dev, 0xff, 0x04);           /* page 3 */
583                 data = (sd->hflip ? 0x04 : 0x00)
584                         | (sd->vflip ? 0x08 : 0x00);
585         }
586         reg_w(gspca_dev, 0x21, data);
587         reg_w(gspca_dev, 0x11, 0x01);
588 }
589
590 /* this function is called at open time */
591 static int sd_open(struct gspca_dev *gspca_dev)
592 {
593         return 0;
594 }
595
596 static void sd_start(struct gspca_dev *gspca_dev)
597 {
598         struct sd *sd = (struct sd *) gspca_dev;
599
600         sd->sof_read = 0;
601
602         if (sd->sensor == SENSOR_PAC7302)
603                 reg_w_var(gspca_dev, start_7302);
604         else
605                 reg_w_var(gspca_dev, start_7311);
606
607         setcontrast(gspca_dev);
608         setbrightness(gspca_dev);
609         setcolors(gspca_dev);
610
611         /* set correct resolution */
612         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
613         case 2:                                 /* 160x120 pac7311 */
614                 reg_w(gspca_dev, 0xff, 0x04);
615                 reg_w(gspca_dev, 0x02, 0x03);
616                 reg_w(gspca_dev, 0xff, 0x01);
617                 reg_w(gspca_dev, 0x08, 0x09);
618                 reg_w(gspca_dev, 0x17, 0x20);
619                 reg_w(gspca_dev, 0x1b, 0x00);
620                 reg_w(gspca_dev, 0x87, 0x10);
621                 break;
622         case 1:                                 /* 320x240 pac7311 */
623                 reg_w(gspca_dev, 0xff, 0x04);
624                 reg_w(gspca_dev, 0x02, 0x03);
625                 reg_w(gspca_dev, 0xff, 0x01);
626                 reg_w(gspca_dev, 0x08, 0x09);
627                 reg_w(gspca_dev, 0x17, 0x30);
628                 reg_w(gspca_dev, 0x87, 0x11);
629                 break;
630         case 0:                                 /* 640x480 */
631                 if (sd->sensor == SENSOR_PAC7302)
632                         break;
633                 reg_w(gspca_dev, 0xff, 0x04);
634                 reg_w(gspca_dev, 0x02, 0x07);
635                 reg_w(gspca_dev, 0xff, 0x01);
636                 reg_w(gspca_dev, 0x08, 0x08);
637                 reg_w(gspca_dev, 0x17, 0x00);
638                 reg_w(gspca_dev, 0x87, 0x12);
639                 break;
640         }
641
642         /* start stream */
643         reg_w(gspca_dev, 0xff, 0x01);
644         if (sd->sensor == SENSOR_PAC7302) {
645                 sethvflip(gspca_dev);
646                 reg_w(gspca_dev, 0x78, 0x01);
647                 reg_w(gspca_dev, 0xff, 0x01);
648                 reg_w(gspca_dev, 0x78, 0x01);
649         } else {
650                 reg_w(gspca_dev, 0x78, 0x44);
651                 reg_w(gspca_dev, 0x78, 0x45);
652         }
653
654         sd->sof_read = 0;
655         sd->autogain_ignore_frames = 0;
656         atomic_set(&sd->avg_lum, -1);
657 }
658
659 static void sd_stopN(struct gspca_dev *gspca_dev)
660 {
661         struct sd *sd = (struct sd *) gspca_dev;
662
663         if (sd->sensor == SENSOR_PAC7302) {
664                 reg_w(gspca_dev, 0xff, 0x01);
665                 reg_w(gspca_dev, 0x78, 0x00);
666                 reg_w(gspca_dev, 0x78, 0x00);
667                 return;
668         }
669         reg_w(gspca_dev, 0xff, 0x04);
670         reg_w(gspca_dev, 0x27, 0x80);
671         reg_w(gspca_dev, 0x28, 0xca);
672         reg_w(gspca_dev, 0x29, 0x53);
673         reg_w(gspca_dev, 0x2a, 0x0e);
674         reg_w(gspca_dev, 0xff, 0x01);
675         reg_w(gspca_dev, 0x3e, 0x20);
676         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
677         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
678         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
679 }
680
681 static void sd_stop0(struct gspca_dev *gspca_dev)
682 {
683         struct sd *sd = (struct sd *) gspca_dev;
684
685         if (sd->sensor == SENSOR_PAC7302) {
686                 reg_w(gspca_dev, 0xff, 0x01);
687                 reg_w(gspca_dev, 0x78, 0x40);
688         }
689 }
690
691 /* this function is called at close time */
692 static void sd_close(struct gspca_dev *gspca_dev)
693 {
694 }
695
696 static void do_autogain(struct gspca_dev *gspca_dev)
697 {
698 }
699
700 static const unsigned char pac7311_jpeg_header1[] = {
701   0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
702 };
703
704 static const unsigned char pac7311_jpeg_header2[] = {
705   0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
706   0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
707 };
708
709 /* Include pac common sof detection functions */
710 #include "pac_common.h"
711
712 #define HEADER_LENGTH 2
713
714 /* this function is run at interrupt level */
715 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
716                         struct gspca_frame *frame,      /* target */
717                         __u8 *data,                     /* isoc packet */
718                         int len)                        /* iso packet length */
719 {
720         struct sd *sd = (struct sd *) gspca_dev;
721         unsigned char *sof;
722
723         sof = pac_find_sof(gspca_dev, data, len);
724         if (sof) {
725                 unsigned char tmpbuf[4];
726                 int n, lum_offset, footer_length;
727
728                 if (sd->sensor == SENSOR_PAC7302) {
729                   lum_offset = 34 + sizeof pac_sof_marker;
730                   footer_length = 74;
731                 } else {
732                   lum_offset = 24 + sizeof pac_sof_marker;
733                   footer_length = 26;
734                 }
735
736                 /* Finish decoding current frame */
737                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
738                 if (n < 0) {
739                         frame->data_end += n;
740                         n = 0;
741                 }
742                 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
743                                         data, n);
744                 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
745                                 frame->data_end[-2] == 0xff &&
746                                 frame->data_end[-1] == 0xd9)
747                         frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
748                                                 NULL, 0);
749
750                 n = sof - data;
751                 len -= n;
752                 data = sof;
753
754                 /* Get average lumination */
755                 if (gspca_dev->last_packet_type == LAST_PACKET &&
756                                 n >= lum_offset) {
757                         if (sd->sensor == SENSOR_PAC7302)
758                                 atomic_set(&sd->avg_lum,
759                                                 (data[-lum_offset] << 8) |
760                                                 data[-lum_offset + 1]);
761                         else
762                                 atomic_set(&sd->avg_lum,
763                                                 data[-lum_offset] +
764                                                 data[-lum_offset + 1]);
765                 } else {
766                         atomic_set(&sd->avg_lum, -1);
767                 }
768
769                 /* Start the new frame with the jpeg header */
770                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
771                         pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
772                 if (sd->sensor == SENSOR_PAC7302) {
773                         /* The PAC7302 has the image rotated 90 degrees */
774                         tmpbuf[0] = gspca_dev->width >> 8;
775                         tmpbuf[1] = gspca_dev->width & 0xff;
776                         tmpbuf[2] = gspca_dev->height >> 8;
777                         tmpbuf[3] = gspca_dev->height & 0xff;
778                 } else {
779                         tmpbuf[0] = gspca_dev->height >> 8;
780                         tmpbuf[1] = gspca_dev->height & 0xff;
781                         tmpbuf[2] = gspca_dev->width >> 8;
782                         tmpbuf[3] = gspca_dev->width & 0xff;
783                 }
784                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
785                 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
786                         pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
787
788                 sd->header_read = 0;
789         }
790
791         if (sd->header_read < HEADER_LENGTH) {
792                 /* skip the variable part of the sof header */
793                 int needed = HEADER_LENGTH - sd->header_read;
794                 if (len <= needed) {
795                         sd->header_read += len;
796                         return;
797                 }
798                 data += needed;
799                 len -= needed;
800                 sd->header_read = HEADER_LENGTH;
801         }
802
803         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
804 }
805
806 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
807 {
808         struct sd *sd = (struct sd *) gspca_dev;
809
810         sd->brightness = val;
811         if (gspca_dev->streaming)
812                 setbrightness(gspca_dev);
813         return 0;
814 }
815
816 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
817 {
818         struct sd *sd = (struct sd *) gspca_dev;
819
820         *val = sd->brightness;
821         return 0;
822 }
823
824 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
825 {
826         struct sd *sd = (struct sd *) gspca_dev;
827
828         sd->contrast = val;
829         if (gspca_dev->streaming)
830                 setcontrast(gspca_dev);
831         return 0;
832 }
833
834 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
835 {
836         struct sd *sd = (struct sd *) gspca_dev;
837
838         *val = sd->contrast;
839         return 0;
840 }
841
842 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
843 {
844         struct sd *sd = (struct sd *) gspca_dev;
845
846         sd->colors = val;
847         if (gspca_dev->streaming)
848                 setcolors(gspca_dev);
849         return 0;
850 }
851
852 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
853 {
854         struct sd *sd = (struct sd *) gspca_dev;
855
856         *val = sd->colors;
857         return 0;
858 }
859
860 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
861 {
862         struct sd *sd = (struct sd *) gspca_dev;
863
864         sd->autogain = val;
865
866         return 0;
867 }
868
869 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
870 {
871         struct sd *sd = (struct sd *) gspca_dev;
872
873         *val = sd->autogain;
874         return 0;
875 }
876
877 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
878 {
879         struct sd *sd = (struct sd *) gspca_dev;
880
881         sd->hflip = val;
882         if (gspca_dev->streaming)
883                 sethvflip(gspca_dev);
884         return 0;
885 }
886
887 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
888 {
889         struct sd *sd = (struct sd *) gspca_dev;
890
891         *val = sd->hflip;
892         return 0;
893 }
894
895 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
896 {
897         struct sd *sd = (struct sd *) gspca_dev;
898
899         sd->vflip = val;
900         if (gspca_dev->streaming)
901                 sethvflip(gspca_dev);
902         return 0;
903 }
904
905 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
906 {
907         struct sd *sd = (struct sd *) gspca_dev;
908
909         *val = sd->vflip;
910         return 0;
911 }
912
913 /* sub-driver description */
914 static struct sd_desc sd_desc = {
915         .name = MODULE_NAME,
916         .ctrls = sd_ctrls,
917         .nctrls = ARRAY_SIZE(sd_ctrls),
918         .config = sd_config,
919         .open = sd_open,
920         .start = sd_start,
921         .stopN = sd_stopN,
922         .stop0 = sd_stop0,
923         .close = sd_close,
924         .pkt_scan = sd_pkt_scan,
925         .dq_callback = do_autogain,
926 };
927
928 /* -- module initialisation -- */
929 static __devinitdata struct usb_device_id device_table[] = {
930         {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
931         {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
932         {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
933         {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
934         {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
935         {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
936         {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
937         {}
938 };
939 MODULE_DEVICE_TABLE(usb, device_table);
940
941 /* -- device connect -- */
942 static int sd_probe(struct usb_interface *intf,
943                         const struct usb_device_id *id)
944 {
945         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
946                                 THIS_MODULE);
947 }
948
949 static struct usb_driver sd_driver = {
950         .name = MODULE_NAME,
951         .id_table = device_table,
952         .probe = sd_probe,
953         .disconnect = gspca_disconnect,
954 #ifdef CONFIG_PM
955         .suspend = gspca_suspend,
956         .resume = gspca_resume,
957 #endif
958 };
959
960 /* -- module insert / remove -- */
961 static int __init sd_mod_init(void)
962 {
963         if (usb_register(&sd_driver) < 0)
964                 return -1;
965         PDEBUG(D_PROBE, "registered");
966         return 0;
967 }
968 static void __exit sd_mod_exit(void)
969 {
970         usb_deregister(&sd_driver);
971         PDEBUG(D_PROBE, "deregistered");
972 }
973
974 module_init(sd_mod_init);
975 module_exit(sd_mod_exit);