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