Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[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                 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                 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                 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 static void write_vector(struct gspca_dev *gspca_dev,
400                         const struct cmd *data, int ncmds)
401 {
402         while (--ncmds >= 0) {
403                 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
404                 data++;
405         }
406 }
407
408 static void setup_qtable(struct gspca_dev *gspca_dev,
409                         const u8 qtable[2][64])
410 {
411         int i;
412
413         /* loop over y components */
414         for (i = 0; i < 64; i++)
415                 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
416
417         /* loop over c components */
418         for (i = 0; i < 64; i++)
419                 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
420 }
421
422 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
423                              u8 req, u16 idx, u16 val)
424 {
425         reg_w_riv(gspca_dev, req, idx, val);
426         reg_r(gspca_dev, 0x01, 0x0001, 1);
427         PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
428         reg_w_riv(gspca_dev, req, idx, val);
429
430         msleep(200);
431         reg_r(gspca_dev, 0x01, 0x0001, 1);
432         PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
433 }
434
435 #ifdef GSPCA_DEBUG
436 static void spca504_read_info(struct gspca_dev *gspca_dev)
437 {
438         int i;
439         u8 info[6];
440
441         for (i = 0; i < 6; i++) {
442                 reg_r(gspca_dev, 0, i, 1);
443                 info[i] = gspca_dev->usb_buf[0];
444         }
445         PDEBUG(D_STREAM,
446                 "Read info: %d %d %d %d %d %d."
447                 " Should be 1,0,2,2,0,0",
448                 info[0], info[1], info[2],
449                 info[3], info[4], info[5]);
450 }
451 #endif
452
453 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
454                         u8 req,
455                         u16 idx, u16 val, u8 endcode, u8 count)
456 {
457         u16 status;
458
459         reg_w_riv(gspca_dev, req, idx, val);
460         reg_r(gspca_dev, 0x01, 0x0001, 1);
461         if (gspca_dev->usb_err < 0)
462                 return;
463         PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
464                         gspca_dev->usb_buf[0], endcode);
465         if (!count)
466                 return;
467         count = 200;
468         while (--count > 0) {
469                 msleep(10);
470                 /* gsmart mini2 write a each wait setting 1 ms is enough */
471 /*              reg_w_riv(gspca_dev, req, idx, val); */
472                 reg_r(gspca_dev, 0x01, 0x0001, 1);
473                 status = gspca_dev->usb_buf[0];
474                 if (status == endcode) {
475                         PDEBUG(D_FRAM, "status 0x%04x after wait %d",
476                                 status, 200 - count);
477                                 break;
478                 }
479         }
480 }
481
482 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
483 {
484         int count = 10;
485
486         while (--count > 0) {
487                 reg_r(gspca_dev, 0x21, 0, 1);
488                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
489                         break;
490                 msleep(10);
491         }
492 }
493
494 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
495 {
496         int count = 50;
497
498         while (--count > 0) {
499                 reg_r(gspca_dev, 0x21, 1, 1);
500                 if (gspca_dev->usb_buf[0] != 0) {
501                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
502                         reg_r(gspca_dev, 0x21, 1, 1);
503                         spca504B_PollingDataReady(gspca_dev);
504                         break;
505                 }
506                 msleep(10);
507         }
508 }
509
510 #ifdef GSPCA_DEBUG
511 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
512 {
513         u8 *data;
514
515         data = gspca_dev->usb_buf;
516         reg_r(gspca_dev, 0x20, 0, 5);
517         PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
518                 data[0], data[1], data[2], data[3], data[4]);
519         reg_r(gspca_dev, 0x23, 0, 64);
520         reg_r(gspca_dev, 0x23, 1, 64);
521 }
522 #endif
523
524 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
525 {
526         struct sd *sd = (struct sd *) gspca_dev;
527         u8 Size;
528
529         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
530         switch (sd->bridge) {
531         case BRIDGE_SPCA533:
532                 reg_w_riv(gspca_dev, 0x31, 0, 0);
533                 spca504B_WaitCmdStatus(gspca_dev);
534                 spca504B_PollingDataReady(gspca_dev);
535 #ifdef GSPCA_DEBUG
536                 spca50x_GetFirmware(gspca_dev);
537 #endif
538                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
539                 reg_r(gspca_dev, 0x24, 8, 1);
540
541                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
542                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
543                 spca504B_PollingDataReady(gspca_dev);
544
545                 /* Init the cam width height with some values get on init ? */
546                 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
547                 spca504B_WaitCmdStatus(gspca_dev);
548                 spca504B_PollingDataReady(gspca_dev);
549                 break;
550         default:
551 /* case BRIDGE_SPCA504B: */
552 /* case BRIDGE_SPCA536: */
553                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
554                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
555                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
556                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
557                 spca504B_PollingDataReady(gspca_dev);
558                 break;
559         case BRIDGE_SPCA504:
560                 Size += 3;
561                 if (sd->subtype == AiptekMiniPenCam13) {
562                         /* spca504a aiptek */
563                         spca504A_acknowledged_command(gspca_dev,
564                                                 0x08, Size, 0,
565                                                 0x80 | (Size & 0x0f), 1);
566                         spca504A_acknowledged_command(gspca_dev,
567                                                         1, 3, 0, 0x9f, 0);
568                 } else {
569                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
570                 }
571                 break;
572         case BRIDGE_SPCA504C:
573                 /* capture mode */
574                 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
575                 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
576                 break;
577         }
578 }
579
580 static void spca504_wait_status(struct gspca_dev *gspca_dev)
581 {
582         int cnt;
583
584         cnt = 256;
585         while (--cnt > 0) {
586                 /* With this we get the status, when return 0 it's all ok */
587                 reg_r(gspca_dev, 0x06, 0x00, 1);
588                 if (gspca_dev->usb_buf[0] == 0)
589                         return;
590                 msleep(10);
591         }
592 }
593
594 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
595 {
596         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
597         reg_r(gspca_dev, 0x26, 0, 1);
598         spca504B_PollingDataReady(gspca_dev);
599 }
600
601 static void setbrightness(struct gspca_dev *gspca_dev)
602 {
603         struct sd *sd = (struct sd *) gspca_dev;
604         u16 reg;
605
606         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
607         reg_w_riv(gspca_dev, 0x00, reg, sd->brightness);
608 }
609
610 static void setcontrast(struct gspca_dev *gspca_dev)
611 {
612         struct sd *sd = (struct sd *) gspca_dev;
613         u16 reg;
614
615         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
616         reg_w_riv(gspca_dev, 0x00, reg, sd->contrast);
617 }
618
619 static void setcolors(struct gspca_dev *gspca_dev)
620 {
621         struct sd *sd = (struct sd *) gspca_dev;
622         u16 reg;
623
624         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
625         reg_w_riv(gspca_dev, 0x00, reg, sd->colors);
626 }
627
628 static void init_ctl_reg(struct gspca_dev *gspca_dev)
629 {
630         struct sd *sd = (struct sd *) gspca_dev;
631         int pollreg = 1;
632
633         setbrightness(gspca_dev);
634         setcontrast(gspca_dev);
635         setcolors(gspca_dev);
636
637         switch (sd->bridge) {
638         case BRIDGE_SPCA504:
639         case BRIDGE_SPCA504C:
640                 pollreg = 0;
641                 /* fall thru */
642         default:
643 /*      case BRIDGE_SPCA533: */
644 /*      case BRIDGE_SPCA504B: */
645                 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
646                 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
647                 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
648                 break;
649         case BRIDGE_SPCA536:
650                 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
651                 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
652                 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
653                 break;
654         }
655         if (pollreg)
656                 spca504B_PollingDataReady(gspca_dev);
657 }
658
659 /* this function is called at probe time */
660 static int sd_config(struct gspca_dev *gspca_dev,
661                         const struct usb_device_id *id)
662 {
663         struct sd *sd = (struct sd *) gspca_dev;
664         struct cam *cam;
665
666         cam = &gspca_dev->cam;
667
668         sd->bridge = id->driver_info >> 8;
669         sd->subtype = id->driver_info;
670
671         if (sd->subtype == AiptekMiniPenCam13) {
672
673                 /* try to get the firmware as some cam answer 2.0.1.2.2
674                  * and should be a spca504b then overwrite that setting */
675                 reg_r(gspca_dev, 0x20, 0, 1);
676                 switch (gspca_dev->usb_buf[0]) {
677                 case 1:
678                         break;          /* (right bridge/subtype) */
679                 case 2:
680                         sd->bridge = BRIDGE_SPCA504B;
681                         sd->subtype = 0;
682                         break;
683                 default:
684                         return -ENODEV;
685                 }
686         }
687
688         switch (sd->bridge) {
689         default:
690 /*      case BRIDGE_SPCA504B: */
691 /*      case BRIDGE_SPCA504: */
692 /*      case BRIDGE_SPCA536: */
693                 cam->cam_mode = vga_mode;
694                 cam->nmodes = ARRAY_SIZE(vga_mode);
695                 break;
696         case BRIDGE_SPCA533:
697                 cam->cam_mode = custom_mode;
698                 if (sd->subtype == MegaImageVI)         /* 320x240 only */
699                         cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
700                 else
701                         cam->nmodes = ARRAY_SIZE(custom_mode);
702                 break;
703         case BRIDGE_SPCA504C:
704                 cam->cam_mode = vga_mode2;
705                 cam->nmodes = ARRAY_SIZE(vga_mode2);
706                 break;
707         }
708         sd->brightness = BRIGHTNESS_DEF;
709         sd->contrast = CONTRAST_DEF;
710         sd->colors = COLOR_DEF;
711         sd->autogain = AUTOGAIN_DEF;
712         sd->quality = QUALITY_DEF;
713         return 0;
714 }
715
716 /* this function is called at probe and resume time */
717 static int sd_init(struct gspca_dev *gspca_dev)
718 {
719         struct sd *sd = (struct sd *) gspca_dev;
720
721         switch (sd->bridge) {
722         case BRIDGE_SPCA504B:
723                 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
724                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
725                 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
726                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
727                 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
728                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
729                 /* fall thru */
730         case BRIDGE_SPCA533:
731                 spca504B_PollingDataReady(gspca_dev);
732 #ifdef GSPCA_DEBUG
733                 spca50x_GetFirmware(gspca_dev);
734 #endif
735                 break;
736         case BRIDGE_SPCA536:
737 #ifdef GSPCA_DEBUG
738                 spca50x_GetFirmware(gspca_dev);
739 #endif
740                 reg_r(gspca_dev, 0x00, 0x5002, 1);
741                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
742                 reg_r(gspca_dev, 0x24, 0, 1);
743                 spca504B_PollingDataReady(gspca_dev);
744                 reg_w_riv(gspca_dev, 0x34, 0, 0);
745                 spca504B_WaitCmdStatus(gspca_dev);
746                 break;
747         case BRIDGE_SPCA504C:   /* pccam600 */
748                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
749                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
750                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);     /* reset */
751                 spca504_wait_status(gspca_dev);
752                 if (sd->subtype == LogitechClickSmart420)
753                         write_vector(gspca_dev,
754                                 spca504A_clicksmart420_open_data,
755                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
756                 else
757                         write_vector(gspca_dev, spca504_pccam600_open_data,
758                                 ARRAY_SIZE(spca504_pccam600_open_data));
759                 setup_qtable(gspca_dev, qtable_creative_pccam);
760                 break;
761         default:
762 /*      case BRIDGE_SPCA504: */
763                 PDEBUG(D_STREAM, "Opening SPCA504");
764                 if (sd->subtype == AiptekMiniPenCam13) {
765 #ifdef GSPCA_DEBUG
766                         spca504_read_info(gspca_dev);
767 #endif
768
769                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
770                         spca504A_acknowledged_command(gspca_dev, 0x24,
771                                                         8, 3, 0x9e, 1);
772                         /* Twice sequential need status 0xff->0x9e->0x9d */
773                         spca504A_acknowledged_command(gspca_dev, 0x24,
774                                                         8, 3, 0x9e, 0);
775
776                         spca504A_acknowledged_command(gspca_dev, 0x24,
777                                                         0, 0, 0x9d, 1);
778                         /******************************/
779                         /* spca504a aiptek */
780                         spca504A_acknowledged_command(gspca_dev, 0x08,
781                                                         6, 0, 0x86, 1);
782 /*                      reg_write (dev, 0, 0x2000, 0); */
783 /*                      reg_write (dev, 0, 0x2883, 1); */
784 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
785                                                         6, 0, 0x86, 1); */
786 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
787                                                         0, 0, 0x9D, 1); */
788                         reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
789                                                         /* L92 sno1t.txt */
790                         reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
791                         spca504A_acknowledged_command(gspca_dev, 0x01,
792                                                         0x0f, 0, 0xff, 0);
793                 }
794                 /* setup qtable */
795                 reg_w_riv(gspca_dev, 0, 0x2000, 0);
796                 reg_w_riv(gspca_dev, 0, 0x2883, 1);
797                 setup_qtable(gspca_dev, qtable_spca504_default);
798                 break;
799         }
800         return gspca_dev->usb_err;
801 }
802
803 static int sd_start(struct gspca_dev *gspca_dev)
804 {
805         struct sd *sd = (struct sd *) gspca_dev;
806         int enable;
807
808         /* create the JPEG header */
809         jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
810                         0x22);          /* JPEG 411 */
811         jpeg_set_qual(sd->jpeg_hdr, sd->quality);
812
813         if (sd->bridge == BRIDGE_SPCA504B)
814                 spca504B_setQtable(gspca_dev);
815         spca504B_SetSizeType(gspca_dev);
816         switch (sd->bridge) {
817         default:
818 /*      case BRIDGE_SPCA504B: */
819 /*      case BRIDGE_SPCA533: */
820 /*      case BRIDGE_SPCA536: */
821                 switch (sd->subtype) {
822                 case MegapixV4:
823                 case LogitechClickSmart820:
824                 case MegaImageVI:
825                         reg_w_riv(gspca_dev, 0xf0, 0, 0);
826                         spca504B_WaitCmdStatus(gspca_dev);
827                         reg_r(gspca_dev, 0xf0, 4, 0);
828                         spca504B_WaitCmdStatus(gspca_dev);
829                         break;
830                 default:
831                         reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
832                         spca504B_WaitCmdStatus(gspca_dev);
833                         spca504B_PollingDataReady(gspca_dev);
834                         break;
835                 }
836                 break;
837         case BRIDGE_SPCA504:
838                 if (sd->subtype == AiptekMiniPenCam13) {
839 #ifdef GSPCA_DEBUG
840                         spca504_read_info(gspca_dev);
841 #endif
842
843                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
844                         spca504A_acknowledged_command(gspca_dev, 0x24,
845                                                         8, 3, 0x9e, 1);
846                         /* Twice sequential need status 0xff->0x9e->0x9d */
847                         spca504A_acknowledged_command(gspca_dev, 0x24,
848                                                         8, 3, 0x9e, 0);
849                         spca504A_acknowledged_command(gspca_dev, 0x24,
850                                                         0, 0, 0x9d, 1);
851                 } else {
852                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
853 #ifdef GSPCA_DEBUG
854                         spca504_read_info(gspca_dev);
855 #endif
856                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
857                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
858                 }
859                 spca504B_SetSizeType(gspca_dev);
860                 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
861                                                         /* L92 sno1t.txt */
862                 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
863                 break;
864         case BRIDGE_SPCA504C:
865                 if (sd->subtype == LogitechClickSmart420) {
866                         write_vector(gspca_dev,
867                                 spca504A_clicksmart420_init_data,
868                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
869                 } else {
870                         write_vector(gspca_dev, spca504_pccam600_init_data,
871                                 ARRAY_SIZE(spca504_pccam600_init_data));
872                 }
873                 enable = (sd->autogain ? 0x04 : 0x01);
874                 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
875                                                         /* auto exposure */
876                 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
877                                                         /* auto whiteness */
878
879                 /* set default exposure compensation and whiteness balance */
880                 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);        /* ~ 20 fps */
881                 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
882                 spca504B_SetSizeType(gspca_dev);
883                 break;
884         }
885         init_ctl_reg(gspca_dev);
886         return gspca_dev->usb_err;
887 }
888
889 static void sd_stopN(struct gspca_dev *gspca_dev)
890 {
891         struct sd *sd = (struct sd *) gspca_dev;
892
893         switch (sd->bridge) {
894         default:
895 /*      case BRIDGE_SPCA533: */
896 /*      case BRIDGE_SPCA536: */
897 /*      case BRIDGE_SPCA504B: */
898                 reg_w_riv(gspca_dev, 0x31, 0, 0);
899                 spca504B_WaitCmdStatus(gspca_dev);
900                 spca504B_PollingDataReady(gspca_dev);
901                 break;
902         case BRIDGE_SPCA504:
903         case BRIDGE_SPCA504C:
904                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
905
906                 if (sd->subtype == AiptekMiniPenCam13) {
907                         /* spca504a aiptek */
908 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
909                                                          6, 0, 0x86, 1); */
910                         spca504A_acknowledged_command(gspca_dev, 0x24,
911                                                         0x00, 0x00, 0x9d, 1);
912                         spca504A_acknowledged_command(gspca_dev, 0x01,
913                                                         0x0f, 0x00, 0xff, 1);
914                 } else {
915                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
916                         reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
917                 }
918                 break;
919         }
920 }
921
922 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
923                         u8 *data,                       /* isoc packet */
924                         int len)                        /* iso packet length */
925 {
926         struct sd *sd = (struct sd *) gspca_dev;
927         int i, sof = 0;
928         static u8 ffd9[] = {0xff, 0xd9};
929
930 /* frames are jpeg 4.1.1 without 0xff escape */
931         switch (sd->bridge) {
932         case BRIDGE_SPCA533:
933                 if (data[0] == 0xff) {
934                         if (data[1] != 0x01) {  /* drop packet */
935 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
936                                 return;
937                         }
938                         sof = 1;
939                         data += SPCA533_OFFSET_DATA;
940                         len -= SPCA533_OFFSET_DATA;
941                 } else {
942                         data += 1;
943                         len -= 1;
944                 }
945                 break;
946         case BRIDGE_SPCA536:
947                 if (data[0] == 0xff) {
948                         sof = 1;
949                         data += SPCA536_OFFSET_DATA;
950                         len -= SPCA536_OFFSET_DATA;
951                 } else {
952                         data += 2;
953                         len -= 2;
954                 }
955                 break;
956         default:
957 /*      case BRIDGE_SPCA504: */
958 /*      case BRIDGE_SPCA504B: */
959                 switch (data[0]) {
960                 case 0xfe:                      /* start of frame */
961                         sof = 1;
962                         data += SPCA50X_OFFSET_DATA;
963                         len -= SPCA50X_OFFSET_DATA;
964                         break;
965                 case 0xff:                      /* drop packet */
966 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
967                         return;
968                 default:
969                         data += 1;
970                         len -= 1;
971                         break;
972                 }
973                 break;
974         case BRIDGE_SPCA504C:
975                 switch (data[0]) {
976                 case 0xfe:                      /* start of frame */
977                         sof = 1;
978                         data += SPCA504_PCCAM600_OFFSET_DATA;
979                         len -= SPCA504_PCCAM600_OFFSET_DATA;
980                         break;
981                 case 0xff:                      /* drop packet */
982 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
983                         return;
984                 default:
985                         data += 1;
986                         len -= 1;
987                         break;
988                 }
989                 break;
990         }
991         if (sof) {              /* start of frame */
992                 gspca_frame_add(gspca_dev, LAST_PACKET,
993                                 ffd9, 2);
994
995                 /* put the JPEG header in the new frame */
996                 gspca_frame_add(gspca_dev, FIRST_PACKET,
997                         sd->jpeg_hdr, JPEG_HDR_SZ);
998         }
999
1000         /* add 0x00 after 0xff */
1001         i = 0;
1002         do {
1003                 if (data[i] == 0xff) {
1004                         gspca_frame_add(gspca_dev, INTER_PACKET,
1005                                         data, i + 1);
1006                         len -= i;
1007                         data += i;
1008                         *data = 0x00;
1009                         i = 0;
1010                 }
1011                 i++;
1012         } while (i < len);
1013         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1014 }
1015
1016 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1017 {
1018         struct sd *sd = (struct sd *) gspca_dev;
1019
1020         sd->brightness = val;
1021         if (gspca_dev->streaming)
1022                 setbrightness(gspca_dev);
1023         return gspca_dev->usb_err;
1024 }
1025
1026 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1027 {
1028         struct sd *sd = (struct sd *) gspca_dev;
1029
1030         *val = sd->brightness;
1031         return 0;
1032 }
1033
1034 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1035 {
1036         struct sd *sd = (struct sd *) gspca_dev;
1037
1038         sd->contrast = val;
1039         if (gspca_dev->streaming)
1040                 setcontrast(gspca_dev);
1041         return gspca_dev->usb_err;
1042 }
1043
1044 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1045 {
1046         struct sd *sd = (struct sd *) gspca_dev;
1047
1048         *val = sd->contrast;
1049         return 0;
1050 }
1051
1052 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1053 {
1054         struct sd *sd = (struct sd *) gspca_dev;
1055
1056         sd->colors = val;
1057         if (gspca_dev->streaming)
1058                 setcolors(gspca_dev);
1059         return gspca_dev->usb_err;
1060 }
1061
1062 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1063 {
1064         struct sd *sd = (struct sd *) gspca_dev;
1065
1066         *val = sd->colors;
1067         return 0;
1068 }
1069
1070 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1071 {
1072         struct sd *sd = (struct sd *) gspca_dev;
1073
1074         sd->autogain = val;
1075         return 0;
1076 }
1077
1078 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1079 {
1080         struct sd *sd = (struct sd *) gspca_dev;
1081
1082         *val = sd->autogain;
1083         return 0;
1084 }
1085
1086 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1087                         struct v4l2_jpegcompression *jcomp)
1088 {
1089         struct sd *sd = (struct sd *) gspca_dev;
1090
1091         if (jcomp->quality < QUALITY_MIN)
1092                 sd->quality = QUALITY_MIN;
1093         else if (jcomp->quality > QUALITY_MAX)
1094                 sd->quality = QUALITY_MAX;
1095         else
1096                 sd->quality = jcomp->quality;
1097         if (gspca_dev->streaming)
1098                 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1099         return gspca_dev->usb_err;
1100 }
1101
1102 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1103                         struct v4l2_jpegcompression *jcomp)
1104 {
1105         struct sd *sd = (struct sd *) gspca_dev;
1106
1107         memset(jcomp, 0, sizeof *jcomp);
1108         jcomp->quality = sd->quality;
1109         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1110                         | V4L2_JPEG_MARKER_DQT;
1111         return 0;
1112 }
1113
1114 /* sub-driver description */
1115 static const struct sd_desc sd_desc = {
1116         .name = MODULE_NAME,
1117         .ctrls = sd_ctrls,
1118         .nctrls = ARRAY_SIZE(sd_ctrls),
1119         .config = sd_config,
1120         .init = sd_init,
1121         .start = sd_start,
1122         .stopN = sd_stopN,
1123         .pkt_scan = sd_pkt_scan,
1124         .get_jcomp = sd_get_jcomp,
1125         .set_jcomp = sd_set_jcomp,
1126 };
1127
1128 /* -- module initialisation -- */
1129 #define BS(bridge, subtype) \
1130         .driver_info = (BRIDGE_ ## bridge << 8) \
1131                         | (subtype)
1132 static const struct usb_device_id device_table[] = {
1133         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1134         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1135         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1136         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1137         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1138         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1139         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1140         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1141         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1142         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1143         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1144         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1145         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1146         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1147         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1148         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1149         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1150         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1151         {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1152         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1153         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1154         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1155         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1156         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1157         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1158         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1159         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1160         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1161         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1162         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1163         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1164         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1165         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1166         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1167         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1168         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1169         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1170         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1171         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1172         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1173         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1174         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1175         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1176         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1177         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1178         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1179         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1180         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1181         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1182         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1183         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1184         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1185         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1186         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1187         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1188         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1189         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1190         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1191         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1192         {}
1193 };
1194 MODULE_DEVICE_TABLE(usb, device_table);
1195
1196 /* -- device connect -- */
1197 static int sd_probe(struct usb_interface *intf,
1198                         const struct usb_device_id *id)
1199 {
1200         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1201                                 THIS_MODULE);
1202 }
1203
1204 static struct usb_driver sd_driver = {
1205         .name = MODULE_NAME,
1206         .id_table = device_table,
1207         .probe = sd_probe,
1208         .disconnect = gspca_disconnect,
1209 #ifdef CONFIG_PM
1210         .suspend = gspca_suspend,
1211         .resume = gspca_resume,
1212 #endif
1213 };
1214
1215 /* -- module insert / remove -- */
1216 static int __init sd_mod_init(void)
1217 {
1218         return usb_register(&sd_driver);
1219 }
1220 static void __exit sd_mod_exit(void)
1221 {
1222         usb_deregister(&sd_driver);
1223 }
1224
1225 module_init(sd_mod_init);
1226 module_exit(sd_mod_exit);