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