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