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