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