Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.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                         0,              /* 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                 err("reg_w_buf failed index 0x%02x, error %d",
412                         index, ret);
413                 gspca_dev->usb_err = ret;
414         }
415 }
416
417
418 static void reg_w(struct gspca_dev *gspca_dev,
419                   __u8 index,
420                   __u8 value)
421 {
422         int ret;
423
424         if (gspca_dev->usb_err < 0)
425                 return;
426         gspca_dev->usb_buf[0] = value;
427         ret = usb_control_msg(gspca_dev->dev,
428                         usb_sndctrlpipe(gspca_dev->dev, 0),
429                         0,                      /* request */
430                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
431                         0, index, gspca_dev->usb_buf, 1,
432                         500);
433         if (ret < 0) {
434                 err("reg_w() failed index 0x%02x, value 0x%02x, error %d",
435                         index, value, ret);
436                 gspca_dev->usb_err = ret;
437         }
438 }
439
440 static void reg_w_seq(struct gspca_dev *gspca_dev,
441                 const __u8 *seq, int len)
442 {
443         while (--len >= 0) {
444                 reg_w(gspca_dev, seq[0], seq[1]);
445                 seq += 2;
446         }
447 }
448
449 /* load the beginning of a page */
450 static void reg_w_page(struct gspca_dev *gspca_dev,
451                         const __u8 *page, int len)
452 {
453         int index;
454         int ret = 0;
455
456         if (gspca_dev->usb_err < 0)
457                 return;
458         for (index = 0; index < len; index++) {
459                 if (page[index] == SKIP)                /* skip this index */
460                         continue;
461                 gspca_dev->usb_buf[0] = page[index];
462                 ret = usb_control_msg(gspca_dev->dev,
463                                 usb_sndctrlpipe(gspca_dev->dev, 0),
464                                 0,                      /* request */
465                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
466                                 0, index, gspca_dev->usb_buf, 1,
467                                 500);
468                 if (ret < 0) {
469                         err("reg_w_page() failed index 0x%02x, "
470                         "value 0x%02x, error %d",
471                                 index, page[index], ret);
472                         gspca_dev->usb_err = ret;
473                         break;
474                 }
475         }
476 }
477
478 /* output a variable sequence */
479 static void reg_w_var(struct gspca_dev *gspca_dev,
480                         const __u8 *seq,
481                         const __u8 *page3, unsigned int page3_len)
482 {
483         int index, len;
484
485         for (;;) {
486                 index = *seq++;
487                 len = *seq++;
488                 switch (len) {
489                 case END_OF_SEQUENCE:
490                         return;
491                 case LOAD_PAGE3:
492                         reg_w_page(gspca_dev, page3, page3_len);
493                         break;
494                 default:
495                         if (len > USB_BUF_SZ) {
496                                 PDEBUG(D_ERR|D_STREAM,
497                                         "Incorrect variable sequence");
498                                 return;
499                         }
500                         while (len > 0) {
501                                 if (len < 8) {
502                                         reg_w_buf(gspca_dev,
503                                                 index, seq, len);
504                                         seq += len;
505                                         break;
506                                 }
507                                 reg_w_buf(gspca_dev, index, seq, 8);
508                                 seq += 8;
509                                 index += 8;
510                                 len -= 8;
511                         }
512                 }
513         }
514         /* not reached */
515 }
516
517 /* this function is called at probe time for pac7302 */
518 static int sd_config(struct gspca_dev *gspca_dev,
519                         const struct usb_device_id *id)
520 {
521         struct sd *sd = (struct sd *) gspca_dev;
522         struct cam *cam;
523
524         cam = &gspca_dev->cam;
525
526         PDEBUG(D_CONF, "Find Sensor PAC7302");
527         cam->cam_mode = vga_mode;       /* only 640x480 */
528         cam->nmodes = ARRAY_SIZE(vga_mode);
529
530         sd->brightness = BRIGHTNESS_DEF;
531         sd->contrast = CONTRAST_DEF;
532         sd->colors = COLOR_DEF;
533         sd->white_balance = WHITEBALANCE_DEF;
534         sd->red_balance = REDBALANCE_DEF;
535         sd->blue_balance = BLUEBALANCE_DEF;
536         sd->gain = GAIN_DEF;
537         sd->exposure = EXPOSURE_DEF;
538         sd->autogain = AUTOGAIN_DEF;
539         sd->hflip = HFLIP_DEF;
540         sd->vflip = VFLIP_DEF;
541         sd->flags = id->driver_info;
542         return 0;
543 }
544
545 /* This function is used by pac7302 only */
546 static void setbrightcont(struct gspca_dev *gspca_dev)
547 {
548         struct sd *sd = (struct sd *) gspca_dev;
549         int i, v;
550         static const __u8 max[10] =
551                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
552                  0xd4, 0xec};
553         static const __u8 delta[10] =
554                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
555                  0x11, 0x0b};
556
557         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
558         for (i = 0; i < 10; i++) {
559                 v = max[i];
560                 v += (sd->brightness - BRIGHTNESS_MAX)
561                         * 150 / BRIGHTNESS_MAX;         /* 200 ? */
562                 v -= delta[i] * sd->contrast / CONTRAST_MAX;
563                 if (v < 0)
564                         v = 0;
565                 else if (v > 0xff)
566                         v = 0xff;
567                 reg_w(gspca_dev, 0xa2 + i, v);
568         }
569         reg_w(gspca_dev, 0xdc, 0x01);
570 }
571
572 /* This function is used by pac7302 only */
573 static void setcolors(struct gspca_dev *gspca_dev)
574 {
575         struct sd *sd = (struct sd *) gspca_dev;
576         int i, v;
577         static const int a[9] =
578                 {217, -212, 0, -101, 170, -67, -38, -315, 355};
579         static const int b[9] =
580                 {19, 106, 0, 19, 106, 1, 19, 106, 1};
581
582         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
583         reg_w(gspca_dev, 0x11, 0x01);
584         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
585         for (i = 0; i < 9; i++) {
586                 v = a[i] * sd->colors / COLOR_MAX + b[i];
587                 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
588                 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
589         }
590         reg_w(gspca_dev, 0xdc, 0x01);
591         PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
592 }
593
594 static void setwhitebalance(struct gspca_dev *gspca_dev)
595 {
596         struct sd *sd = (struct sd *) gspca_dev;
597
598         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
599         reg_w(gspca_dev, 0xc6, sd->white_balance);
600
601         reg_w(gspca_dev, 0xdc, 0x01);
602         PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
603 }
604
605 static void setredbalance(struct gspca_dev *gspca_dev)
606 {
607         struct sd *sd = (struct sd *) gspca_dev;
608
609         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
610         reg_w(gspca_dev, 0xc5, sd->red_balance);
611
612         reg_w(gspca_dev, 0xdc, 0x01);
613         PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
614 }
615
616 static void setbluebalance(struct gspca_dev *gspca_dev)
617 {
618         struct sd *sd = (struct sd *) gspca_dev;
619
620         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
621         reg_w(gspca_dev, 0xc7, sd->blue_balance);
622
623         reg_w(gspca_dev, 0xdc, 0x01);
624         PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
625 }
626
627 static void setgain(struct gspca_dev *gspca_dev)
628 {
629         struct sd *sd = (struct sd *) gspca_dev;
630
631         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
632         reg_w(gspca_dev, 0x10, sd->gain >> 3);
633
634         /* load registers to sensor (Bit 0, auto clear) */
635         reg_w(gspca_dev, 0x11, 0x01);
636 }
637
638 static void setexposure(struct gspca_dev *gspca_dev)
639 {
640         struct sd *sd = (struct sd *) gspca_dev;
641         __u8 clockdiv;
642         __u16 exposure;
643
644         /* register 2 of frame 3 contains the clock divider configuring the
645            no fps according to the formula: 90 / reg. sd->exposure is the
646            desired exposure time in 0.5 ms. */
647         clockdiv = (90 * sd->exposure + 1999) / 2000;
648
649         /* Note clockdiv = 3 also works, but when running at 30 fps, depending
650            on the scene being recorded, the camera switches to another
651            quantization table for certain JPEG blocks, and we don't know how
652            to decompress these blocks. So we cap the framerate at 15 fps */
653         if (clockdiv < 6)
654                 clockdiv = 6;
655         else if (clockdiv > 63)
656                 clockdiv = 63;
657
658         /* reg2 MUST be a multiple of 3, except when between 6 and 12?
659            Always round up, otherwise we cannot get the desired frametime
660            using the partial frame time exposure control */
661         if (clockdiv < 6 || clockdiv > 12)
662                 clockdiv = ((clockdiv + 2) / 3) * 3;
663
664         /* frame exposure time in ms = 1000 * clockdiv / 90    ->
665         exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
666         exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
667         /* 0 = use full frametime, 448 = no exposure, reverse it */
668         exposure = 448 - exposure;
669
670         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
671         reg_w(gspca_dev, 0x02, clockdiv);
672         reg_w(gspca_dev, 0x0e, exposure & 0xff);
673         reg_w(gspca_dev, 0x0f, exposure >> 8);
674
675         /* load registers to sensor (Bit 0, auto clear) */
676         reg_w(gspca_dev, 0x11, 0x01);
677 }
678
679 static void sethvflip(struct gspca_dev *gspca_dev)
680 {
681         struct sd *sd = (struct sd *) gspca_dev;
682         u8 data, hflip, vflip;
683
684         hflip = sd->hflip;
685         if (sd->flags & FL_HFLIP)
686                 hflip = !hflip;
687         vflip = sd->vflip;
688         if (sd->flags & FL_VFLIP)
689                 vflip = !vflip;
690
691         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
692         data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
693         reg_w(gspca_dev, 0x21, data);
694
695         /* load registers to sensor (Bit 0, auto clear) */
696         reg_w(gspca_dev, 0x11, 0x01);
697 }
698
699 /* this function is called at probe and resume time for pac7302 */
700 static int sd_init(struct gspca_dev *gspca_dev)
701 {
702         reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
703         return gspca_dev->usb_err;
704 }
705
706 static int sd_start(struct gspca_dev *gspca_dev)
707 {
708         struct sd *sd = (struct sd *) gspca_dev;
709
710         sd->sof_read = 0;
711
712         reg_w_var(gspca_dev, start_7302,
713                 page3_7302, sizeof(page3_7302));
714         setbrightcont(gspca_dev);
715         setcolors(gspca_dev);
716         setwhitebalance(gspca_dev);
717         setredbalance(gspca_dev);
718         setbluebalance(gspca_dev);
719         setgain(gspca_dev);
720         setexposure(gspca_dev);
721         sethvflip(gspca_dev);
722
723         /* only resolution 640x480 is supported for pac7302 */
724
725         sd->sof_read = 0;
726         sd->autogain_ignore_frames = 0;
727         atomic_set(&sd->avg_lum, -1);
728
729         /* start stream */
730         reg_w(gspca_dev, 0xff, 0x01);
731         reg_w(gspca_dev, 0x78, 0x01);
732
733         return gspca_dev->usb_err;
734 }
735
736 static void sd_stopN(struct gspca_dev *gspca_dev)
737 {
738
739         /* stop stream */
740         reg_w(gspca_dev, 0xff, 0x01);
741         reg_w(gspca_dev, 0x78, 0x00);
742 }
743
744 /* called on streamoff with alt 0 and on disconnect for pac7302 */
745 static void sd_stop0(struct gspca_dev *gspca_dev)
746 {
747         if (!gspca_dev->present)
748                 return;
749         reg_w(gspca_dev, 0xff, 0x01);
750         reg_w(gspca_dev, 0x78, 0x40);
751 }
752
753 /* Include pac common sof detection functions */
754 #include "pac_common.h"
755
756 static void do_autogain(struct gspca_dev *gspca_dev)
757 {
758         struct sd *sd = (struct sd *) gspca_dev;
759         int avg_lum = atomic_read(&sd->avg_lum);
760         int desired_lum;
761         const int deadzone = 30;
762
763         if (avg_lum == -1)
764                 return;
765
766         desired_lum = 270 + sd->brightness;
767
768         if (sd->autogain_ignore_frames > 0)
769                 sd->autogain_ignore_frames--;
770         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
771                         deadzone, GAIN_KNEE, EXPOSURE_KNEE))
772                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
773 }
774
775 /* JPEG header, part 1 */
776 static const unsigned char pac_jpeg_header1[] = {
777   0xff, 0xd8,           /* SOI: Start of Image */
778
779   0xff, 0xc0,           /* SOF0: Start of Frame (Baseline DCT) */
780   0x00, 0x11,           /* length = 17 bytes (including this length field) */
781   0x08                  /* Precision: 8 */
782   /* 2 bytes is placed here: number of image lines */
783   /* 2 bytes is placed here: samples per line */
784 };
785
786 /* JPEG header, continued */
787 static const unsigned char pac_jpeg_header2[] = {
788   0x03,                 /* Number of image components: 3 */
789   0x01, 0x21, 0x00,     /* ID=1, Subsampling 1x1, Quantization table: 0 */
790   0x02, 0x11, 0x01,     /* ID=2, Subsampling 2x1, Quantization table: 1 */
791   0x03, 0x11, 0x01,     /* ID=3, Subsampling 2x1, Quantization table: 1 */
792
793   0xff, 0xda,           /* SOS: Start Of Scan */
794   0x00, 0x0c,           /* length = 12 bytes (including this length field) */
795   0x03,                 /* number of components: 3 */
796   0x01, 0x00,           /* selector 1, table 0x00 */
797   0x02, 0x11,           /* selector 2, table 0x11 */
798   0x03, 0x11,           /* selector 3, table 0x11 */
799   0x00, 0x3f,           /* Spectral selection: 0 .. 63 */
800   0x00                  /* Successive approximation: 0 */
801 };
802
803 static void pac_start_frame(struct gspca_dev *gspca_dev,
804                 __u16 lines, __u16 samples_per_line)
805 {
806         unsigned char tmpbuf[4];
807
808         gspca_frame_add(gspca_dev, FIRST_PACKET,
809                 pac_jpeg_header1, sizeof(pac_jpeg_header1));
810
811         tmpbuf[0] = lines >> 8;
812         tmpbuf[1] = lines & 0xff;
813         tmpbuf[2] = samples_per_line >> 8;
814         tmpbuf[3] = samples_per_line & 0xff;
815
816         gspca_frame_add(gspca_dev, INTER_PACKET,
817                 tmpbuf, sizeof(tmpbuf));
818         gspca_frame_add(gspca_dev, INTER_PACKET,
819                 pac_jpeg_header2, sizeof(pac_jpeg_header2));
820 }
821
822 /* this function is run at interrupt level */
823 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
824                         u8 *data,                       /* isoc packet */
825                         int len)                        /* iso packet length */
826 {
827         struct sd *sd = (struct sd *) gspca_dev;
828         u8 *image;
829         unsigned char *sof;
830
831         sof = pac_find_sof(&sd->sof_read, data, len);
832         if (sof) {
833                 int n, lum_offset, footer_length;
834
835                 /* 6 bytes after the FF D9 EOF marker a number of lumination
836                    bytes are send corresponding to different parts of the
837                    image, the 14th and 15th byte after the EOF seem to
838                    correspond to the center of the image */
839                 lum_offset = 61 + sizeof pac_sof_marker;
840                 footer_length = 74;
841
842                 /* Finish decoding current frame */
843                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
844                 if (n < 0) {
845                         gspca_dev->image_len += n;
846                         n = 0;
847                 } else {
848                         gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
849                 }
850
851                 image = gspca_dev->image;
852                 if (image != NULL
853                  && image[gspca_dev->image_len - 2] == 0xff
854                  && image[gspca_dev->image_len - 1] == 0xd9)
855                         gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
856
857                 n = sof - data;
858                 len -= n;
859                 data = sof;
860
861                 /* Get average lumination */
862                 if (gspca_dev->last_packet_type == LAST_PACKET &&
863                                 n >= lum_offset)
864                         atomic_set(&sd->avg_lum, data[-lum_offset] +
865                                                 data[-lum_offset + 1]);
866                 else
867                         atomic_set(&sd->avg_lum, -1);
868
869                 /* Start the new frame with the jpeg header */
870                 /* The PAC7302 has the image rotated 90 degrees */
871                 pac_start_frame(gspca_dev,
872                         gspca_dev->width, gspca_dev->height);
873         }
874         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
875 }
876
877 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
878 {
879         struct sd *sd = (struct sd *) gspca_dev;
880
881         sd->brightness = val;
882         if (gspca_dev->streaming)
883                 setbrightcont(gspca_dev);
884         return gspca_dev->usb_err;
885 }
886
887 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
888 {
889         struct sd *sd = (struct sd *) gspca_dev;
890
891         *val = sd->brightness;
892         return 0;
893 }
894
895 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
896 {
897         struct sd *sd = (struct sd *) gspca_dev;
898
899         sd->contrast = val;
900         if (gspca_dev->streaming)
901                 setbrightcont(gspca_dev);
902         return gspca_dev->usb_err;
903 }
904
905 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
906 {
907         struct sd *sd = (struct sd *) gspca_dev;
908
909         *val = sd->contrast;
910         return 0;
911 }
912
913 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
914 {
915         struct sd *sd = (struct sd *) gspca_dev;
916
917         sd->colors = val;
918         if (gspca_dev->streaming)
919                 setcolors(gspca_dev);
920         return gspca_dev->usb_err;
921 }
922
923 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
924 {
925         struct sd *sd = (struct sd *) gspca_dev;
926
927         *val = sd->colors;
928         return 0;
929 }
930
931 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
932 {
933         struct sd *sd = (struct sd *) gspca_dev;
934
935         sd->white_balance = val;
936         if (gspca_dev->streaming)
937                 setwhitebalance(gspca_dev);
938         return gspca_dev->usb_err;
939 }
940
941 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
942 {
943         struct sd *sd = (struct sd *) gspca_dev;
944
945         *val = sd->white_balance;
946         return 0;
947 }
948
949 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
950 {
951         struct sd *sd = (struct sd *) gspca_dev;
952
953         sd->red_balance = val;
954         if (gspca_dev->streaming)
955                 setredbalance(gspca_dev);
956         return gspca_dev->usb_err;
957 }
958
959 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
960 {
961         struct sd *sd = (struct sd *) gspca_dev;
962
963         *val = sd->red_balance;
964         return 0;
965 }
966
967 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
968 {
969         struct sd *sd = (struct sd *) gspca_dev;
970
971         sd->blue_balance = val;
972         if (gspca_dev->streaming)
973                 setbluebalance(gspca_dev);
974         return gspca_dev->usb_err;
975 }
976
977 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
978 {
979         struct sd *sd = (struct sd *) gspca_dev;
980
981         *val = sd->blue_balance;
982         return 0;
983 }
984
985 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
986 {
987         struct sd *sd = (struct sd *) gspca_dev;
988
989         sd->gain = val;
990         if (gspca_dev->streaming)
991                 setgain(gspca_dev);
992         return gspca_dev->usb_err;
993 }
994
995 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
996 {
997         struct sd *sd = (struct sd *) gspca_dev;
998
999         *val = sd->gain;
1000         return 0;
1001 }
1002
1003 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1004 {
1005         struct sd *sd = (struct sd *) gspca_dev;
1006
1007         sd->exposure = val;
1008         if (gspca_dev->streaming)
1009                 setexposure(gspca_dev);
1010         return gspca_dev->usb_err;
1011 }
1012
1013 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1014 {
1015         struct sd *sd = (struct sd *) gspca_dev;
1016
1017         *val = sd->exposure;
1018         return 0;
1019 }
1020
1021 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1022 {
1023         struct sd *sd = (struct sd *) gspca_dev;
1024
1025         sd->autogain = val;
1026         /* when switching to autogain set defaults to make sure
1027            we are on a valid point of the autogain gain /
1028            exposure knee graph, and give this change time to
1029            take effect before doing autogain. */
1030         if (sd->autogain) {
1031                 sd->exposure = EXPOSURE_DEF;
1032                 sd->gain = GAIN_DEF;
1033                 if (gspca_dev->streaming) {
1034                         sd->autogain_ignore_frames =
1035                                 PAC_AUTOGAIN_IGNORE_FRAMES;
1036                         setexposure(gspca_dev);
1037                         setgain(gspca_dev);
1038                 }
1039         }
1040
1041         return gspca_dev->usb_err;
1042 }
1043
1044 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1045 {
1046         struct sd *sd = (struct sd *) gspca_dev;
1047
1048         *val = sd->autogain;
1049         return 0;
1050 }
1051
1052 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1053 {
1054         struct sd *sd = (struct sd *) gspca_dev;
1055
1056         sd->hflip = val;
1057         if (gspca_dev->streaming)
1058                 sethvflip(gspca_dev);
1059         return gspca_dev->usb_err;
1060 }
1061
1062 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1063 {
1064         struct sd *sd = (struct sd *) gspca_dev;
1065
1066         *val = sd->hflip;
1067         return 0;
1068 }
1069
1070 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1071 {
1072         struct sd *sd = (struct sd *) gspca_dev;
1073
1074         sd->vflip = val;
1075         if (gspca_dev->streaming)
1076                 sethvflip(gspca_dev);
1077         return gspca_dev->usb_err;
1078 }
1079
1080 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1081 {
1082         struct sd *sd = (struct sd *) gspca_dev;
1083
1084         *val = sd->vflip;
1085         return 0;
1086 }
1087
1088 #ifdef CONFIG_VIDEO_ADV_DEBUG
1089 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1090                         struct v4l2_dbg_register *reg)
1091 {
1092         __u8 index;
1093         __u8 value;
1094
1095         /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1096                                long on the USB bus)
1097         */
1098         if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
1099             reg->match.addr == 0 &&
1100             (reg->reg < 0x000000ff) &&
1101             (reg->val <= 0x000000ff)
1102         ) {
1103                 /* Currently writing to page 0 is only supported. */
1104                 /* reg_w() only supports 8bit index */
1105                 index = reg->reg & 0x000000ff;
1106                 value = reg->val & 0x000000ff;
1107
1108                 /* Note that there shall be no access to other page
1109                    by any other function between the page swith and
1110                    the actual register write */
1111                 reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
1112                 reg_w(gspca_dev, index, value);
1113
1114                 reg_w(gspca_dev, 0xdc, 0x01);
1115         }
1116         return gspca_dev->usb_err;
1117 }
1118
1119 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1120                         struct v4l2_dbg_chip_ident *chip)
1121 {
1122         int ret = -EINVAL;
1123
1124         if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
1125             chip->match.addr == 0) {
1126                 chip->revision = 0;
1127                 chip->ident = V4L2_IDENT_UNKNOWN;
1128                 ret = 0;
1129         }
1130         return ret;
1131 }
1132 #endif
1133
1134 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1135 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1136                         u8 *data,               /* interrupt packet data */
1137                         int len)                /* interrput packet length */
1138 {
1139         int ret = -EINVAL;
1140         u8 data0, data1;
1141
1142         if (len == 2) {
1143                 data0 = data[0];
1144                 data1 = data[1];
1145                 if ((data0 == 0x00 && data1 == 0x11) ||
1146                     (data0 == 0x22 && data1 == 0x33) ||
1147                     (data0 == 0x44 && data1 == 0x55) ||
1148                     (data0 == 0x66 && data1 == 0x77) ||
1149                     (data0 == 0x88 && data1 == 0x99) ||
1150                     (data0 == 0xaa && data1 == 0xbb) ||
1151                     (data0 == 0xcc && data1 == 0xdd) ||
1152                     (data0 == 0xee && data1 == 0xff)) {
1153                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1154                         input_sync(gspca_dev->input_dev);
1155                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1156                         input_sync(gspca_dev->input_dev);
1157                         ret = 0;
1158                 }
1159         }
1160
1161         return ret;
1162 }
1163 #endif
1164
1165 /* sub-driver description for pac7302 */
1166 static const struct sd_desc sd_desc = {
1167         .name = MODULE_NAME,
1168         .ctrls = sd_ctrls,
1169         .nctrls = ARRAY_SIZE(sd_ctrls),
1170         .config = sd_config,
1171         .init = sd_init,
1172         .start = sd_start,
1173         .stopN = sd_stopN,
1174         .stop0 = sd_stop0,
1175         .pkt_scan = sd_pkt_scan,
1176         .dq_callback = do_autogain,
1177 #ifdef CONFIG_VIDEO_ADV_DEBUG
1178         .set_register = sd_dbg_s_register,
1179         .get_chip_ident = sd_chip_ident,
1180 #endif
1181 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1182         .int_pkt_scan = sd_int_pkt_scan,
1183 #endif
1184 };
1185
1186 /* -- module initialisation -- */
1187 static const struct usb_device_id device_table[] __devinitconst = {
1188         {USB_DEVICE(0x06f8, 0x3009)},
1189         {USB_DEVICE(0x093a, 0x2620)},
1190         {USB_DEVICE(0x093a, 0x2621)},
1191         {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
1192         {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
1193         {USB_DEVICE(0x093a, 0x2625)},
1194         {USB_DEVICE(0x093a, 0x2626)},
1195         {USB_DEVICE(0x093a, 0x2628)},
1196         {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
1197         {USB_DEVICE(0x093a, 0x262a)},
1198         {USB_DEVICE(0x093a, 0x262c)},
1199         {}
1200 };
1201 MODULE_DEVICE_TABLE(usb, device_table);
1202
1203 /* -- device connect -- */
1204 static int __devinit sd_probe(struct usb_interface *intf,
1205                         const struct usb_device_id *id)
1206 {
1207         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1208                                 THIS_MODULE);
1209 }
1210
1211 static struct usb_driver sd_driver = {
1212         .name = MODULE_NAME,
1213         .id_table = device_table,
1214         .probe = sd_probe,
1215         .disconnect = gspca_disconnect,
1216 #ifdef CONFIG_PM
1217         .suspend = gspca_suspend,
1218         .resume = gspca_resume,
1219 #endif
1220 };
1221
1222 /* -- module insert / remove -- */
1223 static int __init sd_mod_init(void)
1224 {
1225         return usb_register(&sd_driver);
1226 }
1227 static void __exit sd_mod_exit(void)
1228 {
1229         usb_deregister(&sd_driver);
1230 }
1231
1232 module_init(sd_mod_init);
1233 module_exit(sd_mod_exit);