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