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