GNU Linux-libre 4.9.309-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  * 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         if (len > USB_BUF_SZ) {
255                 PERR("reg_r: buffer overflow\n");
256                 return;
257         }
258         if (len == 0) {
259                 PERR("reg_r: zero-length read\n");
260                 return;
261         }
262         if (gspca_dev->usb_err < 0)
263                 return;
264         ret = usb_control_msg(gspca_dev->dev,
265                         usb_rcvctrlpipe(gspca_dev->dev, 0),
266                         req,
267                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
268                         0,              /* value */
269                         index,
270                         gspca_dev->usb_buf, len,
271                         500);
272         if (ret < 0) {
273                 pr_err("reg_r err %d\n", ret);
274                 gspca_dev->usb_err = ret;
275                 /*
276                  * Make sure the buffer is zeroed to avoid uninitialized
277                  * values.
278                  */
279                 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
280         }
281 }
282
283 /* write one byte */
284 static void reg_w_1(struct gspca_dev *gspca_dev,
285                    u8 req,
286                    u16 value,
287                    u16 index,
288                    u16 byte)
289 {
290         int ret;
291
292         if (gspca_dev->usb_err < 0)
293                 return;
294         gspca_dev->usb_buf[0] = byte;
295         ret = usb_control_msg(gspca_dev->dev,
296                         usb_sndctrlpipe(gspca_dev->dev, 0),
297                         req,
298                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
299                         value, index,
300                         gspca_dev->usb_buf, 1,
301                         500);
302         if (ret < 0) {
303                 pr_err("reg_w_1 err %d\n", ret);
304                 gspca_dev->usb_err = ret;
305         }
306 }
307
308 /* write req / index / value */
309 static void reg_w_riv(struct gspca_dev *gspca_dev,
310                      u8 req, u16 index, u16 value)
311 {
312         struct usb_device *dev = gspca_dev->dev;
313         int ret;
314
315         if (gspca_dev->usb_err < 0)
316                 return;
317         ret = usb_control_msg(dev,
318                         usb_sndctrlpipe(dev, 0),
319                         req,
320                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
321                         value, index, NULL, 0, 500);
322         if (ret < 0) {
323                 pr_err("reg_w_riv err %d\n", ret);
324                 gspca_dev->usb_err = ret;
325                 return;
326         }
327         PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
328                 req, index, value);
329 }
330
331 static void write_vector(struct gspca_dev *gspca_dev,
332                         const struct cmd *data, int ncmds)
333 {
334         while (--ncmds >= 0) {
335                 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
336                 data++;
337         }
338 }
339
340 static void setup_qtable(struct gspca_dev *gspca_dev,
341                         const u8 qtable[2][64])
342 {
343         int i;
344
345         /* loop over y components */
346         for (i = 0; i < 64; i++)
347                 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
348
349         /* loop over c components */
350         for (i = 0; i < 64; i++)
351                 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
352 }
353
354 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
355                              u8 req, u16 idx, u16 val)
356 {
357         reg_w_riv(gspca_dev, req, idx, val);
358         reg_r(gspca_dev, 0x01, 0x0001, 1);
359         PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
360         reg_w_riv(gspca_dev, req, idx, val);
361
362         msleep(200);
363         reg_r(gspca_dev, 0x01, 0x0001, 1);
364         PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
365 }
366
367 static void spca504_read_info(struct gspca_dev *gspca_dev)
368 {
369         int i;
370         u8 info[6];
371
372         if (gspca_debug < D_STREAM)
373                 return;
374
375         for (i = 0; i < 6; i++) {
376                 reg_r(gspca_dev, 0, i, 1);
377                 info[i] = gspca_dev->usb_buf[0];
378         }
379         PDEBUG(D_STREAM,
380                 "Read info: %d %d %d %d %d %d."
381                 " Should be 1,0,2,2,0,0",
382                 info[0], info[1], info[2],
383                 info[3], info[4], info[5]);
384 }
385
386 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
387                         u8 req,
388                         u16 idx, u16 val, u8 endcode, u8 count)
389 {
390         u16 status;
391
392         reg_w_riv(gspca_dev, req, idx, val);
393         reg_r(gspca_dev, 0x01, 0x0001, 1);
394         if (gspca_dev->usb_err < 0)
395                 return;
396         PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
397                         gspca_dev->usb_buf[0], endcode);
398         if (!count)
399                 return;
400         count = 200;
401         while (--count > 0) {
402                 msleep(10);
403                 /* gsmart mini2 write a each wait setting 1 ms is enough */
404 /*              reg_w_riv(gspca_dev, req, idx, val); */
405                 reg_r(gspca_dev, 0x01, 0x0001, 1);
406                 status = gspca_dev->usb_buf[0];
407                 if (status == endcode) {
408                         PDEBUG(D_FRAM, "status 0x%04x after wait %d",
409                                 status, 200 - count);
410                                 break;
411                 }
412         }
413 }
414
415 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
416 {
417         int count = 10;
418
419         while (--count > 0) {
420                 reg_r(gspca_dev, 0x21, 0, 1);
421                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
422                         break;
423                 msleep(10);
424         }
425 }
426
427 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
428 {
429         int count = 50;
430
431         while (--count > 0) {
432                 reg_r(gspca_dev, 0x21, 1, 1);
433                 if (gspca_dev->usb_buf[0] != 0) {
434                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
435                         reg_r(gspca_dev, 0x21, 1, 1);
436                         spca504B_PollingDataReady(gspca_dev);
437                         break;
438                 }
439                 msleep(10);
440         }
441 }
442
443 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
444 {
445         u8 *data;
446
447         if (gspca_debug < D_STREAM)
448                 return;
449
450         data = gspca_dev->usb_buf;
451         reg_r(gspca_dev, 0x20, 0, 5);
452         PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
453                 data[0], data[1], data[2], data[3], data[4]);
454         reg_r(gspca_dev, 0x23, 0, 64);
455         reg_r(gspca_dev, 0x23, 1, 64);
456 }
457
458 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
459 {
460         struct sd *sd = (struct sd *) gspca_dev;
461         u8 Size;
462
463         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
464         switch (sd->bridge) {
465         case BRIDGE_SPCA533:
466                 reg_w_riv(gspca_dev, 0x31, 0, 0);
467                 spca504B_WaitCmdStatus(gspca_dev);
468                 spca504B_PollingDataReady(gspca_dev);
469                 spca50x_GetFirmware(gspca_dev);
470
471                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
472                 reg_r(gspca_dev, 0x24, 8, 1);
473
474                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
475                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
476                 spca504B_PollingDataReady(gspca_dev);
477
478                 /* Init the cam width height with some values get on init ? */
479                 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
480                 spca504B_WaitCmdStatus(gspca_dev);
481                 spca504B_PollingDataReady(gspca_dev);
482                 break;
483         default:
484 /* case BRIDGE_SPCA504B: */
485 /* case BRIDGE_SPCA536: */
486                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
487                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
488                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
489                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
490                 spca504B_PollingDataReady(gspca_dev);
491                 break;
492         case BRIDGE_SPCA504:
493                 Size += 3;
494                 if (sd->subtype == AiptekMiniPenCam13) {
495                         /* spca504a aiptek */
496                         spca504A_acknowledged_command(gspca_dev,
497                                                 0x08, Size, 0,
498                                                 0x80 | (Size & 0x0f), 1);
499                         spca504A_acknowledged_command(gspca_dev,
500                                                         1, 3, 0, 0x9f, 0);
501                 } else {
502                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
503                 }
504                 break;
505         case BRIDGE_SPCA504C:
506                 /* capture mode */
507                 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
508                 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
509                 break;
510         }
511 }
512
513 static void spca504_wait_status(struct gspca_dev *gspca_dev)
514 {
515         int cnt;
516
517         cnt = 256;
518         while (--cnt > 0) {
519                 /* With this we get the status, when return 0 it's all ok */
520                 reg_r(gspca_dev, 0x06, 0x00, 1);
521                 if (gspca_dev->usb_buf[0] == 0)
522                         return;
523                 msleep(10);
524         }
525 }
526
527 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
528 {
529         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
530         reg_r(gspca_dev, 0x26, 0, 1);
531         spca504B_PollingDataReady(gspca_dev);
532 }
533
534 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
535 {
536         struct sd *sd = (struct sd *) gspca_dev;
537         u16 reg;
538
539         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
540         reg_w_riv(gspca_dev, 0x00, reg, val);
541 }
542
543 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
544 {
545         struct sd *sd = (struct sd *) gspca_dev;
546         u16 reg;
547
548         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
549         reg_w_riv(gspca_dev, 0x00, reg, val);
550 }
551
552 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
553 {
554         struct sd *sd = (struct sd *) gspca_dev;
555         u16 reg;
556
557         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
558         reg_w_riv(gspca_dev, 0x00, reg, val);
559 }
560
561 static void init_ctl_reg(struct gspca_dev *gspca_dev)
562 {
563         struct sd *sd = (struct sd *) gspca_dev;
564         int pollreg = 1;
565
566         switch (sd->bridge) {
567         case BRIDGE_SPCA504:
568         case BRIDGE_SPCA504C:
569                 pollreg = 0;
570                 /* fall thru */
571         default:
572 /*      case BRIDGE_SPCA533: */
573 /*      case BRIDGE_SPCA504B: */
574                 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
575                 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
576                 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
577                 break;
578         case BRIDGE_SPCA536:
579                 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
580                 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
581                 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
582                 break;
583         }
584         if (pollreg)
585                 spca504B_PollingDataReady(gspca_dev);
586 }
587
588 /* this function is called at probe time */
589 static int sd_config(struct gspca_dev *gspca_dev,
590                         const struct usb_device_id *id)
591 {
592         struct sd *sd = (struct sd *) gspca_dev;
593         struct cam *cam;
594
595         cam = &gspca_dev->cam;
596
597         sd->bridge = id->driver_info >> 8;
598         sd->subtype = id->driver_info;
599
600         if (sd->subtype == AiptekMiniPenCam13) {
601
602                 /* try to get the firmware as some cam answer 2.0.1.2.2
603                  * and should be a spca504b then overwrite that setting */
604                 reg_r(gspca_dev, 0x20, 0, 1);
605                 switch (gspca_dev->usb_buf[0]) {
606                 case 1:
607                         break;          /* (right bridge/subtype) */
608                 case 2:
609                         sd->bridge = BRIDGE_SPCA504B;
610                         sd->subtype = 0;
611                         break;
612                 default:
613                         return -ENODEV;
614                 }
615         }
616
617         switch (sd->bridge) {
618         default:
619 /*      case BRIDGE_SPCA504B: */
620 /*      case BRIDGE_SPCA504: */
621 /*      case BRIDGE_SPCA536: */
622                 cam->cam_mode = vga_mode;
623                 cam->nmodes = ARRAY_SIZE(vga_mode);
624                 break;
625         case BRIDGE_SPCA533:
626                 cam->cam_mode = custom_mode;
627                 if (sd->subtype == MegaImageVI)         /* 320x240 only */
628                         cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
629                 else
630                         cam->nmodes = ARRAY_SIZE(custom_mode);
631                 break;
632         case BRIDGE_SPCA504C:
633                 cam->cam_mode = vga_mode2;
634                 cam->nmodes = ARRAY_SIZE(vga_mode2);
635                 break;
636         }
637         return 0;
638 }
639
640 /* this function is called at probe and resume time */
641 static int sd_init(struct gspca_dev *gspca_dev)
642 {
643         struct sd *sd = (struct sd *) gspca_dev;
644
645         switch (sd->bridge) {
646         case BRIDGE_SPCA504B:
647                 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
648                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
649                 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
650                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
651                 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
652                 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
653                 /* fall thru */
654         case BRIDGE_SPCA533:
655                 spca504B_PollingDataReady(gspca_dev);
656                 spca50x_GetFirmware(gspca_dev);
657                 break;
658         case BRIDGE_SPCA536:
659                 spca50x_GetFirmware(gspca_dev);
660                 reg_r(gspca_dev, 0x00, 0x5002, 1);
661                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
662                 reg_r(gspca_dev, 0x24, 0, 1);
663                 spca504B_PollingDataReady(gspca_dev);
664                 reg_w_riv(gspca_dev, 0x34, 0, 0);
665                 spca504B_WaitCmdStatus(gspca_dev);
666                 break;
667         case BRIDGE_SPCA504C:   /* pccam600 */
668                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
669                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
670                 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);     /* reset */
671                 spca504_wait_status(gspca_dev);
672                 if (sd->subtype == LogitechClickSmart420)
673                         write_vector(gspca_dev,
674                                 spca504A_clicksmart420_open_data,
675                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
676                 else
677                         write_vector(gspca_dev, spca504_pccam600_open_data,
678                                 ARRAY_SIZE(spca504_pccam600_open_data));
679                 setup_qtable(gspca_dev, qtable_creative_pccam);
680                 break;
681         default:
682 /*      case BRIDGE_SPCA504: */
683                 PDEBUG(D_STREAM, "Opening SPCA504");
684                 if (sd->subtype == AiptekMiniPenCam13) {
685                         spca504_read_info(gspca_dev);
686
687                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
688                         spca504A_acknowledged_command(gspca_dev, 0x24,
689                                                         8, 3, 0x9e, 1);
690                         /* Twice sequential need status 0xff->0x9e->0x9d */
691                         spca504A_acknowledged_command(gspca_dev, 0x24,
692                                                         8, 3, 0x9e, 0);
693
694                         spca504A_acknowledged_command(gspca_dev, 0x24,
695                                                         0, 0, 0x9d, 1);
696                         /******************************/
697                         /* spca504a aiptek */
698                         spca504A_acknowledged_command(gspca_dev, 0x08,
699                                                         6, 0, 0x86, 1);
700 /*                      reg_write (dev, 0, 0x2000, 0); */
701 /*                      reg_write (dev, 0, 0x2883, 1); */
702 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
703                                                         6, 0, 0x86, 1); */
704 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
705                                                         0, 0, 0x9D, 1); */
706                         reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
707                                                         /* L92 sno1t.txt */
708                         reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
709                         spca504A_acknowledged_command(gspca_dev, 0x01,
710                                                         0x0f, 0, 0xff, 0);
711                 }
712                 /* setup qtable */
713                 reg_w_riv(gspca_dev, 0, 0x2000, 0);
714                 reg_w_riv(gspca_dev, 0, 0x2883, 1);
715                 setup_qtable(gspca_dev, qtable_spca504_default);
716                 break;
717         }
718         return gspca_dev->usb_err;
719 }
720
721 static int sd_start(struct gspca_dev *gspca_dev)
722 {
723         struct sd *sd = (struct sd *) gspca_dev;
724         int enable;
725
726         /* create the JPEG header */
727         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
728                         gspca_dev->pixfmt.width,
729                         0x22);          /* JPEG 411 */
730         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
731
732         if (sd->bridge == BRIDGE_SPCA504B)
733                 spca504B_setQtable(gspca_dev);
734         spca504B_SetSizeType(gspca_dev);
735         switch (sd->bridge) {
736         default:
737 /*      case BRIDGE_SPCA504B: */
738 /*      case BRIDGE_SPCA533: */
739 /*      case BRIDGE_SPCA536: */
740                 switch (sd->subtype) {
741                 case MegapixV4:
742                 case LogitechClickSmart820:
743                 case MegaImageVI:
744                         reg_w_riv(gspca_dev, 0xf0, 0, 0);
745                         spca504B_WaitCmdStatus(gspca_dev);
746                         reg_w_riv(gspca_dev, 0xf0, 4, 0);
747                         spca504B_WaitCmdStatus(gspca_dev);
748                         break;
749                 default:
750                         reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
751                         spca504B_WaitCmdStatus(gspca_dev);
752                         spca504B_PollingDataReady(gspca_dev);
753                         break;
754                 }
755                 break;
756         case BRIDGE_SPCA504:
757                 if (sd->subtype == AiptekMiniPenCam13) {
758                         spca504_read_info(gspca_dev);
759
760                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
761                         spca504A_acknowledged_command(gspca_dev, 0x24,
762                                                         8, 3, 0x9e, 1);
763                         /* Twice sequential need status 0xff->0x9e->0x9d */
764                         spca504A_acknowledged_command(gspca_dev, 0x24,
765                                                         8, 3, 0x9e, 0);
766                         spca504A_acknowledged_command(gspca_dev, 0x24,
767                                                         0, 0, 0x9d, 1);
768                 } else {
769                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
770                         spca504_read_info(gspca_dev);
771                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
772                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
773                 }
774                 spca504B_SetSizeType(gspca_dev);
775                 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
776                                                         /* L92 sno1t.txt */
777                 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
778                 break;
779         case BRIDGE_SPCA504C:
780                 if (sd->subtype == LogitechClickSmart420) {
781                         write_vector(gspca_dev,
782                                 spca504A_clicksmart420_init_data,
783                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
784                 } else {
785                         write_vector(gspca_dev, spca504_pccam600_init_data,
786                                 ARRAY_SIZE(spca504_pccam600_init_data));
787                 }
788                 enable = (sd->autogain ? 0x04 : 0x01);
789                 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
790                                                         /* auto exposure */
791                 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
792                                                         /* auto whiteness */
793
794                 /* set default exposure compensation and whiteness balance */
795                 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);        /* ~ 20 fps */
796                 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
797                 spca504B_SetSizeType(gspca_dev);
798                 break;
799         }
800         init_ctl_reg(gspca_dev);
801         return gspca_dev->usb_err;
802 }
803
804 static void sd_stopN(struct gspca_dev *gspca_dev)
805 {
806         struct sd *sd = (struct sd *) gspca_dev;
807
808         switch (sd->bridge) {
809         default:
810 /*      case BRIDGE_SPCA533: */
811 /*      case BRIDGE_SPCA536: */
812 /*      case BRIDGE_SPCA504B: */
813                 reg_w_riv(gspca_dev, 0x31, 0, 0);
814                 spca504B_WaitCmdStatus(gspca_dev);
815                 spca504B_PollingDataReady(gspca_dev);
816                 break;
817         case BRIDGE_SPCA504:
818         case BRIDGE_SPCA504C:
819                 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
820
821                 if (sd->subtype == AiptekMiniPenCam13) {
822                         /* spca504a aiptek */
823 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
824                                                          6, 0, 0x86, 1); */
825                         spca504A_acknowledged_command(gspca_dev, 0x24,
826                                                         0x00, 0x00, 0x9d, 1);
827                         spca504A_acknowledged_command(gspca_dev, 0x01,
828                                                         0x0f, 0x00, 0xff, 1);
829                 } else {
830                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
831                         reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
832                 }
833                 break;
834         }
835 }
836
837 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
838                         u8 *data,                       /* isoc packet */
839                         int len)                        /* iso packet length */
840 {
841         struct sd *sd = (struct sd *) gspca_dev;
842         int i, sof = 0;
843         static u8 ffd9[] = {0xff, 0xd9};
844
845 /* frames are jpeg 4.1.1 without 0xff escape */
846         switch (sd->bridge) {
847         case BRIDGE_SPCA533:
848                 if (data[0] == 0xff) {
849                         if (data[1] != 0x01) {  /* drop packet */
850 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
851                                 return;
852                         }
853                         sof = 1;
854                         data += SPCA533_OFFSET_DATA;
855                         len -= SPCA533_OFFSET_DATA;
856                 } else {
857                         data += 1;
858                         len -= 1;
859                 }
860                 break;
861         case BRIDGE_SPCA536:
862                 if (data[0] == 0xff) {
863                         sof = 1;
864                         data += SPCA536_OFFSET_DATA;
865                         len -= SPCA536_OFFSET_DATA;
866                 } else {
867                         data += 2;
868                         len -= 2;
869                 }
870                 break;
871         default:
872 /*      case BRIDGE_SPCA504: */
873 /*      case BRIDGE_SPCA504B: */
874                 switch (data[0]) {
875                 case 0xfe:                      /* start of frame */
876                         sof = 1;
877                         data += SPCA50X_OFFSET_DATA;
878                         len -= SPCA50X_OFFSET_DATA;
879                         break;
880                 case 0xff:                      /* drop packet */
881 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
882                         return;
883                 default:
884                         data += 1;
885                         len -= 1;
886                         break;
887                 }
888                 break;
889         case BRIDGE_SPCA504C:
890                 switch (data[0]) {
891                 case 0xfe:                      /* start of frame */
892                         sof = 1;
893                         data += SPCA504_PCCAM600_OFFSET_DATA;
894                         len -= SPCA504_PCCAM600_OFFSET_DATA;
895                         break;
896                 case 0xff:                      /* drop packet */
897 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
898                         return;
899                 default:
900                         data += 1;
901                         len -= 1;
902                         break;
903                 }
904                 break;
905         }
906         if (sof) {              /* start of frame */
907                 gspca_frame_add(gspca_dev, LAST_PACKET,
908                                 ffd9, 2);
909
910                 /* put the JPEG header in the new frame */
911                 gspca_frame_add(gspca_dev, FIRST_PACKET,
912                         sd->jpeg_hdr, JPEG_HDR_SZ);
913         }
914
915         /* add 0x00 after 0xff */
916         i = 0;
917         do {
918                 if (data[i] == 0xff) {
919                         gspca_frame_add(gspca_dev, INTER_PACKET,
920                                         data, i + 1);
921                         len -= i;
922                         data += i;
923                         *data = 0x00;
924                         i = 0;
925                 }
926                 i++;
927         } while (i < len);
928         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
929 }
930
931 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
932 {
933         struct gspca_dev *gspca_dev =
934                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
935         struct sd *sd = (struct sd *)gspca_dev;
936
937         gspca_dev->usb_err = 0;
938
939         if (!gspca_dev->streaming)
940                 return 0;
941
942         switch (ctrl->id) {
943         case V4L2_CID_BRIGHTNESS:
944                 setbrightness(gspca_dev, ctrl->val);
945                 break;
946         case V4L2_CID_CONTRAST:
947                 setcontrast(gspca_dev, ctrl->val);
948                 break;
949         case V4L2_CID_SATURATION:
950                 setcolors(gspca_dev, ctrl->val);
951                 break;
952         case V4L2_CID_AUTOGAIN:
953                 sd->autogain = ctrl->val;
954                 break;
955         }
956         return gspca_dev->usb_err;
957 }
958
959 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
960         .s_ctrl = sd_s_ctrl,
961 };
962
963 static int sd_init_controls(struct gspca_dev *gspca_dev)
964 {
965         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
966
967         gspca_dev->vdev.ctrl_handler = hdl;
968         v4l2_ctrl_handler_init(hdl, 4);
969         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
970                         V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
971         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
972                         V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
973         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
974                         V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
975         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
976                         V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
977
978         if (hdl->error) {
979                 pr_err("Could not initialize controls\n");
980                 return hdl->error;
981         }
982         return 0;
983 }
984
985 /* sub-driver description */
986 static const struct sd_desc sd_desc = {
987         .name = MODULE_NAME,
988         .config = sd_config,
989         .init = sd_init,
990         .init_controls = sd_init_controls,
991         .start = sd_start,
992         .stopN = sd_stopN,
993         .pkt_scan = sd_pkt_scan,
994 };
995
996 /* -- module initialisation -- */
997 #define BS(bridge, subtype) \
998         .driver_info = (BRIDGE_ ## bridge << 8) \
999                         | (subtype)
1000 static const struct usb_device_id device_table[] = {
1001         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1002         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1003         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1004         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1005         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1006         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1007         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1008         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1009         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1010         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1011         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1012         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1013         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1014         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1015         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1016         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1017         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1018         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1019         {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1020         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1021         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1022         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1023         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1024         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1025         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1026         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1027         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1028         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1029         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1030         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1031         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1032         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1033         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1034         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1035         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1036         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1037         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1038         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1039         {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 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);