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