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