]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/video/gspca/pac7302.c
Merge branches 'upstream-fixes', 'bkl-removal', 'debugfs-fixes' and 'hid-suspend...
[mv-sheeva.git] / drivers / media / video / gspca / pac7302.c
1 /*
2  *              Pixart PAC7302 library
3  *              Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * Separated from Pixart PAC7311 library by Márton Németh
8  * Camera button input handling by Márton Németh <nm127@freemail.hu>
9  * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  */
25
26 /* Some documentation about various registers as determined by trial and error.
27
28    Register page 1:
29
30    Address      Description
31    0x78         Global control, bit 6 controls the LED (inverted)
32
33    Register page 3:
34
35    Address      Description
36    0x02         Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
37                 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
38    0x03         Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
39    0x04         Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
40                 63 -> ~27 fps, the 2 msb's must always be 1 !!
41    0x05         Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42                 1 -> ~30 fps, 2 -> ~20 fps
43    0x0e         Exposure bits 0-7, 0-448, 0 = use full frame time
44    0x0f         Exposure bit 8, 0-448, 448 = no exposure at all
45    0x10         Master gain 0-31
46    0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47
48    The registers are accessed in the following functions:
49
50    Page | Register   | Function
51    -----+------------+---------------------------------------------------
52     0   | 0x0f..0x20 | setcolors()
53     0   | 0xa2..0xab | setbrightcont()
54     0   | 0xc5       | setredbalance()
55     0   | 0xc6       | setwhitebalance()
56     0   | 0xc7       | setbluebalance()
57     0   | 0xdc       | setbrightcont(), setcolors()
58     3   | 0x02       | setexposure()
59     3   | 0x10       | setgain()
60     3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
61     3   | 0x21       | sethvflip()
62 */
63
64 #define MODULE_NAME "pac7302"
65
66 #include <linux/input.h>
67 #include <media/v4l2-chip-ident.h>
68 #include "gspca.h"
69
70 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
71 MODULE_DESCRIPTION("Pixart PAC7302");
72 MODULE_LICENSE("GPL");
73
74 /* specific webcam descriptor for pac7302 */
75 struct sd {
76         struct gspca_dev gspca_dev;             /* !! must be the first item */
77
78         unsigned char brightness;
79         unsigned char contrast;
80         unsigned char colors;
81         unsigned char white_balance;
82         unsigned char red_balance;
83         unsigned char blue_balance;
84         unsigned char gain;
85         unsigned char autogain;
86         unsigned short exposure;
87         __u8 hflip;
88         __u8 vflip;
89         u8 flags;
90 #define FL_HFLIP 0x01           /* mirrored by default */
91 #define FL_VFLIP 0x02           /* vertical flipped by default */
92
93         u8 sof_read;
94         u8 autogain_ignore_frames;
95
96         atomic_t avg_lum;
97 };
98
99 /* V4L2 controls supported by the driver */
100 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
105 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
106 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
107 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
108 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
109 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
110 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
111 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
112 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
113 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
114 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
115 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
116 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
117 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
118 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
119 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
120 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
121 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
122
123 static const struct ctrl sd_ctrls[] = {
124         {
125             {
126                 .id      = V4L2_CID_BRIGHTNESS,
127                 .type    = V4L2_CTRL_TYPE_INTEGER,
128                 .name    = "Brightness",
129                 .minimum = 0,
130 #define BRIGHTNESS_MAX 0x20
131                 .maximum = BRIGHTNESS_MAX,
132                 .step    = 1,
133 #define BRIGHTNESS_DEF 0x10
134                 .default_value = BRIGHTNESS_DEF,
135             },
136             .set = sd_setbrightness,
137             .get = sd_getbrightness,
138         },
139         {
140             {
141                 .id      = V4L2_CID_CONTRAST,
142                 .type    = V4L2_CTRL_TYPE_INTEGER,
143                 .name    = "Contrast",
144                 .minimum = 0,
145 #define CONTRAST_MAX 255
146                 .maximum = CONTRAST_MAX,
147                 .step    = 1,
148 #define CONTRAST_DEF 127
149                 .default_value = CONTRAST_DEF,
150             },
151             .set = sd_setcontrast,
152             .get = sd_getcontrast,
153         },
154         {
155             {
156                 .id      = V4L2_CID_SATURATION,
157                 .type    = V4L2_CTRL_TYPE_INTEGER,
158                 .name    = "Saturation",
159                 .minimum = 0,
160 #define COLOR_MAX 255
161                 .maximum = COLOR_MAX,
162                 .step    = 1,
163 #define COLOR_DEF 127
164                 .default_value = COLOR_DEF,
165             },
166             .set = sd_setcolors,
167             .get = sd_getcolors,
168         },
169         {
170             {
171                 .id      = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
172                 .type    = V4L2_CTRL_TYPE_INTEGER,
173                 .name    = "White Balance",
174                 .minimum = 0,
175                 .maximum = 255,
176                 .step    = 1,
177 #define WHITEBALANCE_DEF 4
178                 .default_value = WHITEBALANCE_DEF,
179             },
180             .set = sd_setwhitebalance,
181             .get = sd_getwhitebalance,
182         },
183         {
184             {
185                 .id      = V4L2_CID_RED_BALANCE,
186                 .type    = V4L2_CTRL_TYPE_INTEGER,
187                 .name    = "Red",
188                 .minimum = 0,
189                 .maximum = 3,
190                 .step    = 1,
191 #define REDBALANCE_DEF 1
192                 .default_value = REDBALANCE_DEF,
193             },
194             .set = sd_setredbalance,
195             .get = sd_getredbalance,
196         },
197         {
198             {
199                 .id      = V4L2_CID_BLUE_BALANCE,
200                 .type    = V4L2_CTRL_TYPE_INTEGER,
201                 .name    = "Blue",
202                 .minimum = 0,
203                 .maximum = 3,
204                 .step    = 1,
205 #define BLUEBALANCE_DEF 1
206                 .default_value = BLUEBALANCE_DEF,
207             },
208             .set = sd_setbluebalance,
209             .get = sd_getbluebalance,
210         },
211         {
212             {
213                 .id      = V4L2_CID_GAIN,
214                 .type    = V4L2_CTRL_TYPE_INTEGER,
215                 .name    = "Gain",
216                 .minimum = 0,
217 #define GAIN_MAX 255
218                 .maximum = GAIN_MAX,
219                 .step    = 1,
220 #define GAIN_DEF 127
221 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
222                 .default_value = GAIN_DEF,
223             },
224             .set = sd_setgain,
225             .get = sd_getgain,
226         },
227         {
228             {
229                 .id      = V4L2_CID_EXPOSURE,
230                 .type    = V4L2_CTRL_TYPE_INTEGER,
231                 .name    = "Exposure",
232                 .minimum = 0,
233                 .maximum = 1023,
234                 .step    = 1,
235 #define EXPOSURE_DEF  66  /*  33 ms / 30 fps */
236 #define EXPOSURE_KNEE 133 /*  66 ms / 15 fps */
237                 .default_value = EXPOSURE_DEF,
238             },
239             .set = sd_setexposure,
240             .get = sd_getexposure,
241         },
242         {
243             {
244                 .id      = V4L2_CID_AUTOGAIN,
245                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
246                 .name    = "Auto Gain",
247                 .minimum = 0,
248                 .maximum = 1,
249                 .step    = 1,
250 #define AUTOGAIN_DEF 1
251                 .default_value = AUTOGAIN_DEF,
252             },
253             .set = sd_setautogain,
254             .get = sd_getautogain,
255         },
256         {
257             {
258                 .id      = V4L2_CID_HFLIP,
259                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
260                 .name    = "Mirror",
261                 .minimum = 0,
262                 .maximum = 1,
263                 .step    = 1,
264 #define HFLIP_DEF 0
265                 .default_value = HFLIP_DEF,
266             },
267             .set = sd_sethflip,
268             .get = sd_gethflip,
269         },
270         {
271             {
272                 .id      = V4L2_CID_VFLIP,
273                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
274                 .name    = "Vflip",
275                 .minimum = 0,
276                 .maximum = 1,
277                 .step    = 1,
278 #define VFLIP_DEF 0
279                 .default_value = VFLIP_DEF,
280             },
281             .set = sd_setvflip,
282             .get = sd_getvflip,
283         },
284 };
285
286 static const struct v4l2_pix_format vga_mode[] = {
287         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
288                 .bytesperline = 640,
289                 .sizeimage = 640 * 480 * 3 / 8 + 590,
290                 .colorspace = V4L2_COLORSPACE_JPEG,
291                 .priv = 0},
292 };
293
294 #define LOAD_PAGE3              255
295 #define END_OF_SEQUENCE         0
296
297 /* pac 7302 */
298 static const __u8 init_7302[] = {
299 /*      index,value */
300         0xff, 0x01,             /* page 1 */
301         0x78, 0x00,             /* deactivate */
302         0xff, 0x01,
303         0x78, 0x40,             /* led off */
304 };
305 static const __u8 start_7302[] = {
306 /*      index, len, [value]* */
307         0xff, 1,        0x00,           /* page 0 */
308         0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
309                         0x00, 0x00, 0x00, 0x00,
310         0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
311                         0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
312                         0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
313         0x26, 2,        0xaa, 0xaa,
314         0x2e, 1,        0x31,
315         0x38, 1,        0x01,
316         0x3a, 3,        0x14, 0xff, 0x5a,
317         0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
318                         0x00, 0x54, 0x11,
319         0x55, 1,        0x00,
320         0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
321         0x6b, 1,        0x00,
322         0x6e, 3,        0x08, 0x06, 0x00,
323         0x72, 3,        0x00, 0xff, 0x00,
324         0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
325                         0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
326                         0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
327         0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
328                         0xd2, 0xeb,
329         0xaf, 1,        0x02,
330         0xb5, 2,        0x08, 0x08,
331         0xb8, 2,        0x08, 0x88,
332         0xc4, 4,        0xae, 0x01, 0x04, 0x01,
333         0xcc, 1,        0x00,
334         0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
335                         0xc1, 0xd7, 0xec,
336         0xdc, 1,        0x01,
337         0xff, 1,        0x01,           /* page 1 */
338         0x12, 3,        0x02, 0x00, 0x01,
339         0x3e, 2,        0x00, 0x00,
340         0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
341         0x7c, 1,        0x00,
342         0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
343                         0x02, 0x00,
344         0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
345         0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
346                         0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
347         0xd8, 1,        0x01,
348         0xdb, 2,        0x00, 0x01,
349         0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
350         0xe6, 4,        0x00, 0x00, 0x00, 0x01,
351         0xeb, 1,        0x00,
352         0xff, 1,        0x02,           /* page 2 */
353         0x22, 1,        0x00,
354         0xff, 1,        0x03,           /* page 3 */
355         0, LOAD_PAGE3,                  /* load the page 3 */
356         0x11, 1,        0x01,
357         0xff, 1,        0x02,           /* page 2 */
358         0x13, 1,        0x00,
359         0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
360         0x27, 2,        0x14, 0x0c,
361         0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
362         0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
363         0x6e, 1,        0x08,
364         0xff, 1,        0x01,           /* page 1 */
365         0x78, 1,        0x00,
366         0, END_OF_SEQUENCE              /* end of sequence */
367 };
368
369 #define SKIP            0xaa
370 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
371 static const __u8 page3_7302[] = {
372         0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
373         0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
374         0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375         0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
376         0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
377         0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
378         0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
379         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380         0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
381         SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
382         0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383         0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
384         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385         0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
386         0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
387         0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
388         0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390         0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
391         0x00
392 };
393
394 static void reg_w_buf(struct gspca_dev *gspca_dev,
395                   __u8 index,
396                   const char *buffer, int len)
397 {
398         int ret;
399
400         if (gspca_dev->usb_err < 0)
401                 return;
402         memcpy(gspca_dev->usb_buf, buffer, len);
403         ret = usb_control_msg(gspca_dev->dev,
404                         usb_sndctrlpipe(gspca_dev->dev, 0),
405                         1,              /* request */
406                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
407                         0,              /* value */
408                         index, gspca_dev->usb_buf, len,
409                         500);
410         if (ret < 0) {
411                 PDEBUG(D_ERR, "reg_w_buf(): "
412                 "Failed to write registers to index 0x%x, error %i",
413                 index, ret);
414                 gspca_dev->usb_err = ret;
415         }
416 }
417
418
419 static void reg_w(struct gspca_dev *gspca_dev,
420                   __u8 index,
421                   __u8 value)
422 {
423         int ret;
424
425         if (gspca_dev->usb_err < 0)
426                 return;
427         gspca_dev->usb_buf[0] = value;
428         ret = usb_control_msg(gspca_dev->dev,
429                         usb_sndctrlpipe(gspca_dev->dev, 0),
430                         0,                      /* request */
431                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
432                         0, index, gspca_dev->usb_buf, 1,
433                         500);
434         if (ret < 0) {
435                 PDEBUG(D_ERR, "reg_w(): "
436                 "Failed to write register to index 0x%x, value 0x%x, error %i",
437                 index, value, ret);
438                 gspca_dev->usb_err = ret;
439         }
440 }
441
442 static void reg_w_seq(struct gspca_dev *gspca_dev,
443                 const __u8 *seq, int len)
444 {
445         while (--len >= 0) {
446                 reg_w(gspca_dev, seq[0], seq[1]);
447                 seq += 2;
448         }
449 }
450
451 /* load the beginning of a page */
452 static void reg_w_page(struct gspca_dev *gspca_dev,
453                         const __u8 *page, int len)
454 {
455         int index;
456         int ret = 0;
457
458         if (gspca_dev->usb_err < 0)
459                 return;
460         for (index = 0; index < len; index++) {
461                 if (page[index] == SKIP)                /* skip this index */
462                         continue;
463                 gspca_dev->usb_buf[0] = page[index];
464                 ret = usb_control_msg(gspca_dev->dev,
465                                 usb_sndctrlpipe(gspca_dev->dev, 0),
466                                 0,                      /* request */
467                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
468                                 0, index, gspca_dev->usb_buf, 1,
469                                 500);
470                 if (ret < 0) {
471                         PDEBUG(D_ERR, "reg_w_page(): "
472                         "Failed to write register to index 0x%x, "
473                         "value 0x%x, error %i",
474                         index, page[index], ret);
475                         gspca_dev->usb_err = ret;
476                         break;
477                 }
478         }
479 }
480
481 /* output a variable sequence */
482 static void reg_w_var(struct gspca_dev *gspca_dev,
483                         const __u8 *seq,
484                         const __u8 *page3, unsigned int page3_len)
485 {
486         int index, len;
487
488         for (;;) {
489                 index = *seq++;
490                 len = *seq++;
491                 switch (len) {
492                 case END_OF_SEQUENCE:
493                         return;
494                 case LOAD_PAGE3:
495                         reg_w_page(gspca_dev, page3, page3_len);
496                         break;
497                 default:
498                         if (len > USB_BUF_SZ) {
499                                 PDEBUG(D_ERR|D_STREAM,
500                                         "Incorrect variable sequence");
501                                 return;
502                         }
503                         while (len > 0) {
504                                 if (len < 8) {
505                                         reg_w_buf(gspca_dev,
506                                                 index, seq, len);
507                                         seq += len;
508                                         break;
509                                 }
510                                 reg_w_buf(gspca_dev, index, seq, 8);
511                                 seq += 8;
512                                 index += 8;
513                                 len -= 8;
514                         }
515                 }
516         }
517         /* not reached */
518 }
519
520 /* this function is called at probe time for pac7302 */
521 static int sd_config(struct gspca_dev *gspca_dev,
522                         const struct usb_device_id *id)
523 {
524         struct sd *sd = (struct sd *) gspca_dev;
525         struct cam *cam;
526
527         cam = &gspca_dev->cam;
528
529         PDEBUG(D_CONF, "Find Sensor PAC7302");
530         cam->cam_mode = vga_mode;       /* only 640x480 */
531         cam->nmodes = ARRAY_SIZE(vga_mode);
532
533         sd->brightness = BRIGHTNESS_DEF;
534         sd->contrast = CONTRAST_DEF;
535         sd->colors = COLOR_DEF;
536         sd->white_balance = WHITEBALANCE_DEF;
537         sd->red_balance = REDBALANCE_DEF;
538         sd->blue_balance = BLUEBALANCE_DEF;
539         sd->gain = GAIN_DEF;
540         sd->exposure = EXPOSURE_DEF;
541         sd->autogain = AUTOGAIN_DEF;
542         sd->hflip = HFLIP_DEF;
543         sd->vflip = VFLIP_DEF;
544         sd->flags = id->driver_info;
545         return 0;
546 }
547
548 /* This function is used by pac7302 only */
549 static void setbrightcont(struct gspca_dev *gspca_dev)
550 {
551         struct sd *sd = (struct sd *) gspca_dev;
552         int i, v;
553         static const __u8 max[10] =
554                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
555                  0xd4, 0xec};
556         static const __u8 delta[10] =
557                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
558                  0x11, 0x0b};
559
560         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
561         for (i = 0; i < 10; i++) {
562                 v = max[i];
563                 v += (sd->brightness - BRIGHTNESS_MAX)
564                         * 150 / BRIGHTNESS_MAX;         /* 200 ? */
565                 v -= delta[i] * sd->contrast / CONTRAST_MAX;
566                 if (v < 0)
567                         v = 0;
568                 else if (v > 0xff)
569                         v = 0xff;
570                 reg_w(gspca_dev, 0xa2 + i, v);
571         }
572         reg_w(gspca_dev, 0xdc, 0x01);
573 }
574
575 /* This function is used by pac7302 only */
576 static void setcolors(struct gspca_dev *gspca_dev)
577 {
578         struct sd *sd = (struct sd *) gspca_dev;
579         int i, v;
580         static const int a[9] =
581                 {217, -212, 0, -101, 170, -67, -38, -315, 355};
582         static const int b[9] =
583                 {19, 106, 0, 19, 106, 1, 19, 106, 1};
584
585         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
586         reg_w(gspca_dev, 0x11, 0x01);
587         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
588         for (i = 0; i < 9; i++) {
589                 v = a[i] * sd->colors / COLOR_MAX + b[i];
590                 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
591                 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
592         }
593         reg_w(gspca_dev, 0xdc, 0x01);
594         PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
595 }
596
597 static void setwhitebalance(struct gspca_dev *gspca_dev)
598 {
599         struct sd *sd = (struct sd *) gspca_dev;
600
601         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
602         reg_w(gspca_dev, 0xc6, sd->white_balance);
603
604         reg_w(gspca_dev, 0xdc, 0x01);
605         PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
606 }
607
608 static void setredbalance(struct gspca_dev *gspca_dev)
609 {
610         struct sd *sd = (struct sd *) gspca_dev;
611
612         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
613         reg_w(gspca_dev, 0xc5, sd->red_balance);
614
615         reg_w(gspca_dev, 0xdc, 0x01);
616         PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
617 }
618
619 static void setbluebalance(struct gspca_dev *gspca_dev)
620 {
621         struct sd *sd = (struct sd *) gspca_dev;
622
623         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
624         reg_w(gspca_dev, 0xc7, sd->blue_balance);
625
626         reg_w(gspca_dev, 0xdc, 0x01);
627         PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
628 }
629
630 static void setgain(struct gspca_dev *gspca_dev)
631 {
632         struct sd *sd = (struct sd *) gspca_dev;
633
634         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
635         reg_w(gspca_dev, 0x10, sd->gain >> 3);
636
637         /* load registers to sensor (Bit 0, auto clear) */
638         reg_w(gspca_dev, 0x11, 0x01);
639 }
640
641 static void setexposure(struct gspca_dev *gspca_dev)
642 {
643         struct sd *sd = (struct sd *) gspca_dev;
644         __u8 clockdiv;
645         __u16 exposure;
646
647         /* register 2 of frame 3 contains the clock divider configuring the
648            no fps according to the formula: 90 / reg. sd->exposure is the
649            desired exposure time in 0.5 ms. */
650         clockdiv = (90 * sd->exposure + 1999) / 2000;
651
652         /* Note clockdiv = 3 also works, but when running at 30 fps, depending
653            on the scene being recorded, the camera switches to another
654            quantization table for certain JPEG blocks, and we don't know how
655            to decompress these blocks. So we cap the framerate at 15 fps */
656         if (clockdiv < 6)
657                 clockdiv = 6;
658         else if (clockdiv > 63)
659                 clockdiv = 63;
660
661         /* reg2 MUST be a multiple of 3, except when between 6 and 12?
662            Always round up, otherwise we cannot get the desired frametime
663            using the partial frame time exposure control */
664         if (clockdiv < 6 || clockdiv > 12)
665                 clockdiv = ((clockdiv + 2) / 3) * 3;
666
667         /* frame exposure time in ms = 1000 * clockdiv / 90    ->
668         exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
669         exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
670         /* 0 = use full frametime, 448 = no exposure, reverse it */
671         exposure = 448 - exposure;
672
673         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
674         reg_w(gspca_dev, 0x02, clockdiv);
675         reg_w(gspca_dev, 0x0e, exposure & 0xff);
676         reg_w(gspca_dev, 0x0f, exposure >> 8);
677
678         /* load registers to sensor (Bit 0, auto clear) */
679         reg_w(gspca_dev, 0x11, 0x01);
680 }
681
682 static void sethvflip(struct gspca_dev *gspca_dev)
683 {
684         struct sd *sd = (struct sd *) gspca_dev;
685         u8 data, hflip, vflip;
686
687         hflip = sd->hflip;
688         if (sd->flags & FL_HFLIP)
689                 hflip = !hflip;
690         vflip = sd->vflip;
691         if (sd->flags & FL_VFLIP)
692                 vflip = !vflip;
693
694         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
695         data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
696         reg_w(gspca_dev, 0x21, data);
697
698         /* load registers to sensor (Bit 0, auto clear) */
699         reg_w(gspca_dev, 0x11, 0x01);
700 }
701
702 /* this function is called at probe and resume time for pac7302 */
703 static int sd_init(struct gspca_dev *gspca_dev)
704 {
705         reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
706         return gspca_dev->usb_err;
707 }
708
709 static int sd_start(struct gspca_dev *gspca_dev)
710 {
711         struct sd *sd = (struct sd *) gspca_dev;
712
713         sd->sof_read = 0;
714
715         reg_w_var(gspca_dev, start_7302,
716                 page3_7302, sizeof(page3_7302));
717         setbrightcont(gspca_dev);
718         setcolors(gspca_dev);
719         setwhitebalance(gspca_dev);
720         setredbalance(gspca_dev);
721         setbluebalance(gspca_dev);
722         setgain(gspca_dev);
723         setexposure(gspca_dev);
724         sethvflip(gspca_dev);
725
726         /* only resolution 640x480 is supported for pac7302 */
727
728         sd->sof_read = 0;
729         sd->autogain_ignore_frames = 0;
730         atomic_set(&sd->avg_lum, -1);
731
732         /* start stream */
733         reg_w(gspca_dev, 0xff, 0x01);
734         reg_w(gspca_dev, 0x78, 0x01);
735
736         return gspca_dev->usb_err;
737 }
738
739 static void sd_stopN(struct gspca_dev *gspca_dev)
740 {
741
742         /* stop stream */
743         reg_w(gspca_dev, 0xff, 0x01);
744         reg_w(gspca_dev, 0x78, 0x00);
745 }
746
747 /* called on streamoff with alt 0 and on disconnect for pac7302 */
748 static void sd_stop0(struct gspca_dev *gspca_dev)
749 {
750         if (!gspca_dev->present)
751                 return;
752         reg_w(gspca_dev, 0xff, 0x01);
753         reg_w(gspca_dev, 0x78, 0x40);
754 }
755
756 /* Include pac common sof detection functions */
757 #include "pac_common.h"
758
759 static void do_autogain(struct gspca_dev *gspca_dev)
760 {
761         struct sd *sd = (struct sd *) gspca_dev;
762         int avg_lum = atomic_read(&sd->avg_lum);
763         int desired_lum;
764         const int deadzone = 30;
765
766         if (avg_lum == -1)
767                 return;
768
769         desired_lum = 270 + sd->brightness;
770
771         if (sd->autogain_ignore_frames > 0)
772                 sd->autogain_ignore_frames--;
773         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
774                         deadzone, GAIN_KNEE, EXPOSURE_KNEE))
775                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
776 }
777
778 /* JPEG header, part 1 */
779 static const unsigned char pac_jpeg_header1[] = {
780   0xff, 0xd8,           /* SOI: Start of Image */
781
782   0xff, 0xc0,           /* SOF0: Start of Frame (Baseline DCT) */
783   0x00, 0x11,           /* length = 17 bytes (including this length field) */
784   0x08                  /* Precision: 8 */
785   /* 2 bytes is placed here: number of image lines */
786   /* 2 bytes is placed here: samples per line */
787 };
788
789 /* JPEG header, continued */
790 static const unsigned char pac_jpeg_header2[] = {
791   0x03,                 /* Number of image components: 3 */
792   0x01, 0x21, 0x00,     /* ID=1, Subsampling 1x1, Quantization table: 0 */
793   0x02, 0x11, 0x01,     /* ID=2, Subsampling 2x1, Quantization table: 1 */
794   0x03, 0x11, 0x01,     /* ID=3, Subsampling 2x1, Quantization table: 1 */
795
796   0xff, 0xda,           /* SOS: Start Of Scan */
797   0x00, 0x0c,           /* length = 12 bytes (including this length field) */
798   0x03,                 /* number of components: 3 */
799   0x01, 0x00,           /* selector 1, table 0x00 */
800   0x02, 0x11,           /* selector 2, table 0x11 */
801   0x03, 0x11,           /* selector 3, table 0x11 */
802   0x00, 0x3f,           /* Spectral selection: 0 .. 63 */
803   0x00                  /* Successive approximation: 0 */
804 };
805
806 static void pac_start_frame(struct gspca_dev *gspca_dev,
807                 struct gspca_frame *frame,
808                 __u16 lines, __u16 samples_per_line)
809 {
810         unsigned char tmpbuf[4];
811
812         gspca_frame_add(gspca_dev, FIRST_PACKET,
813                 pac_jpeg_header1, sizeof(pac_jpeg_header1));
814
815         tmpbuf[0] = lines >> 8;
816         tmpbuf[1] = lines & 0xff;
817         tmpbuf[2] = samples_per_line >> 8;
818         tmpbuf[3] = samples_per_line & 0xff;
819
820         gspca_frame_add(gspca_dev, INTER_PACKET,
821                 tmpbuf, sizeof(tmpbuf));
822         gspca_frame_add(gspca_dev, INTER_PACKET,
823                 pac_jpeg_header2, sizeof(pac_jpeg_header2));
824 }
825
826 /* this function is run at interrupt level */
827 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
828                         u8 *data,                       /* isoc packet */
829                         int len)                        /* iso packet length */
830 {
831         struct sd *sd = (struct sd *) gspca_dev;
832         struct gspca_frame *frame;
833         unsigned char *sof;
834
835         sof = pac_find_sof(&sd->sof_read, data, len);
836         if (sof) {
837                 int n, lum_offset, footer_length;
838
839                 frame = gspca_get_i_frame(gspca_dev);
840                 if (frame == NULL) {
841                         gspca_dev->last_packet_type = DISCARD_PACKET;
842                         return;
843                 }
844
845                 /* 6 bytes after the FF D9 EOF marker a number of lumination
846                    bytes are send corresponding to different parts of the
847                    image, the 14th and 15th byte after the EOF seem to
848                    correspond to the center of the image */
849                 lum_offset = 61 + sizeof pac_sof_marker;
850                 footer_length = 74;
851
852                 /* Finish decoding current frame */
853                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
854                 if (n < 0) {
855                         frame->data_end += n;
856                         n = 0;
857                 }
858                 gspca_frame_add(gspca_dev, INTER_PACKET,
859                                         data, n);
860                 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
861                                 frame->data_end[-2] == 0xff &&
862                                 frame->data_end[-1] == 0xd9)
863                         gspca_frame_add(gspca_dev, LAST_PACKET,
864                                                 NULL, 0);
865
866                 n = sof - data;
867                 len -= n;
868                 data = sof;
869
870                 /* Get average lumination */
871                 if (gspca_dev->last_packet_type == LAST_PACKET &&
872                                 n >= lum_offset)
873                         atomic_set(&sd->avg_lum, data[-lum_offset] +
874                                                 data[-lum_offset + 1]);
875                 else
876                         atomic_set(&sd->avg_lum, -1);
877
878                 /* Start the new frame with the jpeg header */
879                 /* The PAC7302 has the image rotated 90 degrees */
880                 pac_start_frame(gspca_dev, frame,
881                         gspca_dev->width, gspca_dev->height);
882         }
883         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
884 }
885
886 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
887 {
888         struct sd *sd = (struct sd *) gspca_dev;
889
890         sd->brightness = val;
891         if (gspca_dev->streaming)
892                 setbrightcont(gspca_dev);
893         return gspca_dev->usb_err;
894 }
895
896 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
897 {
898         struct sd *sd = (struct sd *) gspca_dev;
899
900         *val = sd->brightness;
901         return 0;
902 }
903
904 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
905 {
906         struct sd *sd = (struct sd *) gspca_dev;
907
908         sd->contrast = val;
909         if (gspca_dev->streaming) {
910                 setbrightcont(gspca_dev);
911         }
912         return gspca_dev->usb_err;
913 }
914
915 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
916 {
917         struct sd *sd = (struct sd *) gspca_dev;
918
919         *val = sd->contrast;
920         return 0;
921 }
922
923 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
924 {
925         struct sd *sd = (struct sd *) gspca_dev;
926
927         sd->colors = val;
928         if (gspca_dev->streaming)
929                 setcolors(gspca_dev);
930         return gspca_dev->usb_err;
931 }
932
933 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
934 {
935         struct sd *sd = (struct sd *) gspca_dev;
936
937         *val = sd->colors;
938         return 0;
939 }
940
941 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
942 {
943         struct sd *sd = (struct sd *) gspca_dev;
944
945         sd->white_balance = val;
946         if (gspca_dev->streaming)
947                 setwhitebalance(gspca_dev);
948         return gspca_dev->usb_err;
949 }
950
951 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
952 {
953         struct sd *sd = (struct sd *) gspca_dev;
954
955         *val = sd->white_balance;
956         return 0;
957 }
958
959 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
960 {
961         struct sd *sd = (struct sd *) gspca_dev;
962
963         sd->red_balance = val;
964         if (gspca_dev->streaming)
965                 setredbalance(gspca_dev);
966         return gspca_dev->usb_err;
967 }
968
969 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
970 {
971         struct sd *sd = (struct sd *) gspca_dev;
972
973         *val = sd->red_balance;
974         return 0;
975 }
976
977 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
978 {
979         struct sd *sd = (struct sd *) gspca_dev;
980
981         sd->blue_balance = val;
982         if (gspca_dev->streaming)
983                 setbluebalance(gspca_dev);
984         return gspca_dev->usb_err;
985 }
986
987 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
988 {
989         struct sd *sd = (struct sd *) gspca_dev;
990
991         *val = sd->blue_balance;
992         return 0;
993 }
994
995 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
996 {
997         struct sd *sd = (struct sd *) gspca_dev;
998
999         sd->gain = val;
1000         if (gspca_dev->streaming)
1001                 setgain(gspca_dev);
1002         return gspca_dev->usb_err;
1003 }
1004
1005 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1006 {
1007         struct sd *sd = (struct sd *) gspca_dev;
1008
1009         *val = sd->gain;
1010         return 0;
1011 }
1012
1013 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1014 {
1015         struct sd *sd = (struct sd *) gspca_dev;
1016
1017         sd->exposure = val;
1018         if (gspca_dev->streaming)
1019                 setexposure(gspca_dev);
1020         return gspca_dev->usb_err;
1021 }
1022
1023 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1024 {
1025         struct sd *sd = (struct sd *) gspca_dev;
1026
1027         *val = sd->exposure;
1028         return 0;
1029 }
1030
1031 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1032 {
1033         struct sd *sd = (struct sd *) gspca_dev;
1034
1035         sd->autogain = val;
1036         /* when switching to autogain set defaults to make sure
1037            we are on a valid point of the autogain gain /
1038            exposure knee graph, and give this change time to
1039            take effect before doing autogain. */
1040         if (sd->autogain) {
1041                 sd->exposure = EXPOSURE_DEF;
1042                 sd->gain = GAIN_DEF;
1043                 if (gspca_dev->streaming) {
1044                         sd->autogain_ignore_frames =
1045                                 PAC_AUTOGAIN_IGNORE_FRAMES;
1046                         setexposure(gspca_dev);
1047                         setgain(gspca_dev);
1048                 }
1049         }
1050
1051         return gspca_dev->usb_err;
1052 }
1053
1054 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1055 {
1056         struct sd *sd = (struct sd *) gspca_dev;
1057
1058         *val = sd->autogain;
1059         return 0;
1060 }
1061
1062 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1063 {
1064         struct sd *sd = (struct sd *) gspca_dev;
1065
1066         sd->hflip = val;
1067         if (gspca_dev->streaming)
1068                 sethvflip(gspca_dev);
1069         return gspca_dev->usb_err;
1070 }
1071
1072 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1073 {
1074         struct sd *sd = (struct sd *) gspca_dev;
1075
1076         *val = sd->hflip;
1077         return 0;
1078 }
1079
1080 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1081 {
1082         struct sd *sd = (struct sd *) gspca_dev;
1083
1084         sd->vflip = val;
1085         if (gspca_dev->streaming)
1086                 sethvflip(gspca_dev);
1087         return gspca_dev->usb_err;
1088 }
1089
1090 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1091 {
1092         struct sd *sd = (struct sd *) gspca_dev;
1093
1094         *val = sd->vflip;
1095         return 0;
1096 }
1097
1098 #ifdef CONFIG_VIDEO_ADV_DEBUG
1099 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1100                         struct v4l2_dbg_register *reg)
1101 {
1102         __u8 index;
1103         __u8 value;
1104
1105         /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1106                                long on the USB bus)
1107         */
1108         if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
1109             reg->match.addr == 0 &&
1110             (reg->reg < 0x000000ff) &&
1111             (reg->val <= 0x000000ff)
1112         ) {
1113                 /* Currently writing to page 0 is only supported. */
1114                 /* reg_w() only supports 8bit index */
1115                 index = reg->reg & 0x000000ff;
1116                 value = reg->val & 0x000000ff;
1117
1118                 /* Note that there shall be no access to other page
1119                    by any other function between the page swith and
1120                    the actual register write */
1121                 reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
1122                 reg_w(gspca_dev, index, value);
1123
1124                 reg_w(gspca_dev, 0xdc, 0x01);
1125         }
1126         return gspca_dev->usb_err;
1127 }
1128
1129 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1130                         struct v4l2_dbg_chip_ident *chip)
1131 {
1132         int ret = -EINVAL;
1133
1134         if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
1135             chip->match.addr == 0) {
1136                 chip->revision = 0;
1137                 chip->ident = V4L2_IDENT_UNKNOWN;
1138                 ret = 0;
1139         }
1140         return ret;
1141 }
1142 #endif
1143
1144 #ifdef CONFIG_INPUT
1145 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1146                         u8 *data,               /* interrupt packet data */
1147                         int len)                /* interrput packet length */
1148 {
1149         int ret = -EINVAL;
1150         u8 data0, data1;
1151
1152         if (len == 2) {
1153                 data0 = data[0];
1154                 data1 = data[1];
1155                 if ((data0 == 0x00 && data1 == 0x11) ||
1156                     (data0 == 0x22 && data1 == 0x33) ||
1157                     (data0 == 0x44 && data1 == 0x55) ||
1158                     (data0 == 0x66 && data1 == 0x77) ||
1159                     (data0 == 0x88 && data1 == 0x99) ||
1160                     (data0 == 0xaa && data1 == 0xbb) ||
1161                     (data0 == 0xcc && data1 == 0xdd) ||
1162                     (data0 == 0xee && data1 == 0xff)) {
1163                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1164                         input_sync(gspca_dev->input_dev);
1165                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1166                         input_sync(gspca_dev->input_dev);
1167                         ret = 0;
1168                 }
1169         }
1170
1171         return ret;
1172 }
1173 #endif
1174
1175 /* sub-driver description for pac7302 */
1176 static const struct sd_desc sd_desc = {
1177         .name = MODULE_NAME,
1178         .ctrls = sd_ctrls,
1179         .nctrls = ARRAY_SIZE(sd_ctrls),
1180         .config = sd_config,
1181         .init = sd_init,
1182         .start = sd_start,
1183         .stopN = sd_stopN,
1184         .stop0 = sd_stop0,
1185         .pkt_scan = sd_pkt_scan,
1186         .dq_callback = do_autogain,
1187 #ifdef CONFIG_VIDEO_ADV_DEBUG
1188         .set_register = sd_dbg_s_register,
1189         .get_chip_ident = sd_chip_ident,
1190 #endif
1191 #ifdef CONFIG_INPUT
1192         .int_pkt_scan = sd_int_pkt_scan,
1193 #endif
1194 };
1195
1196 /* -- module initialisation -- */
1197 static const struct usb_device_id device_table[] __devinitconst = {
1198         {USB_DEVICE(0x06f8, 0x3009)},
1199         {USB_DEVICE(0x093a, 0x2620)},
1200         {USB_DEVICE(0x093a, 0x2621)},
1201         {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
1202         {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
1203         {USB_DEVICE(0x093a, 0x2626)},
1204         {USB_DEVICE(0x093a, 0x2628)},
1205         {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
1206         {USB_DEVICE(0x093a, 0x262a)},
1207         {USB_DEVICE(0x093a, 0x262c)},
1208         {}
1209 };
1210 MODULE_DEVICE_TABLE(usb, device_table);
1211
1212 /* -- device connect -- */
1213 static int __devinit sd_probe(struct usb_interface *intf,
1214                         const struct usb_device_id *id)
1215 {
1216         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1217                                 THIS_MODULE);
1218 }
1219
1220 static struct usb_driver sd_driver = {
1221         .name = MODULE_NAME,
1222         .id_table = device_table,
1223         .probe = sd_probe,
1224         .disconnect = gspca_disconnect,
1225 #ifdef CONFIG_PM
1226         .suspend = gspca_suspend,
1227         .resume = gspca_resume,
1228 #endif
1229 };
1230
1231 /* -- module insert / remove -- */
1232 static int __init sd_mod_init(void)
1233 {
1234         int ret;
1235         ret = usb_register(&sd_driver);
1236         if (ret < 0)
1237                 return ret;
1238         PDEBUG(D_PROBE, "registered");
1239         return 0;
1240 }
1241 static void __exit sd_mod_exit(void)
1242 {
1243         usb_deregister(&sd_driver);
1244         PDEBUG(D_PROBE, "deregistered");
1245 }
1246
1247 module_init(sd_mod_init);
1248 module_exit(sd_mod_exit);