Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify
[pandora-kernel.git] / drivers / media / video / gspca / sunplus.c
1 /*
2  *              Sunplus spca504(abc) spca533 spca536 library
3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "sunplus"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
29 MODULE_LICENSE("GPL");
30
31 /* specific webcam descriptor */
32 struct sd {
33         struct gspca_dev gspca_dev;     /* !! must be the first item */
34
35         s8 brightness;
36         u8 contrast;
37         u8 colors;
38         u8 autogain;
39         u8 quality;
40 #define QUALITY_MIN 70
41 #define QUALITY_MAX 95
42 #define QUALITY_DEF 85
43
44         u8 bridge;
45 #define BRIDGE_SPCA504 0
46 #define BRIDGE_SPCA504B 1
47 #define BRIDGE_SPCA504C 2
48 #define BRIDGE_SPCA533 3
49 #define BRIDGE_SPCA536 4
50         u8 subtype;
51 #define AiptekMiniPenCam13 1
52 #define LogitechClickSmart420 2
53 #define LogitechClickSmart820 3
54 #define MegapixV4 4
55 #define MegaImageVI 5
56
57         u8 jpeg_hdr[JPEG_HDR_SZ];
58 };
59
60 /* V4L2 controls supported by the driver */
61 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
69
70 static const struct ctrl sd_ctrls[] = {
71         {
72             {
73                 .id      = V4L2_CID_BRIGHTNESS,
74                 .type    = V4L2_CTRL_TYPE_INTEGER,
75                 .name    = "Brightness",
76                 .minimum = -128,
77                 .maximum = 127,
78                 .step    = 1,
79 #define BRIGHTNESS_DEF 0
80                 .default_value = BRIGHTNESS_DEF,
81             },
82             .set = sd_setbrightness,
83             .get = sd_getbrightness,
84         },
85         {
86             {
87                 .id      = V4L2_CID_CONTRAST,
88                 .type    = V4L2_CTRL_TYPE_INTEGER,
89                 .name    = "Contrast",
90                 .minimum = 0,
91                 .maximum = 0xff,
92                 .step    = 1,
93 #define CONTRAST_DEF 0x20
94                 .default_value = CONTRAST_DEF,
95             },
96             .set = sd_setcontrast,
97             .get = sd_getcontrast,
98         },
99         {
100             {
101                 .id      = V4L2_CID_SATURATION,
102                 .type    = V4L2_CTRL_TYPE_INTEGER,
103                 .name    = "Color",
104                 .minimum = 0,
105                 .maximum = 0xff,
106                 .step    = 1,
107 #define COLOR_DEF 0x1a
108                 .default_value = COLOR_DEF,
109             },
110             .set = sd_setcolors,
111             .get = sd_getcolors,
112         },
113         {
114             {
115                 .id      = V4L2_CID_AUTOGAIN,
116                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
117                 .name    = "Auto Gain",
118                 .minimum = 0,
119                 .maximum = 1,
120                 .step    = 1,
121 #define AUTOGAIN_DEF 1
122                 .default_value = AUTOGAIN_DEF,
123             },
124             .set = sd_setautogain,
125             .get = sd_getautogain,
126         },
127 };
128
129 static const struct v4l2_pix_format vga_mode[] = {
130         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
131                 .bytesperline = 320,
132                 .sizeimage = 320 * 240 * 3 / 8 + 590,
133                 .colorspace = V4L2_COLORSPACE_JPEG,
134                 .priv = 2},
135         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136                 .bytesperline = 640,
137                 .sizeimage = 640 * 480 * 3 / 8 + 590,
138                 .colorspace = V4L2_COLORSPACE_JPEG,
139                 .priv = 1},
140 };
141
142 static const struct v4l2_pix_format custom_mode[] = {
143         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
144                 .bytesperline = 320,
145                 .sizeimage = 320 * 240 * 3 / 8 + 590,
146                 .colorspace = V4L2_COLORSPACE_JPEG,
147                 .priv = 2},
148         {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
149                 .bytesperline = 464,
150                 .sizeimage = 464 * 480 * 3 / 8 + 590,
151                 .colorspace = V4L2_COLORSPACE_JPEG,
152                 .priv = 1},
153 };
154
155 static const struct v4l2_pix_format vga_mode2[] = {
156         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157                 .bytesperline = 176,
158                 .sizeimage = 176 * 144 * 3 / 8 + 590,
159                 .colorspace = V4L2_COLORSPACE_JPEG,
160                 .priv = 4},
161         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
162                 .bytesperline = 320,
163                 .sizeimage = 320 * 240 * 3 / 8 + 590,
164                 .colorspace = V4L2_COLORSPACE_JPEG,
165                 .priv = 3},
166         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
167                 .bytesperline = 352,
168                 .sizeimage = 352 * 288 * 3 / 8 + 590,
169                 .colorspace = V4L2_COLORSPACE_JPEG,
170                 .priv = 2},
171         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
172                 .bytesperline = 640,
173                 .sizeimage = 640 * 480 * 3 / 8 + 590,
174                 .colorspace = V4L2_COLORSPACE_JPEG,
175                 .priv = 1},
176 };
177
178 #define SPCA50X_OFFSET_DATA 10
179 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
180 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
181 #define SPCA504_PCCAM600_OFFSET_MODE     5
182 #define SPCA504_PCCAM600_OFFSET_DATA     14
183  /* Frame packet header offsets for the spca533 */
184 #define SPCA533_OFFSET_DATA     16
185 #define SPCA533_OFFSET_FRAMSEQ  15
186 /* Frame packet header offsets for the spca536 */
187 #define SPCA536_OFFSET_DATA     4
188 #define SPCA536_OFFSET_FRAMSEQ  1
189
190 struct cmd {
191         u8 req;
192         u16 val;
193         u16 idx;
194 };
195
196 /* Initialisation data for the Creative PC-CAM 600 */
197 static const struct cmd spca504_pccam600_init_data[] = {
198 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
199         {0x00, 0x0000, 0x2000},
200         {0x00, 0x0013, 0x2301},
201         {0x00, 0x0003, 0x2000},
202         {0x00, 0x0001, 0x21ac},
203         {0x00, 0x0001, 0x21a6},
204         {0x00, 0x0000, 0x21a7}, /* brightness */
205         {0x00, 0x0020, 0x21a8}, /* contrast */
206         {0x00, 0x0001, 0x21ac}, /* sat/hue */
207         {0x00, 0x0000, 0x21ad}, /* hue */
208         {0x00, 0x001a, 0x21ae}, /* saturation */
209         {0x00, 0x0002, 0x21a3}, /* gamma */
210         {0x30, 0x0154, 0x0008},
211         {0x30, 0x0004, 0x0006},
212         {0x30, 0x0258, 0x0009},
213         {0x30, 0x0004, 0x0000},
214         {0x30, 0x0093, 0x0004},
215         {0x30, 0x0066, 0x0005},
216         {0x00, 0x0000, 0x2000},
217         {0x00, 0x0013, 0x2301},
218         {0x00, 0x0003, 0x2000},
219         {0x00, 0x0013, 0x2301},
220         {0x00, 0x0003, 0x2000},
221 };
222
223 /* Creative PC-CAM 600 specific open data, sent before using the
224  * generic initialisation data from spca504_open_data.
225  */
226 static const struct cmd spca504_pccam600_open_data[] = {
227         {0x00, 0x0001, 0x2501},
228         {0x20, 0x0500, 0x0001}, /* snapshot mode */
229         {0x00, 0x0003, 0x2880},
230         {0x00, 0x0001, 0x2881},
231 };
232
233 /* Initialisation data for the logitech clicksmart 420 */
234 static const struct cmd spca504A_clicksmart420_init_data[] = {
235 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
236         {0x00, 0x0000, 0x2000},
237         {0x00, 0x0013, 0x2301},
238         {0x00, 0x0003, 0x2000},
239         {0x00, 0x0001, 0x21ac},
240         {0x00, 0x0001, 0x21a6},
241         {0x00, 0x0000, 0x21a7}, /* brightness */
242         {0x00, 0x0020, 0x21a8}, /* contrast */
243         {0x00, 0x0001, 0x21ac}, /* sat/hue */
244         {0x00, 0x0000, 0x21ad}, /* hue */
245         {0x00, 0x001a, 0x21ae}, /* saturation */
246         {0x00, 0x0002, 0x21a3}, /* gamma */
247         {0x30, 0x0004, 0x000a},
248         {0xb0, 0x0001, 0x0000},
249
250
251         {0xa1, 0x0080, 0x0001},
252         {0x30, 0x0049, 0x0000},
253         {0x30, 0x0060, 0x0005},
254         {0x0c, 0x0004, 0x0000},
255         {0x00, 0x0000, 0x0000},
256         {0x00, 0x0000, 0x2000},
257         {0x00, 0x0013, 0x2301},
258         {0x00, 0x0003, 0x2000},
259         {0x00, 0x0000, 0x2000},
260
261 };
262
263 /* clicksmart 420 open data ? */
264 static const struct cmd spca504A_clicksmart420_open_data[] = {
265         {0x00, 0x0001, 0x2501},
266         {0x20, 0x0502, 0x0000},
267         {0x06, 0x0000, 0x0000},
268         {0x00, 0x0004, 0x2880},
269         {0x00, 0x0001, 0x2881},
270
271         {0xa0, 0x0000, 0x0503},
272 };
273
274 static const u8 qtable_creative_pccam[2][64] = {
275         {                               /* Q-table Y-components */
276          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
277          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
278          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
279          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
280          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
281          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
282          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
283          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
284         {                               /* Q-table C-components */
285          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
286          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
287          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
288          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
289          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
290          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
291          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
292          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
293 };
294
295 /* FIXME: This Q-table is identical to the Creative PC-CAM one,
296  *              except for one byte. Possibly a typo?
297  *              NWG: 18/05/2003.
298  */
299 static const u8 qtable_spca504_default[2][64] = {
300         {                               /* Q-table Y-components */
301          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
302          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
303          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
304          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
305          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
306          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
307          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
308          0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
309          },
310         {                               /* Q-table C-components */
311          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
312          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
313          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
314          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
315          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
316          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
317          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
318          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
319 };
320
321 /* read <len> bytes to gspca_dev->usb_buf */
322 static void reg_r(struct gspca_dev *gspca_dev,
323                   u8 req,
324                   u16 index,
325                   u16 len)
326 {
327         int ret;
328
329 #ifdef GSPCA_DEBUG
330         if (len > USB_BUF_SZ) {
331                 err("reg_r: buffer overflow");
332                 return;
333         }
334 #endif
335         if (gspca_dev->usb_err < 0)
336                 return;
337         ret = usb_control_msg(gspca_dev->dev,
338                         usb_rcvctrlpipe(gspca_dev->dev, 0),
339                         req,
340                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
341                         0,              /* value */
342                         index,
343                         len ? gspca_dev->usb_buf : NULL, len,
344                         500);
345         if (ret < 0) {
346                 PDEBUG(D_ERR, "reg_r err %d", ret);
347                 gspca_dev->usb_err = ret;
348         }
349 }
350
351 /* write one byte */
352 static void reg_w_1(struct gspca_dev *gspca_dev,
353                    u8 req,
354                    u16 value,
355                    u16 index,
356                    u16 byte)
357 {
358         int ret;
359
360         if (gspca_dev->usb_err < 0)
361                 return;
362         gspca_dev->usb_buf[0] = byte;
363         ret = usb_control_msg(gspca_dev->dev,
364                         usb_sndctrlpipe(gspca_dev->dev, 0),
365                         req,
366                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
367                         value, index,
368                         gspca_dev->usb_buf, 1,
369                         500);
370         if (ret < 0) {
371                 PDEBUG(D_ERR, "reg_w_1 err %d", ret);
372                 gspca_dev->usb_err = ret;
373         }
374 }
375
376 /* write req / index / value */
377 static void reg_w_riv(struct gspca_dev *gspca_dev,
378                      u8 req, u16 index, u16 value)
379 {
380         struct usb_device *dev = gspca_dev->dev;
381         int ret;
382
383         if (gspca_dev->usb_err < 0)
384                 return;
385         ret = usb_control_msg(dev,
386                         usb_sndctrlpipe(dev, 0),
387                         req,
388                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
389                         value, index, NULL, 0, 500);
390         if (ret < 0) {
391                 PDEBUG(D_ERR, "reg_w_riv err %d", ret);
392                 gspca_dev->usb_err = ret;
393                 return;
394         }
395         PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
396                 req, index, value);
397 }
398
399 /* read 1 byte */
400 static u8 reg_r_1(struct gspca_dev *gspca_dev,
401                         u16 value)      /* wValue */
402 {
403         int ret;
404
405         if (gspca_dev->usb_err < 0)
406                 return 0;
407         ret = usb_control_msg(gspca_dev->dev,
408                         usb_rcvctrlpipe(gspca_dev->dev, 0),
409                         0x20,                   /* request */
410                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
411                         value,
412                         0,                      /* index */
413                         gspca_dev->usb_buf, 1,
414                         500);                   /* timeout */
415         if (ret < 0) {
416                 PDEBUG(D_ERR, "reg_r_1 err %d", ret);
417                 gspca_dev->usb_err = ret;
418                 return 0;
419         }
420         return gspca_dev->usb_buf[0];
421 }
422
423 /* read 1 or 2 bytes */
424 static u16 reg_r_12(struct gspca_dev *gspca_dev,
425                         u8 req,         /* bRequest */
426                         u16 index,      /* wIndex */
427                         u16 length)     /* wLength (1 or 2 only) */
428 {
429         int ret;
430
431         if (gspca_dev->usb_err < 0)
432                 return 0;
433         gspca_dev->usb_buf[1] = 0;
434         ret = usb_control_msg(gspca_dev->dev,
435                         usb_rcvctrlpipe(gspca_dev->dev, 0),
436                         req,
437                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
438                         0,              /* value */
439                         index,
440                         gspca_dev->usb_buf, length,
441                         500);
442         if (ret < 0) {
443                 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
444                 gspca_dev->usb_err = ret;
445                 return 0;
446         }
447         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
448 }
449
450 static void write_vector(struct gspca_dev *gspca_dev,
451                         const struct cmd *data, int ncmds)
452 {
453         while (--ncmds >= 0) {
454                 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
455                 data++;
456         }
457 }
458
459 static void setup_qtable(struct gspca_dev *gspca_dev,
460                         const u8 qtable[2][64])
461 {
462         int i;
463
464         /* loop over y components */
465         for (i = 0; i < 64; i++)
466                  reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
467
468         /* loop over c components */
469         for (i = 0; i < 64; i++)
470                 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
471 }
472
473 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
474                              u8 req, u16 idx, u16 val)
475 {
476         u16 notdone;
477
478         reg_w_riv(gspca_dev, req, idx, val);
479         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
480         reg_w_riv(gspca_dev, req, idx, val);
481
482         PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
483
484         msleep(200);
485         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
486         PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
487 }
488
489 static void spca504_read_info(struct gspca_dev *gspca_dev)
490 {
491         int i;
492         u8 info[6];
493
494         for (i = 0; i < 6; i++)
495                 info[i] = reg_r_1(gspca_dev, i);
496         PDEBUG(D_STREAM,
497                 "Read info: %d %d %d %d %d %d."
498                 " Should be 1,0,2,2,0,0",
499                 info[0], info[1], info[2],
500                 info[3], info[4], info[5]);
501 }
502
503 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
504                         u8 req,
505                         u16 idx, u16 val, u16 endcode, u8 count)
506 {
507         u16 status;
508
509         reg_w_riv(gspca_dev, req, idx, val);
510         status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
511         if (gspca_dev->usb_err < 0)
512                 return;
513         PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode);
514         if (!count)
515                 return;
516         count = 200;
517         while (--count > 0) {
518                 msleep(10);
519                 /* gsmart mini2 write a each wait setting 1 ms is enough */
520 /*              reg_w_riv(gspca_dev, req, idx, val); */
521                 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
522                 if (status == endcode) {
523                         PDEBUG(D_FRAM, "status 0x%04x after wait %d",
524                                 status, 200 - count);
525                                 break;
526                 }
527         }
528 }
529
530 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
531 {
532         int count = 10;
533
534         while (--count > 0) {
535                 reg_r(gspca_dev, 0x21, 0, 1);
536                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
537                         break;
538                 msleep(10);
539         }
540 }
541
542 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
543 {
544         int count = 50;
545
546         while (--count > 0) {
547                 reg_r(gspca_dev, 0x21, 1, 1);
548                 if (gspca_dev->usb_buf[0] != 0) {
549                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
550                         reg_r(gspca_dev, 0x21, 1, 1);
551                         spca504B_PollingDataReady(gspca_dev);
552                         break;
553                 }
554                 msleep(10);
555         }
556 }
557
558 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
559 {
560         u8 *data;
561
562         data = gspca_dev->usb_buf;
563         reg_r(gspca_dev, 0x20, 0, 5);
564         PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
565                 data[0], data[1], data[2], data[3], data[4]);
566         reg_r(gspca_dev, 0x23, 0, 64);
567         reg_r(gspca_dev, 0x23, 1, 64);
568 }
569
570 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
571 {
572         struct sd *sd = (struct sd *) gspca_dev;
573         u8 Size;
574
575         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
576         switch (sd->bridge) {
577         case BRIDGE_SPCA533:
578                 reg_w_riv(gspca_dev, 0x31, 0, 0);
579                 spca504B_WaitCmdStatus(gspca_dev);
580                 spca504B_PollingDataReady(gspca_dev);
581                 spca50x_GetFirmware(gspca_dev);
582                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
583                 reg_r(gspca_dev, 0x24, 8, 1);
584
585                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
586                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
587                 spca504B_PollingDataReady(gspca_dev);
588
589                 /* Init the cam width height with some values get on init ? */
590                 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
591                 spca504B_WaitCmdStatus(gspca_dev);
592                 spca504B_PollingDataReady(gspca_dev);
593                 break;
594         default:
595 /* case BRIDGE_SPCA504B: */
596 /* case BRIDGE_SPCA536: */
597                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
598                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
599                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
600                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
601                 spca504B_PollingDataReady(gspca_dev);
602                 break;
603         case BRIDGE_SPCA504:
604                 Size += 3;
605                 if (sd->subtype == AiptekMiniPenCam13) {
606                         /* spca504a aiptek */
607                         spca504A_acknowledged_command(gspca_dev,
608                                                 0x08, Size, 0,
609                                                 0x80 | (Size & 0x0f), 1);
610                         spca504A_acknowledged_command(gspca_dev,
611                                                         1, 3, 0, 0x9f, 0);
612                 } else {
613                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
614                 }
615                 break;
616         case BRIDGE_SPCA504C:
617                 /* capture mode */
618                 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
619                 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
620                 break;
621         }
622 }
623
624 static void spca504_wait_status(struct gspca_dev *gspca_dev)
625 {
626         int cnt;
627
628         cnt = 256;
629         while (--cnt > 0) {
630                 /* With this we get the status, when return 0 it's all ok */
631                 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
632                         return;
633                 msleep(10);
634         }
635 }
636
637 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
638 {
639         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
640         reg_r(gspca_dev, 0x26, 0, 1);
641         spca504B_PollingDataReady(gspca_dev);
642 }
643
644 static void setbrightness(struct gspca_dev *gspca_dev)
645 {
646         struct sd *sd = (struct sd *) gspca_dev;
647         u16 reg;
648
649         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
650         reg_w_riv(gspca_dev, 0x00, reg, sd->brightness);
651 }
652
653 static void setcontrast(struct gspca_dev *gspca_dev)
654 {
655         struct sd *sd = (struct sd *) gspca_dev;
656         u16 reg;
657
658         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
659         reg_w_riv(gspca_dev, 0x00, reg, sd->contrast);
660 }
661
662 static void setcolors(struct gspca_dev *gspca_dev)
663 {
664         struct sd *sd = (struct sd *) gspca_dev;
665         u16 reg;
666
667         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
668         reg_w_riv(gspca_dev, 0x00, reg, sd->colors);
669 }
670
671 static void init_ctl_reg(struct gspca_dev *gspca_dev)
672 {
673         struct sd *sd = (struct sd *) gspca_dev;
674         int pollreg = 1;
675
676         setbrightness(gspca_dev);
677         setcontrast(gspca_dev);
678         setcolors(gspca_dev);
679
680         switch (sd->bridge) {
681         case BRIDGE_SPCA504:
682         case BRIDGE_SPCA504C:
683                 pollreg = 0;
684                 /* fall thru */
685         default:
686 /*      case BRIDGE_SPCA533: */
687 /*      case BRIDGE_SPCA504B: */
688                 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
689                 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
690                 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
691                 break;
692         case BRIDGE_SPCA536:
693                 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
694                 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
695                 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
696                 break;
697         }
698         if (pollreg)
699                 spca504B_PollingDataReady(gspca_dev);
700 }
701
702 /* this function is called at probe time */
703 static int sd_config(struct gspca_dev *gspca_dev,
704                         const struct usb_device_id *id)
705 {
706         struct sd *sd = (struct sd *) gspca_dev;
707         struct cam *cam;
708
709         cam = &gspca_dev->cam;
710
711         sd->bridge = id->driver_info >> 8;
712         sd->subtype = id->driver_info;
713
714         if (sd->subtype == AiptekMiniPenCam13) {
715 /* try to get the firmware as some cam answer 2.0.1.2.2
716  * and should be a spca504b then overwrite that setting */
717                 reg_r(gspca_dev, 0x20, 0, 1);
718                 switch (gspca_dev->usb_buf[0]) {
719                 case 1:
720                         break;          /* (right bridge/subtype) */
721                 case 2:
722                         sd->bridge = BRIDGE_SPCA504B;
723                         sd->subtype = 0;
724                         break;
725                 default:
726                         return -ENODEV;
727                 }
728         }
729
730         switch (sd->bridge) {
731         default:
732 /*      case BRIDGE_SPCA504B: */
733 /*      case BRIDGE_SPCA504: */
734 /*      case BRIDGE_SPCA536: */
735                 cam->cam_mode = vga_mode;
736                 cam->nmodes =ARRAY_SIZE(vga_mode);
737                 break;
738         case BRIDGE_SPCA533:
739                 cam->cam_mode = custom_mode;
740                 if (sd->subtype == MegaImageVI)         /* 320x240 only */
741                         cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
742                 else
743                         cam->nmodes = ARRAY_SIZE(custom_mode);
744                 break;
745         case BRIDGE_SPCA504C:
746                 cam->cam_mode = vga_mode2;
747                 cam->nmodes = ARRAY_SIZE(vga_mode2);
748                 break;
749         }
750         sd->brightness = BRIGHTNESS_DEF;
751         sd->contrast = CONTRAST_DEF;
752         sd->colors = COLOR_DEF;
753         sd->autogain = AUTOGAIN_DEF;
754         sd->quality = QUALITY_DEF;
755         return 0;
756 }
757
758 /* this function is called at probe and resume time */
759 static int sd_init(struct gspca_dev *gspca_dev)
760 {
761         struct sd *sd = (struct sd *) gspca_dev;
762
763         switch (sd->bridge) {
764         case BRIDGE_SPCA504B:
765                 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
766                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
767                 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
768                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
769                 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
770                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
771                 /* fall thru */
772         case BRIDGE_SPCA533:
773                 spca504B_PollingDataReady(gspca_dev);
774                 spca50x_GetFirmware(gspca_dev);
775                 break;
776         case BRIDGE_SPCA536:
777                 spca50x_GetFirmware(gspca_dev);
778                 reg_r(gspca_dev, 0x00, 0x5002, 1);
779                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
780                 reg_r(gspca_dev, 0x24, 0, 1);
781                 spca504B_PollingDataReady(gspca_dev);
782                 reg_w_riv(gspca_dev, 0x34, 0, 0);
783                 spca504B_WaitCmdStatus(gspca_dev);
784                 break;
785         case BRIDGE_SPCA504C:   /* pccam600 */
786                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
787                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
788                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);     /* reset */
789                 spca504_wait_status(gspca_dev);
790                 if (sd->subtype == LogitechClickSmart420)
791                         write_vector(gspca_dev,
792                                 spca504A_clicksmart420_open_data,
793                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
794                 else
795                         write_vector(gspca_dev, spca504_pccam600_open_data,
796                                 ARRAY_SIZE(spca504_pccam600_open_data));
797                 setup_qtable(gspca_dev, qtable_creative_pccam);
798                 break;
799         default:
800 /*      case BRIDGE_SPCA504: */
801                 PDEBUG(D_STREAM, "Opening SPCA504");
802                 if (sd->subtype == AiptekMiniPenCam13) {
803                         spca504_read_info(gspca_dev);
804
805                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
806                         spca504A_acknowledged_command(gspca_dev, 0x24,
807                                                         8, 3, 0x9e, 1);
808                         /* Twice sequential need status 0xff->0x9e->0x9d */
809                         spca504A_acknowledged_command(gspca_dev, 0x24,
810                                                         8, 3, 0x9e, 0);
811
812                         spca504A_acknowledged_command(gspca_dev, 0x24,
813                                                         0, 0, 0x9d, 1);
814                         /******************************/
815                         /* spca504a aiptek */
816                         spca504A_acknowledged_command(gspca_dev, 0x08,
817                                                         6, 0, 0x86, 1);
818 /*                      reg_write (dev, 0, 0x2000, 0); */
819 /*                      reg_write (dev, 0, 0x2883, 1); */
820 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
821                                                         6, 0, 0x86, 1); */
822 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
823                                                         0, 0, 0x9D, 1); */
824                         reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
825                                                         /* L92 sno1t.txt */
826                         reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
827                         spca504A_acknowledged_command(gspca_dev, 0x01,
828                                                         0x0f, 0, 0xff, 0);
829                 }
830                 /* setup qtable */
831                 reg_w_riv(gspca_dev, 0, 0x2000, 0);
832                 reg_w_riv(gspca_dev, 0, 0x2883, 1);
833                 setup_qtable(gspca_dev, qtable_spca504_default);
834                 break;
835         }
836         return gspca_dev->usb_err;
837 }
838
839 static int sd_start(struct gspca_dev *gspca_dev)
840 {
841         struct sd *sd = (struct sd *) gspca_dev;
842         int enable;
843
844         /* create the JPEG header */
845         jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
846                         0x22);          /* JPEG 411 */
847         jpeg_set_qual(sd->jpeg_hdr, sd->quality);
848
849         if (sd->bridge == BRIDGE_SPCA504B)
850                 spca504B_setQtable(gspca_dev);
851         spca504B_SetSizeType(gspca_dev);
852         switch (sd->bridge) {
853         default:
854 /*      case BRIDGE_SPCA504B: */
855 /*      case BRIDGE_SPCA533: */
856 /*      case BRIDGE_SPCA536: */
857                 switch (sd->subtype) {
858                 case MegapixV4:
859                 case LogitechClickSmart820:
860                 case MegaImageVI:
861                         reg_w_riv(gspca_dev, 0xf0, 0, 0);
862                         spca504B_WaitCmdStatus(gspca_dev);
863                         reg_r(gspca_dev, 0xf0, 4, 0);
864                         spca504B_WaitCmdStatus(gspca_dev);
865                         break;
866                 default:
867                         reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
868                         spca504B_WaitCmdStatus(gspca_dev);
869                         spca504B_PollingDataReady(gspca_dev);
870                         break;
871                 }
872                 break;
873         case BRIDGE_SPCA504:
874                 if (sd->subtype == AiptekMiniPenCam13) {
875                         spca504_read_info(gspca_dev);
876
877                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
878                         spca504A_acknowledged_command(gspca_dev, 0x24,
879                                                         8, 3, 0x9e, 1);
880                         /* Twice sequential need status 0xff->0x9e->0x9d */
881                         spca504A_acknowledged_command(gspca_dev, 0x24,
882                                                         8, 3, 0x9e, 0);
883                         spca504A_acknowledged_command(gspca_dev, 0x24,
884                                                         0, 0, 0x9d, 1);
885                 } else {
886                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
887                         spca504_read_info(gspca_dev);
888                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
889                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
890                 }
891                 spca504B_SetSizeType(gspca_dev);
892                 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
893                                                         /* L92 sno1t.txt */
894                 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
895                 break;
896         case BRIDGE_SPCA504C:
897                 if (sd->subtype == LogitechClickSmart420) {
898                         write_vector(gspca_dev,
899                                 spca504A_clicksmart420_init_data,
900                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
901                 } else {
902                         write_vector(gspca_dev, spca504_pccam600_init_data,
903                                 ARRAY_SIZE(spca504_pccam600_init_data));
904                 }
905                 enable = (sd->autogain ? 0x04 : 0x01);
906                 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
907                                                         /* auto exposure */
908                 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
909                                                         /* auto whiteness */
910
911                 /* set default exposure compensation and whiteness balance */
912                 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);        /* ~ 20 fps */
913                 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
914                 spca504B_SetSizeType(gspca_dev);
915                 break;
916         }
917         init_ctl_reg(gspca_dev);
918         return gspca_dev->usb_err;
919 }
920
921 static void sd_stopN(struct gspca_dev *gspca_dev)
922 {
923         struct sd *sd = (struct sd *) gspca_dev;
924
925         switch (sd->bridge) {
926         default:
927 /*      case BRIDGE_SPCA533: */
928 /*      case BRIDGE_SPCA536: */
929 /*      case BRIDGE_SPCA504B: */
930                 reg_w_riv(gspca_dev, 0x31, 0, 0);
931                 spca504B_WaitCmdStatus(gspca_dev);
932                 spca504B_PollingDataReady(gspca_dev);
933                 break;
934         case BRIDGE_SPCA504:
935         case BRIDGE_SPCA504C:
936                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
937
938                 if (sd->subtype == AiptekMiniPenCam13) {
939                         /* spca504a aiptek */
940 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
941                                                          6, 0, 0x86, 1); */
942                         spca504A_acknowledged_command(gspca_dev, 0x24,
943                                                         0x00, 0x00, 0x9d, 1);
944                         spca504A_acknowledged_command(gspca_dev, 0x01,
945                                                         0x0f, 0x00, 0xff, 1);
946                 } else {
947                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
948                         reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
949                 }
950                 break;
951         }
952 }
953
954 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
955                         u8 *data,                       /* isoc packet */
956                         int len)                        /* iso packet length */
957 {
958         struct sd *sd = (struct sd *) gspca_dev;
959         int i, sof = 0;
960         static u8 ffd9[] = {0xff, 0xd9};
961
962 /* frames are jpeg 4.1.1 without 0xff escape */
963         switch (sd->bridge) {
964         case BRIDGE_SPCA533:
965                 if (data[0] == 0xff) {
966                         if (data[1] != 0x01) {  /* drop packet */
967 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
968                                 return;
969                         }
970                         sof = 1;
971                         data += SPCA533_OFFSET_DATA;
972                         len -= SPCA533_OFFSET_DATA;
973                 } else {
974                         data += 1;
975                         len -= 1;
976                 }
977                 break;
978         case BRIDGE_SPCA536:
979                 if (data[0] == 0xff) {
980                         sof = 1;
981                         data += SPCA536_OFFSET_DATA;
982                         len -= SPCA536_OFFSET_DATA;
983                 } else {
984                         data += 2;
985                         len -= 2;
986                 }
987                 break;
988         default:
989 /*      case BRIDGE_SPCA504: */
990 /*      case BRIDGE_SPCA504B: */
991                 switch (data[0]) {
992                 case 0xfe:                      /* start of frame */
993                         sof = 1;
994                         data += SPCA50X_OFFSET_DATA;
995                         len -= SPCA50X_OFFSET_DATA;
996                         break;
997                 case 0xff:                      /* drop packet */
998 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
999                         return;
1000                 default:
1001                         data += 1;
1002                         len -= 1;
1003                         break;
1004                 }
1005                 break;
1006         case BRIDGE_SPCA504C:
1007                 switch (data[0]) {
1008                 case 0xfe:                      /* start of frame */
1009                         sof = 1;
1010                         data += SPCA504_PCCAM600_OFFSET_DATA;
1011                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1012                         break;
1013                 case 0xff:                      /* drop packet */
1014 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1015                         return;
1016                 default:
1017                         data += 1;
1018                         len -= 1;
1019                         break;
1020                 }
1021                 break;
1022         }
1023         if (sof) {              /* start of frame */
1024                 gspca_frame_add(gspca_dev, LAST_PACKET,
1025                                 ffd9, 2);
1026
1027                 /* put the JPEG header in the new frame */
1028                 gspca_frame_add(gspca_dev, FIRST_PACKET,
1029                         sd->jpeg_hdr, JPEG_HDR_SZ);
1030         }
1031
1032         /* add 0x00 after 0xff */
1033         i = 0;
1034         do {
1035                 if (data[i] == 0xff) {
1036                         gspca_frame_add(gspca_dev, INTER_PACKET,
1037                                         data, i + 1);
1038                         len -= i;
1039                         data += i;
1040                         *data = 0x00;
1041                         i = 0;
1042                 }
1043                 i++;
1044         } while (i < len);
1045         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1046 }
1047
1048 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1049 {
1050         struct sd *sd = (struct sd *) gspca_dev;
1051
1052         sd->brightness = val;
1053         if (gspca_dev->streaming)
1054                 setbrightness(gspca_dev);
1055         return gspca_dev->usb_err;
1056 }
1057
1058 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1059 {
1060         struct sd *sd = (struct sd *) gspca_dev;
1061
1062         *val = sd->brightness;
1063         return 0;
1064 }
1065
1066 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1067 {
1068         struct sd *sd = (struct sd *) gspca_dev;
1069
1070         sd->contrast = val;
1071         if (gspca_dev->streaming)
1072                 setcontrast(gspca_dev);
1073         return gspca_dev->usb_err;
1074 }
1075
1076 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1077 {
1078         struct sd *sd = (struct sd *) gspca_dev;
1079
1080         *val = sd->contrast;
1081         return 0;
1082 }
1083
1084 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1085 {
1086         struct sd *sd = (struct sd *) gspca_dev;
1087
1088         sd->colors = val;
1089         if (gspca_dev->streaming)
1090                 setcolors(gspca_dev);
1091         return gspca_dev->usb_err;
1092 }
1093
1094 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1095 {
1096         struct sd *sd = (struct sd *) gspca_dev;
1097
1098         *val = sd->colors;
1099         return 0;
1100 }
1101
1102 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1103 {
1104         struct sd *sd = (struct sd *) gspca_dev;
1105
1106         sd->autogain = val;
1107         return 0;
1108 }
1109
1110 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1111 {
1112         struct sd *sd = (struct sd *) gspca_dev;
1113
1114         *val = sd->autogain;
1115         return 0;
1116 }
1117
1118 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1119                         struct v4l2_jpegcompression *jcomp)
1120 {
1121         struct sd *sd = (struct sd *) gspca_dev;
1122
1123         if (jcomp->quality < QUALITY_MIN)
1124                 sd->quality = QUALITY_MIN;
1125         else if (jcomp->quality > QUALITY_MAX)
1126                 sd->quality = QUALITY_MAX;
1127         else
1128                 sd->quality = jcomp->quality;
1129         if (gspca_dev->streaming)
1130                 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1131         return gspca_dev->usb_err;
1132 }
1133
1134 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1135                         struct v4l2_jpegcompression *jcomp)
1136 {
1137         struct sd *sd = (struct sd *) gspca_dev;
1138
1139         memset(jcomp, 0, sizeof *jcomp);
1140         jcomp->quality = sd->quality;
1141         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1142                         | V4L2_JPEG_MARKER_DQT;
1143         return 0;
1144 }
1145
1146 /* sub-driver description */
1147 static const struct sd_desc sd_desc = {
1148         .name = MODULE_NAME,
1149         .ctrls = sd_ctrls,
1150         .nctrls = ARRAY_SIZE(sd_ctrls),
1151         .config = sd_config,
1152         .init = sd_init,
1153         .start = sd_start,
1154         .stopN = sd_stopN,
1155         .pkt_scan = sd_pkt_scan,
1156         .get_jcomp = sd_get_jcomp,
1157         .set_jcomp = sd_set_jcomp,
1158 };
1159
1160 /* -- module initialisation -- */
1161 #define BS(bridge, subtype) \
1162         .driver_info = (BRIDGE_ ## bridge << 8) \
1163                         | (subtype)
1164 static const __devinitdata struct usb_device_id device_table[] = {
1165         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1166         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1167         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1168         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1169         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1170         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1171         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1172         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1173         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1174         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1175         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1176         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1177         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1178         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1179         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1180         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1181         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1182         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1183         {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1184         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1185         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1186         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1187         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1188         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1189         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1190         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1191         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1192         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1193         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1194         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1195         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1196         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1197         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1198         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1199         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1200         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1201         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1202         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1203         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1204         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1205         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1206         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1207         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1208         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1209         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1210         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1211         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1212         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1213         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1214         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1215         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1216         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1217         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1218         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1219         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1220         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1221         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1222         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1223         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1224         {}
1225 };
1226 MODULE_DEVICE_TABLE(usb, device_table);
1227
1228 /* -- device connect -- */
1229 static int sd_probe(struct usb_interface *intf,
1230                         const struct usb_device_id *id)
1231 {
1232         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1233                                 THIS_MODULE);
1234 }
1235
1236 static struct usb_driver sd_driver = {
1237         .name = MODULE_NAME,
1238         .id_table = device_table,
1239         .probe = sd_probe,
1240         .disconnect = gspca_disconnect,
1241 #ifdef CONFIG_PM
1242         .suspend = gspca_suspend,
1243         .resume = gspca_resume,
1244 #endif
1245 };
1246
1247 /* -- module insert / remove -- */
1248 static int __init sd_mod_init(void)
1249 {
1250         int ret;
1251         ret = usb_register(&sd_driver);
1252         if (ret < 0)
1253                 return ret;
1254         PDEBUG(D_PROBE, "registered");
1255         return 0;
1256 }
1257 static void __exit sd_mod_exit(void)
1258 {
1259         usb_deregister(&sd_driver);
1260         PDEBUG(D_PROBE, "deregistered");
1261 }
1262
1263 module_init(sd_mod_init);
1264 module_exit(sd_mod_exit);