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