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