Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / media / video / gspca / spca500.c
1 /*
2  * SPCA500 chip based cameras initialization data
3  *
4  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21
22 #define MODULE_NAME "spca500"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
29 MODULE_LICENSE("GPL");
30
31 /* specific webcam descriptor */
32 struct sd {
33         struct gspca_dev gspca_dev;             /* !! must be the first item */
34
35         unsigned char brightness;
36         unsigned char contrast;
37         unsigned char colors;
38         u8 quality;
39 #define QUALITY_MIN 70
40 #define QUALITY_MAX 95
41 #define QUALITY_DEF 85
42
43         char subtype;
44 #define AgfaCl20 0
45 #define AiptekPocketDV 1
46 #define BenqDC1016 2
47 #define CreativePCCam300 3
48 #define DLinkDSC350 4
49 #define Gsmartmini 5
50 #define IntelPocketPCCamera 6
51 #define KodakEZ200 7
52 #define LogitechClickSmart310 8
53 #define LogitechClickSmart510 9
54 #define LogitechTraveler 10
55 #define MustekGsmart300 11
56 #define Optimedia 12
57 #define PalmPixDC85 13
58 #define ToptroIndus 14
59
60         u8 *jpeg_hdr;
61 };
62
63 /* V4L2 controls supported by the driver */
64 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70
71 static struct ctrl sd_ctrls[] = {
72         {
73             {
74                 .id      = V4L2_CID_BRIGHTNESS,
75                 .type    = V4L2_CTRL_TYPE_INTEGER,
76                 .name    = "Brightness",
77                 .minimum = 0,
78                 .maximum = 255,
79                 .step    = 1,
80 #define BRIGHTNESS_DEF 127
81                 .default_value = BRIGHTNESS_DEF,
82             },
83             .set = sd_setbrightness,
84             .get = sd_getbrightness,
85         },
86         {
87             {
88                 .id      = V4L2_CID_CONTRAST,
89                 .type    = V4L2_CTRL_TYPE_INTEGER,
90                 .name    = "Contrast",
91                 .minimum = 0,
92                 .maximum = 63,
93                 .step    = 1,
94 #define CONTRAST_DEF 31
95                 .default_value = CONTRAST_DEF,
96             },
97             .set = sd_setcontrast,
98             .get = sd_getcontrast,
99         },
100         {
101             {
102                 .id      = V4L2_CID_SATURATION,
103                 .type    = V4L2_CTRL_TYPE_INTEGER,
104                 .name    = "Color",
105                 .minimum = 0,
106                 .maximum = 63,
107                 .step    = 1,
108 #define COLOR_DEF 31
109                 .default_value = COLOR_DEF,
110             },
111             .set = sd_setcolors,
112             .get = sd_getcolors,
113         },
114 };
115
116 static const struct v4l2_pix_format vga_mode[] = {
117         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
118                 .bytesperline = 320,
119                 .sizeimage = 320 * 240 * 3 / 8 + 590,
120                 .colorspace = V4L2_COLORSPACE_JPEG,
121                 .priv = 1},
122         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
123                 .bytesperline = 640,
124                 .sizeimage = 640 * 480 * 3 / 8 + 590,
125                 .colorspace = V4L2_COLORSPACE_JPEG,
126                 .priv = 0},
127 };
128
129 static const struct v4l2_pix_format sif_mode[] = {
130         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
131                 .bytesperline = 176,
132                 .sizeimage = 176 * 144 * 3 / 8 + 590,
133                 .colorspace = V4L2_COLORSPACE_JPEG,
134                 .priv = 1},
135         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136                 .bytesperline = 352,
137                 .sizeimage = 352 * 288 * 3 / 8 + 590,
138                 .colorspace = V4L2_COLORSPACE_JPEG,
139                 .priv = 0},
140 };
141
142 /* Frame packet header offsets for the spca500 */
143 #define SPCA500_OFFSET_PADDINGLB 2
144 #define SPCA500_OFFSET_PADDINGHB 3
145 #define SPCA500_OFFSET_MODE      4
146 #define SPCA500_OFFSET_IMGWIDTH  5
147 #define SPCA500_OFFSET_IMGHEIGHT 6
148 #define SPCA500_OFFSET_IMGMODE   7
149 #define SPCA500_OFFSET_QTBLINDEX 8
150 #define SPCA500_OFFSET_FRAMSEQ   9
151 #define SPCA500_OFFSET_CDSPINFO  10
152 #define SPCA500_OFFSET_GPIO      11
153 #define SPCA500_OFFSET_AUGPIO    12
154 #define SPCA500_OFFSET_DATA      16
155
156
157 static const __u16 spca500_visual_defaults[][3] = {
158         {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
159                                  * hue (H byte) = 0,
160                                  * saturation/hue enable,
161                                  * brightness/contrast enable.
162                                  */
163         {0x00, 0x0000, 0x8167}, /* brightness = 0 */
164         {0x00, 0x0020, 0x8168}, /* contrast = 0 */
165         {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
166                                  * hue (H byte) = 0, saturation/hue enable,
167                                  * brightness/contrast enable.
168                                  * was 0x0003, now 0x0000.
169                                  */
170         {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
171         {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
172         {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
173         {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
174         {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
175         {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
176         {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
177         {0x0c, 0x0004, 0x0000},
178         /* set interface */
179         {}
180 };
181 static const __u16 Clicksmart510_defaults[][3] = {
182         {0x00, 0x00, 0x8211},
183         {0x00, 0x01, 0x82c0},
184         {0x00, 0x10, 0x82cb},
185         {0x00, 0x0f, 0x800d},
186         {0x00, 0x82, 0x8225},
187         {0x00, 0x21, 0x8228},
188         {0x00, 0x00, 0x8203},
189         {0x00, 0x00, 0x8204},
190         {0x00, 0x08, 0x8205},
191         {0x00, 0xf8, 0x8206},
192         {0x00, 0x28, 0x8207},
193         {0x00, 0xa0, 0x8208},
194         {0x00, 0x08, 0x824a},
195         {0x00, 0x08, 0x8214},
196         {0x00, 0x80, 0x82c1},
197         {0x00, 0x00, 0x82c2},
198         {0x00, 0x00, 0x82ca},
199         {0x00, 0x80, 0x82c1},
200         {0x00, 0x04, 0x82c2},
201         {0x00, 0x00, 0x82ca},
202         {0x00, 0xfc, 0x8100},
203         {0x00, 0xfc, 0x8105},
204         {0x00, 0x30, 0x8101},
205         {0x00, 0x00, 0x8102},
206         {0x00, 0x00, 0x8103},
207         {0x00, 0x66, 0x8107},
208         {0x00, 0x00, 0x816b},
209         {0x00, 0x00, 0x8155},
210         {0x00, 0x01, 0x8156},
211         {0x00, 0x60, 0x8157},
212         {0x00, 0x40, 0x8158},
213         {0x00, 0x0a, 0x8159},
214         {0x00, 0x06, 0x815a},
215         {0x00, 0x00, 0x813f},
216         {0x00, 0x00, 0x8200},
217         {0x00, 0x19, 0x8201},
218         {0x00, 0x00, 0x82c1},
219         {0x00, 0xa0, 0x82c2},
220         {0x00, 0x00, 0x82ca},
221         {0x00, 0x00, 0x8117},
222         {0x00, 0x00, 0x8118},
223         {0x00, 0x65, 0x8119},
224         {0x00, 0x00, 0x811a},
225         {0x00, 0x00, 0x811b},
226         {0x00, 0x55, 0x811c},
227         {0x00, 0x65, 0x811d},
228         {0x00, 0x55, 0x811e},
229         {0x00, 0x16, 0x811f},
230         {0x00, 0x19, 0x8120},
231         {0x00, 0x80, 0x8103},
232         {0x00, 0x83, 0x816b},
233         {0x00, 0x25, 0x8168},
234         {0x00, 0x01, 0x820f},
235         {0x00, 0xff, 0x8115},
236         {0x00, 0x48, 0x8116},
237         {0x00, 0x50, 0x8151},
238         {0x00, 0x40, 0x8152},
239         {0x00, 0x78, 0x8153},
240         {0x00, 0x40, 0x8154},
241         {0x00, 0x00, 0x8167},
242         {0x00, 0x20, 0x8168},
243         {0x00, 0x00, 0x816a},
244         {0x00, 0x03, 0x816b},
245         {0x00, 0x20, 0x8169},
246         {0x00, 0x60, 0x8157},
247         {0x00, 0x00, 0x8190},
248         {0x00, 0x00, 0x81a1},
249         {0x00, 0x00, 0x81b2},
250         {0x00, 0x27, 0x8191},
251         {0x00, 0x27, 0x81a2},
252         {0x00, 0x27, 0x81b3},
253         {0x00, 0x4b, 0x8192},
254         {0x00, 0x4b, 0x81a3},
255         {0x00, 0x4b, 0x81b4},
256         {0x00, 0x66, 0x8193},
257         {0x00, 0x66, 0x81a4},
258         {0x00, 0x66, 0x81b5},
259         {0x00, 0x79, 0x8194},
260         {0x00, 0x79, 0x81a5},
261         {0x00, 0x79, 0x81b6},
262         {0x00, 0x8a, 0x8195},
263         {0x00, 0x8a, 0x81a6},
264         {0x00, 0x8a, 0x81b7},
265         {0x00, 0x9b, 0x8196},
266         {0x00, 0x9b, 0x81a7},
267         {0x00, 0x9b, 0x81b8},
268         {0x00, 0xa6, 0x8197},
269         {0x00, 0xa6, 0x81a8},
270         {0x00, 0xa6, 0x81b9},
271         {0x00, 0xb2, 0x8198},
272         {0x00, 0xb2, 0x81a9},
273         {0x00, 0xb2, 0x81ba},
274         {0x00, 0xbe, 0x8199},
275         {0x00, 0xbe, 0x81aa},
276         {0x00, 0xbe, 0x81bb},
277         {0x00, 0xc8, 0x819a},
278         {0x00, 0xc8, 0x81ab},
279         {0x00, 0xc8, 0x81bc},
280         {0x00, 0xd2, 0x819b},
281         {0x00, 0xd2, 0x81ac},
282         {0x00, 0xd2, 0x81bd},
283         {0x00, 0xdb, 0x819c},
284         {0x00, 0xdb, 0x81ad},
285         {0x00, 0xdb, 0x81be},
286         {0x00, 0xe4, 0x819d},
287         {0x00, 0xe4, 0x81ae},
288         {0x00, 0xe4, 0x81bf},
289         {0x00, 0xed, 0x819e},
290         {0x00, 0xed, 0x81af},
291         {0x00, 0xed, 0x81c0},
292         {0x00, 0xf7, 0x819f},
293         {0x00, 0xf7, 0x81b0},
294         {0x00, 0xf7, 0x81c1},
295         {0x00, 0xff, 0x81a0},
296         {0x00, 0xff, 0x81b1},
297         {0x00, 0xff, 0x81c2},
298         {0x00, 0x03, 0x8156},
299         {0x00, 0x00, 0x8211},
300         {0x00, 0x20, 0x8168},
301         {0x00, 0x01, 0x8202},
302         {0x00, 0x30, 0x8101},
303         {0x00, 0x00, 0x8111},
304         {0x00, 0x00, 0x8112},
305         {0x00, 0x00, 0x8113},
306         {0x00, 0x00, 0x8114},
307         {}
308 };
309
310 static const __u8 qtable_creative_pccam[2][64] = {
311         {                               /* Q-table Y-components */
312          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
313          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
314          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
315          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
316          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
317          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
318          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
319          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
320         {                               /* Q-table C-components */
321          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
322          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
323          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
328          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
329 };
330
331 static const __u8 qtable_kodak_ez200[2][64] = {
332         {                               /* Q-table Y-components */
333          0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
334          0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
335          0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
336          0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
337          0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
338          0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
339          0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
340          0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
341         {                               /* Q-table C-components */
342          0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
343          0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
344          0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345          0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
349          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
350 };
351
352 static const __u8 qtable_pocketdv[2][64] = {
353         {               /* Q-table Y-components start registers 0x8800 */
354          0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
355          0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
356          0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
357          0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
358          0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
359          0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
360          0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
361          0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
362          },
363         {               /* Q-table C-components start registers 0x8840 */
364          0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
365          0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
366          0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
367          0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
370          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
371          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
372 };
373
374 /* read 'len' bytes to gspca_dev->usb_buf */
375 static void reg_r(struct gspca_dev *gspca_dev,
376                   __u16 index,
377                   __u16 length)
378 {
379         usb_control_msg(gspca_dev->dev,
380                         usb_rcvctrlpipe(gspca_dev->dev, 0),
381                         0,
382                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
383                         0,              /* value */
384                         index, gspca_dev->usb_buf, length, 500);
385 }
386
387 static int reg_w(struct gspca_dev *gspca_dev,
388                      __u16 req, __u16 index, __u16 value)
389 {
390         int ret;
391
392         PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
393         ret = usb_control_msg(gspca_dev->dev,
394                         usb_sndctrlpipe(gspca_dev->dev, 0),
395                         req,
396                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
397                         value, index, NULL, 0, 500);
398         if (ret < 0)
399                 PDEBUG(D_ERR, "reg write: error %d", ret);
400         return ret;
401 }
402
403 /* returns: negative is error, pos or zero is data */
404 static int reg_r_12(struct gspca_dev *gspca_dev,
405                         __u16 req,      /* bRequest */
406                         __u16 index,    /* wIndex */
407                         __u16 length)   /* wLength (1 or 2 only) */
408 {
409         int ret;
410
411         gspca_dev->usb_buf[1] = 0;
412         ret = usb_control_msg(gspca_dev->dev,
413                         usb_rcvctrlpipe(gspca_dev->dev, 0),
414                         req,
415                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
416                         0,              /* value */
417                         index,
418                         gspca_dev->usb_buf, length,
419                         500);           /* timeout */
420         if (ret < 0) {
421                 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
422                 return -1;
423         }
424         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
425 }
426
427 /*
428  * Simple function to wait for a given 8-bit value to be returned from
429  * a reg_read call.
430  * Returns: negative is error or timeout, zero is success.
431  */
432 static int reg_r_wait(struct gspca_dev *gspca_dev,
433                         __u16 reg, __u16 index, __u16 value)
434 {
435         int ret, cnt = 20;
436
437         while (--cnt > 0) {
438                 ret = reg_r_12(gspca_dev, reg, index, 1);
439                 if (ret == value)
440                         return 0;
441                 msleep(50);
442         }
443         return -EIO;
444 }
445
446 static int write_vector(struct gspca_dev *gspca_dev,
447                         const __u16 data[][3])
448 {
449         int ret, i = 0;
450
451         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
452                 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
453                 if (ret < 0)
454                         return ret;
455                 i++;
456         }
457         return 0;
458 }
459
460 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
461                                 unsigned int request,
462                                 unsigned int ybase,
463                                 unsigned int cbase,
464                                 const __u8 qtable[2][64])
465 {
466         int i, err;
467
468         /* loop over y components */
469         for (i = 0; i < 64; i++) {
470                 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
471                 if (err < 0)
472                         return err;
473         }
474
475         /* loop over c components */
476         for (i = 0; i < 64; i++) {
477                 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
478                 if (err < 0)
479                         return err;
480         }
481         return 0;
482 }
483
484 static void spca500_ping310(struct gspca_dev *gspca_dev)
485 {
486         reg_r(gspca_dev, 0x0d04, 2);
487         PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
488                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
489 }
490
491 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
492 {
493         reg_r(gspca_dev, 0x0d05, 2);
494         PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
495                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
496         reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
497         spca500_ping310(gspca_dev);
498
499         reg_w(gspca_dev, 0x00, 0x8168, 0x22);
500         reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
501         reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
502         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
503         reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
504         reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
505         reg_w(gspca_dev, 0x00, 0x813f, 0x03);
506         reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
507         reg_w(gspca_dev, 0x00, 0x8153, 0x78);
508         reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
509                                                 /* 00 for adjust shutter */
510         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
511         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
512         reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
513 }
514
515 static void spca500_setmode(struct gspca_dev *gspca_dev,
516                         __u8 xmult, __u8 ymult)
517 {
518         int mode;
519
520         /* set x multiplier */
521         reg_w(gspca_dev, 0, 0x8001, xmult);
522
523         /* set y multiplier */
524         reg_w(gspca_dev, 0, 0x8002, ymult);
525
526         /* use compressed mode, VGA, with mode specific subsample */
527         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
528         reg_w(gspca_dev, 0, 0x8003, mode << 4);
529 }
530
531 static int spca500_full_reset(struct gspca_dev *gspca_dev)
532 {
533         int err;
534
535         /* send the reset command */
536         err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
537         if (err < 0)
538                 return err;
539
540         /* wait for the reset to complete */
541         err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
542         if (err < 0)
543                 return err;
544         err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
545         if (err < 0)
546                 return err;
547         err = reg_r_wait(gspca_dev, 0x06, 0, 0);
548         if (err < 0) {
549                 PDEBUG(D_ERR, "reg_r_wait() failed");
550                 return err;
551         }
552         /* all ok */
553         return 0;
554 }
555
556 /* Synchro the Bridge with sensor */
557 /* Maybe that will work on all spca500 chip */
558 /* because i only own a clicksmart310 try for that chip */
559 /* using spca50x_set_packet_size() cause an Ooops here */
560 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
561 /* up-port the same feature as in 2.4.x kernel */
562 static int spca500_synch310(struct gspca_dev *gspca_dev)
563 {
564         if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
565                 PDEBUG(D_ERR, "Set packet size: set interface error");
566                 goto error;
567         }
568         spca500_ping310(gspca_dev);
569
570         reg_r(gspca_dev, 0x0d00, 1);
571
572         /* need alt setting here */
573         PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
574
575         /* Windoze use pipe with altsetting 6 why 7 here */
576         if (usb_set_interface(gspca_dev->dev,
577                                 gspca_dev->iface,
578                                 gspca_dev->alt) < 0) {
579                 PDEBUG(D_ERR, "Set packet size: set interface error");
580                 goto error;
581         }
582         return 0;
583 error:
584         return -EBUSY;
585 }
586
587 static void spca500_reinit(struct gspca_dev *gspca_dev)
588 {
589         int err;
590         __u8 Data;
591
592         /* some unknown command from Aiptek pocket dv and family300 */
593
594         reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
595         reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
596         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
597
598         /* enable drop packet */
599         reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
600
601         err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
602                                  qtable_pocketdv);
603         if (err < 0)
604                 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
605
606         /* set qtable index */
607         reg_w(gspca_dev, 0x00, 0x8880, 2);
608         /* family cam Quicksmart stuff */
609         reg_w(gspca_dev, 0x00, 0x800a, 0x00);
610         /* Set agc transfer: synced inbetween frames */
611         reg_w(gspca_dev, 0x00, 0x820f, 0x01);
612         /* Init SDRAM - needed for SDRAM access */
613         reg_w(gspca_dev, 0x00, 0x870a, 0x04);
614         /*Start init sequence or stream */
615         reg_w(gspca_dev, 0, 0x8003, 0x00);
616         /* switch to video camera mode */
617         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
618         msleep(2000);
619         if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
620                 reg_r(gspca_dev, 0x816b, 1);
621                 Data = gspca_dev->usb_buf[0];
622                 reg_w(gspca_dev, 0x00, 0x816b, Data);
623         }
624 }
625
626 /* this function is called at probe time */
627 static int sd_config(struct gspca_dev *gspca_dev,
628                         const struct usb_device_id *id)
629 {
630         struct sd *sd = (struct sd *) gspca_dev;
631         struct cam *cam;
632
633         cam = &gspca_dev->cam;
634         sd->subtype = id->driver_info;
635         if (sd->subtype != LogitechClickSmart310) {
636                 cam->cam_mode = vga_mode;
637                 cam->nmodes = ARRAY_SIZE(vga_mode);
638         } else {
639                 cam->cam_mode = sif_mode;
640                 cam->nmodes = ARRAY_SIZE(sif_mode);
641         }
642         sd->brightness = BRIGHTNESS_DEF;
643         sd->contrast = CONTRAST_DEF;
644         sd->colors = COLOR_DEF;
645         sd->quality = QUALITY_DEF;
646         return 0;
647 }
648
649 /* this function is called at probe and resume time */
650 static int sd_init(struct gspca_dev *gspca_dev)
651 {
652         struct sd *sd = (struct sd *) gspca_dev;
653
654         /* initialisation of spca500 based cameras is deferred */
655         PDEBUG(D_STREAM, "SPCA500 init");
656         if (sd->subtype == LogitechClickSmart310)
657                 spca500_clksmart310_init(gspca_dev);
658 /*      else
659                 spca500_initialise(gspca_dev); */
660         PDEBUG(D_STREAM, "SPCA500 init done");
661         return 0;
662 }
663
664 static int sd_start(struct gspca_dev *gspca_dev)
665 {
666         struct sd *sd = (struct sd *) gspca_dev;
667         int err;
668         __u8 Data;
669         __u8 xmult, ymult;
670
671         /* create the JPEG header */
672         sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
673         if (!sd->jpeg_hdr)
674                 return -ENOMEM;
675         jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
676                         0x22);          /* JPEG 411 */
677         jpeg_set_qual(sd->jpeg_hdr, sd->quality);
678
679         if (sd->subtype == LogitechClickSmart310) {
680                 xmult = 0x16;
681                 ymult = 0x12;
682         } else {
683                 xmult = 0x28;
684                 ymult = 0x1e;
685         }
686
687         /* is there a sensor here ? */
688         reg_r(gspca_dev, 0x8a04, 1);
689         PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
690                 gspca_dev->usb_buf[0]);
691         PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
692                 gspca_dev->curr_mode, xmult, ymult);
693
694         /* setup qtable */
695         switch (sd->subtype) {
696         case LogitechClickSmart310:
697                  spca500_setmode(gspca_dev, xmult, ymult);
698
699                 /* enable drop packet */
700                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
701                 reg_w(gspca_dev, 0x00, 0x8880, 3);
702                 err = spca50x_setup_qtable(gspca_dev,
703                                            0x00, 0x8800, 0x8840,
704                                            qtable_creative_pccam);
705                 if (err < 0)
706                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
707                 /* Init SDRAM - needed for SDRAM access */
708                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
709
710                 /* switch to video camera mode */
711                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
712                 msleep(500);
713                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
714                         PDEBUG(D_ERR, "reg_r_wait() failed");
715
716                 reg_r(gspca_dev, 0x816b, 1);
717                 Data = gspca_dev->usb_buf[0];
718                 reg_w(gspca_dev, 0x00, 0x816b, Data);
719
720                 spca500_synch310(gspca_dev);
721
722                 write_vector(gspca_dev, spca500_visual_defaults);
723                 spca500_setmode(gspca_dev, xmult, ymult);
724                 /* enable drop packet */
725                 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
726                 if (err < 0)
727                         PDEBUG(D_ERR, "failed to enable drop packet");
728                 reg_w(gspca_dev, 0x00, 0x8880, 3);
729                 err = spca50x_setup_qtable(gspca_dev,
730                                            0x00, 0x8800, 0x8840,
731                                            qtable_creative_pccam);
732                 if (err < 0)
733                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
734
735                 /* Init SDRAM - needed for SDRAM access */
736                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
737
738                 /* switch to video camera mode */
739                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
740
741                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
742                         PDEBUG(D_ERR, "reg_r_wait() failed");
743
744                 reg_r(gspca_dev, 0x816b, 1);
745                 Data = gspca_dev->usb_buf[0];
746                 reg_w(gspca_dev, 0x00, 0x816b, Data);
747                 break;
748         case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
749         case IntelPocketPCCamera:       /* FIXME: Temporary fix for
750                                          *      Intel Pocket PC Camera
751                                          *      - NWG (Sat 29th March 2003) */
752
753                 /* do a full reset */
754                 err = spca500_full_reset(gspca_dev);
755                 if (err < 0)
756                         PDEBUG(D_ERR, "spca500_full_reset failed");
757
758                 /* enable drop packet */
759                 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
760                 if (err < 0)
761                         PDEBUG(D_ERR, "failed to enable drop packet");
762                 reg_w(gspca_dev, 0x00, 0x8880, 3);
763                 err = spca50x_setup_qtable(gspca_dev,
764                                            0x00, 0x8800, 0x8840,
765                                            qtable_creative_pccam);
766                 if (err < 0)
767                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
768
769                 spca500_setmode(gspca_dev, xmult, ymult);
770                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
771
772                 /* switch to video camera mode */
773                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
774
775                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
776                         PDEBUG(D_ERR, "reg_r_wait() failed");
777
778                 reg_r(gspca_dev, 0x816b, 1);
779                 Data = gspca_dev->usb_buf[0];
780                 reg_w(gspca_dev, 0x00, 0x816b, Data);
781
782 /*              write_vector(gspca_dev, spca500_visual_defaults); */
783                 break;
784         case KodakEZ200:                /* Kodak EZ200 */
785
786                 /* do a full reset */
787                 err = spca500_full_reset(gspca_dev);
788                 if (err < 0)
789                         PDEBUG(D_ERR, "spca500_full_reset failed");
790                 /* enable drop packet */
791                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
792                 reg_w(gspca_dev, 0x00, 0x8880, 0);
793                 err = spca50x_setup_qtable(gspca_dev,
794                                            0x00, 0x8800, 0x8840,
795                                            qtable_kodak_ez200);
796                 if (err < 0)
797                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
798                 spca500_setmode(gspca_dev, xmult, ymult);
799
800                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
801
802                 /* switch to video camera mode */
803                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
804
805                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
806                         PDEBUG(D_ERR, "reg_r_wait() failed");
807
808                 reg_r(gspca_dev, 0x816b, 1);
809                 Data = gspca_dev->usb_buf[0];
810                 reg_w(gspca_dev, 0x00, 0x816b, Data);
811
812 /*              write_vector(gspca_dev, spca500_visual_defaults); */
813                 break;
814
815         case BenqDC1016:
816         case DLinkDSC350:               /* FamilyCam 300 */
817         case AiptekPocketDV:            /* Aiptek PocketDV */
818         case Gsmartmini:                /*Mustek Gsmart Mini */
819         case MustekGsmart300:           /* Mustek Gsmart 300 */
820         case PalmPixDC85:
821         case Optimedia:
822         case ToptroIndus:
823         case AgfaCl20:
824                 spca500_reinit(gspca_dev);
825                 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
826                 /* enable drop packet */
827                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
828
829                 err = spca50x_setup_qtable(gspca_dev,
830                                    0x00, 0x8800, 0x8840, qtable_pocketdv);
831                 if (err < 0)
832                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
833                 reg_w(gspca_dev, 0x00, 0x8880, 2);
834
835                 /* familycam Quicksmart pocketDV stuff */
836                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
837                 /* Set agc transfer: synced inbetween frames */
838                 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
839                 /* Init SDRAM - needed for SDRAM access */
840                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
841
842                 spca500_setmode(gspca_dev, xmult, ymult);
843                 /* switch to video camera mode */
844                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
845
846                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
847
848                 reg_r(gspca_dev, 0x816b, 1);
849                 Data = gspca_dev->usb_buf[0];
850                 reg_w(gspca_dev, 0x00, 0x816b, Data);
851                 break;
852         case LogitechTraveler:
853         case LogitechClickSmart510:
854                 reg_w(gspca_dev, 0x02, 0x00, 0x00);
855                 /* enable drop packet */
856                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
857
858                 err = spca50x_setup_qtable(gspca_dev,
859                                         0x00, 0x8800,
860                                         0x8840, qtable_creative_pccam);
861                 if (err < 0)
862                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
863                 reg_w(gspca_dev, 0x00, 0x8880, 3);
864                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
865                 /* Init SDRAM - needed for SDRAM access */
866                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
867
868                 spca500_setmode(gspca_dev, xmult, ymult);
869
870                 /* switch to video camera mode */
871                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
872                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
873
874                 reg_r(gspca_dev, 0x816b, 1);
875                 Data = gspca_dev->usb_buf[0];
876                 reg_w(gspca_dev, 0x00, 0x816b, Data);
877                 write_vector(gspca_dev, Clicksmart510_defaults);
878                 break;
879         }
880         return 0;
881 }
882
883 static void sd_stopN(struct gspca_dev *gspca_dev)
884 {
885         reg_w(gspca_dev, 0, 0x8003, 0x00);
886
887         /* switch to video camera mode */
888         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
889         reg_r(gspca_dev, 0x8000, 1);
890         PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
891                 gspca_dev->usb_buf[0]);
892 }
893
894 static void sd_stop0(struct gspca_dev *gspca_dev)
895 {
896         struct sd *sd = (struct sd *) gspca_dev;
897
898         kfree(sd->jpeg_hdr);
899 }
900
901 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
902                         u8 *data,                       /* isoc packet */
903                         int len)                        /* iso packet length */
904 {
905         struct sd *sd = (struct sd *) gspca_dev;
906         int i;
907         static __u8 ffd9[] = {0xff, 0xd9};
908
909 /* frames are jpeg 4.1.1 without 0xff escape */
910         if (data[0] == 0xff) {
911                 if (data[1] != 0x01) {  /* drop packet */
912 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
913                         return;
914                 }
915                 gspca_frame_add(gspca_dev, LAST_PACKET,
916                                         ffd9, 2);
917
918                 /* put the JPEG header in the new frame */
919                 gspca_frame_add(gspca_dev, FIRST_PACKET,
920                         sd->jpeg_hdr, JPEG_HDR_SZ);
921
922                 data += SPCA500_OFFSET_DATA;
923                 len -= SPCA500_OFFSET_DATA;
924         } else {
925                 data += 1;
926                 len -= 1;
927         }
928
929         /* add 0x00 after 0xff */
930         i = 0;
931         do {
932                 if (data[i] == 0xff) {
933                         gspca_frame_add(gspca_dev, INTER_PACKET,
934                                         data, i + 1);
935                         len -= i;
936                         data += i;
937                         *data = 0x00;
938                         i = 0;
939                 }
940                 i++;
941         } while (i < len);
942         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
943 }
944
945 static void setbrightness(struct gspca_dev *gspca_dev)
946 {
947         struct sd *sd = (struct sd *) gspca_dev;
948
949         reg_w(gspca_dev, 0x00, 0x8167,
950                         (__u8) (sd->brightness - 128));
951 }
952
953 static void setcontrast(struct gspca_dev *gspca_dev)
954 {
955         struct sd *sd = (struct sd *) gspca_dev;
956
957         reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
958 }
959
960 static void setcolors(struct gspca_dev *gspca_dev)
961 {
962         struct sd *sd = (struct sd *) gspca_dev;
963
964         reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
965 }
966
967 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
968 {
969         struct sd *sd = (struct sd *) gspca_dev;
970
971         sd->brightness = val;
972         if (gspca_dev->streaming)
973                 setbrightness(gspca_dev);
974         return 0;
975 }
976
977 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
978 {
979         struct sd *sd = (struct sd *) gspca_dev;
980
981         *val = sd->brightness;
982         return 0;
983 }
984
985 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
986 {
987         struct sd *sd = (struct sd *) gspca_dev;
988
989         sd->contrast = val;
990         if (gspca_dev->streaming)
991                 setcontrast(gspca_dev);
992         return 0;
993 }
994
995 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
996 {
997         struct sd *sd = (struct sd *) gspca_dev;
998
999         *val = sd->contrast;
1000         return 0;
1001 }
1002
1003 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1004 {
1005         struct sd *sd = (struct sd *) gspca_dev;
1006
1007         sd->colors = val;
1008         if (gspca_dev->streaming)
1009                 setcolors(gspca_dev);
1010         return 0;
1011 }
1012
1013 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1014 {
1015         struct sd *sd = (struct sd *) gspca_dev;
1016
1017         *val = sd->colors;
1018         return 0;
1019 }
1020
1021 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1022                         struct v4l2_jpegcompression *jcomp)
1023 {
1024         struct sd *sd = (struct sd *) gspca_dev;
1025
1026         if (jcomp->quality < QUALITY_MIN)
1027                 sd->quality = QUALITY_MIN;
1028         else if (jcomp->quality > QUALITY_MAX)
1029                 sd->quality = QUALITY_MAX;
1030         else
1031                 sd->quality = jcomp->quality;
1032         if (gspca_dev->streaming)
1033                 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1034         return 0;
1035 }
1036
1037 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1038                         struct v4l2_jpegcompression *jcomp)
1039 {
1040         struct sd *sd = (struct sd *) gspca_dev;
1041
1042         memset(jcomp, 0, sizeof *jcomp);
1043         jcomp->quality = sd->quality;
1044         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1045                         | V4L2_JPEG_MARKER_DQT;
1046         return 0;
1047 }
1048
1049 /* sub-driver description */
1050 static struct sd_desc sd_desc = {
1051         .name = MODULE_NAME,
1052         .ctrls = sd_ctrls,
1053         .nctrls = ARRAY_SIZE(sd_ctrls),
1054         .config = sd_config,
1055         .init = sd_init,
1056         .start = sd_start,
1057         .stopN = sd_stopN,
1058         .stop0 = sd_stop0,
1059         .pkt_scan = sd_pkt_scan,
1060         .get_jcomp = sd_get_jcomp,
1061         .set_jcomp = sd_set_jcomp,
1062 };
1063
1064 /* -- module initialisation -- */
1065 static const __devinitdata struct usb_device_id device_table[] = {
1066         {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1067         {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1068         {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1069         {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1070         {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1071         {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1072         {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1073         {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1074         {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1075         {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1076         {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1077         {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1078         {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1079         {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1080         {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1081         {}
1082 };
1083 MODULE_DEVICE_TABLE(usb, device_table);
1084
1085 /* -- device connect -- */
1086 static int sd_probe(struct usb_interface *intf,
1087                         const struct usb_device_id *id)
1088 {
1089         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1090                                 THIS_MODULE);
1091 }
1092
1093 static struct usb_driver sd_driver = {
1094         .name = MODULE_NAME,
1095         .id_table = device_table,
1096         .probe = sd_probe,
1097         .disconnect = gspca_disconnect,
1098 #ifdef CONFIG_PM
1099         .suspend = gspca_suspend,
1100         .resume = gspca_resume,
1101 #endif
1102 };
1103
1104 /* -- module insert / remove -- */
1105 static int __init sd_mod_init(void)
1106 {
1107         int ret;
1108         ret = usb_register(&sd_driver);
1109         if (ret < 0)
1110                 return ret;
1111         PDEBUG(D_PROBE, "registered");
1112         return 0;
1113 }
1114 static void __exit sd_mod_exit(void)
1115 {
1116         usb_deregister(&sd_driver);
1117         PDEBUG(D_PROBE, "deregistered");
1118 }
1119
1120 module_init(sd_mod_init);
1121 module_exit(sd_mod_exit);