c0dd969a310620ea9626b80209366d267c0aab6e
[linux-2.6.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 #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                 if ((err = spca500_full_reset(gspca_dev)) < 0)
837                         PDEBUG(D_ERR, "spca500_full_reset failed");
838
839                 /* enable drop packet */
840                 err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
841                 if (err < 0)
842                         PDEBUG(D_ERR, "failed to enable drop packet");
843                 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
844                 err = spca50x_setup_qtable(gspca_dev,
845                                            0x00, 0x8800, 0x8840,
846                                            qtable_creative_pccam);
847                 if (err < 0)
848                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
849
850                 spca500_setmode(gspca_dev, xmult, ymult);
851                 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
852
853                 /* switch to video camera mode */
854                 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
855
856                 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
857                         PDEBUG(D_ERR, "reg_readwait() failed");
858
859                 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
860                 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
861
862                 /* write_vector(gspca_dev, spca500_visual_defaults); */
863                 break;
864         case KodakEZ200:                /* Kodak EZ200 */
865
866                 /* do a full reset */
867                 err = spca500_full_reset(gspca_dev);
868                 if (err < 0)
869                         PDEBUG(D_ERR, "spca500_full_reset failed");
870                 /* enable drop packet */
871                 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
872                 reg_write(gspca_dev->dev, 0x00, 0x8880, 0);
873                 err = spca50x_setup_qtable(gspca_dev,
874                                            0x00, 0x8800, 0x8840,
875                                            qtable_kodak_ez200);
876                 if (err < 0)
877                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
878                 spca500_setmode(gspca_dev, xmult, ymult);
879
880                 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
881
882                 /* switch to video camera mode */
883                 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
884
885                 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
886                         PDEBUG(D_ERR, "reg_readwait() failed");
887
888                 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
889                 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
890
891                 /* write_vector(gspca_dev, spca500_visual_defaults); */
892                 break;
893
894         case BenqDC1016:
895         case DLinkDSC350:               /* FamilyCam 300 */
896         case AiptekPocketDV:            /* Aiptek PocketDV */
897         case Gsmartmini:                /*Mustek Gsmart Mini */
898         case MustekGsmart300:           /* Mustek Gsmart 300 */
899         case PalmPixDC85:
900         case Optimedia:
901         case ToptroIndus:
902         case AgfaCl20:
903                 spca500_reinit(gspca_dev);
904                 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01);
905                 /* enable drop packet */
906                 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
907
908                 err = spca50x_setup_qtable(gspca_dev,
909                                    0x00, 0x8800, 0x8840, qtable_pocketdv);
910                 if (err < 0)
911                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
912                 reg_write(gspca_dev->dev, 0x00, 0x8880, 2);
913
914                 /* familycam Quicksmart pocketDV stuff */
915                 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
916                 /* Set agc transfer: synced inbetween frames */
917                 reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01);
918                 /* Init SDRAM - needed for SDRAM access */
919                 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
920
921                 spca500_setmode(gspca_dev,xmult,ymult);
922                 /* switch to video camera mode */
923                 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
924
925                 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
926
927                 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
928                 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
929                 break;
930         case LogitechTraveler:
931         case LogitechClickSmart510:
932                 reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
933                 /* enable drop packet */
934                 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
935
936                 err = spca50x_setup_qtable(gspca_dev,
937                                         0x00, 0x8800,
938                                         0x8840, qtable_creative_pccam);
939                 if (err < 0)
940                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
941                 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
942                 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
943                 /* Init SDRAM - needed for SDRAM access */
944                 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
945
946                 spca500_setmode(gspca_dev, xmult, ymult);
947
948                 /* switch to video camera mode */
949                 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
950                 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
951
952                 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
953                 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
954                 write_vector(gspca_dev, Clicksmart510_defaults);
955                 break;
956         }
957 }
958
959 static void sd_stopN(struct gspca_dev *gspca_dev)
960 {
961         __u8 data = 0;
962
963         reg_write(gspca_dev->dev, 0, 0x8003, 0x00);
964
965         /* switch to video camera mode */
966         reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
967         spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1);
968         PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data);
969 }
970
971 static void sd_stop0(struct gspca_dev *gspca_dev)
972 {
973 }
974
975 static void sd_close(struct gspca_dev *gspca_dev)
976 {
977 }
978
979 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
980                         struct gspca_frame *frame,      /* target */
981                         unsigned char *data,            /* isoc packet */
982                         int len)                        /* iso packet length */
983 {
984         struct sd *sd = (struct sd *) gspca_dev;
985         int i;
986         unsigned char *s, *d;
987         static unsigned char ffd9[] = {0xff, 0xd9};
988
989 /* frames are jpeg 4.1.1 without 0xff escape */
990         if (data[0] == 0xff) {
991                 if (data[1] != 0x01) {  /* drop packet */
992 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
993                         return;
994                 }
995                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
996                                         ffd9, 2);
997
998                 /* put the JPEG header in the new frame */
999                 jpeg_put_header(gspca_dev, frame,
1000                                 ((struct sd *) gspca_dev)->qindex,
1001                                 0x22);
1002
1003                 data += SPCA500_OFFSET_DATA;
1004                 len -= SPCA500_OFFSET_DATA;
1005         } else {
1006                 data += 1;
1007                 len -= 1;
1008         }
1009
1010         /* add 0x00 after 0xff */
1011         for (i = len; --i >= 0; )
1012                 if (data[i] == 0xff)
1013                         break;
1014         if (i < 0) {                    /* no 0xff */
1015                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1016                 return;
1017         }
1018         s = data;
1019         d = sd->packet;
1020         for (i = 0; i < len; i++) {
1021                 *d++ = *s++;
1022                 if (s[-1] == 0xff)
1023                         *d++ = 0x00;
1024         }
1025         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1026                         sd->packet, d - sd->packet);
1027 }
1028
1029 static void setbrightness(struct gspca_dev *gspca_dev)
1030 {
1031         struct sd *sd = (struct sd *) gspca_dev;
1032
1033         reg_write(gspca_dev->dev, 0x00, 0x8167,
1034                         (__u8) (sd->brightness - 128));
1035 }
1036
1037 static void getbrightness(struct gspca_dev *gspca_dev)
1038 {
1039         struct sd *sd = (struct sd *) gspca_dev;
1040
1041         sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128;
1042 }
1043
1044 static void setcontrast(struct gspca_dev *gspca_dev)
1045 {
1046         struct sd *sd = (struct sd *) gspca_dev;
1047
1048         reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2);
1049 }
1050
1051 static void getcontrast(struct gspca_dev *gspca_dev)
1052 {
1053         struct sd *sd = (struct sd *) gspca_dev;
1054
1055         sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2;
1056 }
1057
1058 static void setcolors(struct gspca_dev *gspca_dev)
1059 {
1060         struct sd *sd = (struct sd *) gspca_dev;
1061
1062         reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2);
1063 }
1064
1065 static void getcolors(struct gspca_dev *gspca_dev)
1066 {
1067         struct sd *sd = (struct sd *) gspca_dev;
1068
1069         sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2;
1070 }
1071
1072 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1073 {
1074         struct sd *sd = (struct sd *) gspca_dev;
1075
1076         sd->brightness = val;
1077         if (gspca_dev->streaming)
1078                 setbrightness(gspca_dev);
1079         return 0;
1080 }
1081
1082 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1083 {
1084         struct sd *sd = (struct sd *) gspca_dev;
1085
1086         getbrightness(gspca_dev);
1087         *val = sd->brightness;
1088         return 0;
1089 }
1090
1091 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1092 {
1093         struct sd *sd = (struct sd *) gspca_dev;
1094
1095         sd->contrast = val;
1096         if (gspca_dev->streaming)
1097                 setcontrast(gspca_dev);
1098         return 0;
1099 }
1100
1101 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1102 {
1103         struct sd *sd = (struct sd *) gspca_dev;
1104
1105         getcontrast(gspca_dev);
1106         *val = sd->contrast;
1107         return 0;
1108 }
1109
1110 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1111 {
1112         struct sd *sd = (struct sd *) gspca_dev;
1113
1114         sd->colors = val;
1115         if (gspca_dev->streaming)
1116                 setcolors(gspca_dev);
1117         return 0;
1118 }
1119
1120 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1121 {
1122         struct sd *sd = (struct sd *) gspca_dev;
1123
1124         getcolors(gspca_dev);
1125         *val = sd->colors;
1126         return 0;
1127 }
1128
1129 /* sub-driver description */
1130 static struct sd_desc sd_desc = {
1131         .name = MODULE_NAME,
1132         .ctrls = sd_ctrls,
1133         .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
1134         .config = sd_config,
1135         .open = sd_open,
1136         .start = sd_start,
1137         .stopN = sd_stopN,
1138         .stop0 = sd_stop0,
1139         .close = sd_close,
1140         .pkt_scan = sd_pkt_scan,
1141 };
1142
1143 /* -- module initialisation -- */
1144 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1145 static __devinitdata struct usb_device_id device_table[] = {
1146         {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1147         {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1148         {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1149         {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1150         {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1151         {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1152         {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1153         {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1154         {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1155         {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1156         {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1157         {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1158         {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1159         {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1160         {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1161         {}
1162 };
1163 MODULE_DEVICE_TABLE(usb, device_table);
1164
1165 /* -- device connect -- */
1166 static int sd_probe(struct usb_interface *intf,
1167                         const struct usb_device_id *id)
1168 {
1169         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1170                                 THIS_MODULE);
1171 }
1172
1173 static struct usb_driver sd_driver = {
1174         .name = MODULE_NAME,
1175         .id_table = device_table,
1176         .probe = sd_probe,
1177         .disconnect = gspca_disconnect,
1178 };
1179
1180 /* -- module insert / remove -- */
1181 static int __init sd_mod_init(void)
1182 {
1183         if (usb_register(&sd_driver) < 0)
1184                 return -1;
1185         PDEBUG(D_PROBE, "v%s registered", version);
1186         return 0;
1187 }
1188 static void __exit sd_mod_exit(void)
1189 {
1190         usb_deregister(&sd_driver);
1191         PDEBUG(D_PROBE, "deregistered");
1192 }
1193
1194 module_init(sd_mod_init);
1195 module_exit(sd_mod_exit);