Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6
[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, 7)
28 static const char version[] = "2.1.7";
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 /* read 'len' bytes to gspca_dev->usb_buf */
376 static void reg_r(struct gspca_dev *gspca_dev,
377                   __u16 index,
378                   __u16 length)
379 {
380         usb_control_msg(gspca_dev->dev,
381                         usb_rcvctrlpipe(gspca_dev->dev, 0),
382                         0,
383                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
384                         0,              /* value */
385                         index, gspca_dev->usb_buf, length, 500);
386 }
387
388 static int reg_w(struct gspca_dev *gspca_dev,
389                      __u16 req, __u16 index, __u16 value)
390 {
391         int ret;
392
393         PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
394         ret = usb_control_msg(gspca_dev->dev,
395                         usb_sndctrlpipe(gspca_dev->dev, 0),
396                         req,
397                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
398                         value, index, NULL, 0, 500);
399         if (ret < 0)
400                 PDEBUG(D_ERR, "reg write: error %d", ret);
401         return ret;
402 }
403
404 /* returns: negative is error, pos or zero is data */
405 static int reg_r_12(struct gspca_dev *gspca_dev,
406                         __u16 req,      /* bRequest */
407                         __u16 index,    /* wIndex */
408                         __u16 length)   /* wLength (1 or 2 only) */
409 {
410         int ret;
411
412         gspca_dev->usb_buf[1] = 0;
413         ret = usb_control_msg(gspca_dev->dev,
414                         usb_rcvctrlpipe(gspca_dev->dev, 0),
415                         req,
416                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
417                         0,              /* value */
418                         index,
419                         gspca_dev->usb_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 (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_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 gspca_dev *gspca_dev,
434                         __u16 reg, __u16 index, __u16 value)
435 {
436         int ret, cnt = 20;
437
438         while (--cnt > 0) {
439                 ret = reg_r_12(gspca_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         int ret, i = 0;
451
452         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
453                 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
454                 if (ret < 0)
455                         return ret;
456                 i++;
457         }
458         return 0;
459 }
460
461 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
462                                 unsigned int request,
463                                 unsigned int ybase,
464                                 unsigned int cbase,
465                                 const __u8 qtable[2][64])
466 {
467         int i, err;
468
469         /* loop over y components */
470         for (i = 0; i < 64; i++) {
471                 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
472                 if (err < 0)
473                         return err;
474         }
475
476         /* loop over c components */
477         for (i = 0; i < 64; i++) {
478                 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
479                 if (err < 0)
480                         return err;
481         }
482         return 0;
483 }
484
485 static void spca500_ping310(struct gspca_dev *gspca_dev)
486 {
487         reg_r(gspca_dev, 0x0d04, 2);
488         PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
489                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
490 }
491
492 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
493 {
494         reg_r(gspca_dev, 0x0d05, 2);
495         PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
496                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
497         reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
498         spca500_ping310(gspca_dev);
499
500         reg_w(gspca_dev, 0x00, 0x8168, 0x22);
501         reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
502         reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
503         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
504         reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
505         reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
506         reg_w(gspca_dev, 0x00, 0x813f, 0x03);
507         reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
508         reg_w(gspca_dev, 0x00, 0x8153, 0x78);
509         reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
510                                                 /* 00 for adjust shutter */
511         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
512         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
513         reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
514 }
515
516 static void spca500_setmode(struct gspca_dev *gspca_dev,
517                         __u8 xmult, __u8 ymult)
518 {
519         int mode;
520
521         /* set x multiplier */
522         reg_w(gspca_dev, 0, 0x8001, xmult);
523
524         /* set y multiplier */
525         reg_w(gspca_dev, 0, 0x8002, ymult);
526
527         /* use compressed mode, VGA, with mode specific subsample */
528         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
529         reg_w(gspca_dev, 0, 0x8003, mode << 4);
530 }
531
532 static int spca500_full_reset(struct gspca_dev *gspca_dev)
533 {
534         int err;
535
536         /* send the reset command */
537         err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
538         if (err < 0)
539                 return err;
540
541         /* wait for the reset to complete */
542         err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
543         if (err < 0)
544                 return err;
545         err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
546         if (err < 0)
547                 return err;
548         err = reg_r_wait(gspca_dev, 0x06, 0, 0);
549         if (err < 0) {
550                 PDEBUG(D_ERR, "reg_r_wait() failed");
551                 return err;
552         }
553         /* all ok */
554         return 0;
555 }
556
557 /* Synchro the Bridge with sensor */
558 /* Maybe that will work on all spca500 chip */
559 /* because i only own a clicksmart310 try for that chip */
560 /* using spca50x_set_packet_size() cause an Ooops here */
561 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
562 /* up-port the same feature as in 2.4.x kernel */
563 static int spca500_synch310(struct gspca_dev *gspca_dev)
564 {
565         if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
566                 PDEBUG(D_ERR, "Set packet size: set interface error");
567                 goto error;
568         }
569         spca500_ping310(gspca_dev);
570
571         reg_r(gspca_dev, 0x0d00, 1);
572
573         /* need alt setting here */
574         PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
575
576         /* Windoze use pipe with altsetting 6 why 7 here */
577         if (usb_set_interface(gspca_dev->dev,
578                                 gspca_dev->iface,
579                                 gspca_dev->alt) < 0) {
580                 PDEBUG(D_ERR, "Set packet size: set interface error");
581                 goto error;
582         }
583         return 0;
584 error:
585         return -EBUSY;
586 }
587
588 static void spca500_reinit(struct gspca_dev *gspca_dev)
589 {
590         int err;
591         __u8 Data;
592
593         /* some unknow command from Aiptek pocket dv and family300 */
594
595         reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
596         reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
597         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
598
599         /* enable drop packet */
600         reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
601
602         err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
603                                  qtable_pocketdv);
604         if (err < 0)
605                 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
606
607         /* set qtable index */
608         reg_w(gspca_dev, 0x00, 0x8880, 2);
609         /* family cam Quicksmart stuff */
610         reg_w(gspca_dev, 0x00, 0x800a, 0x00);
611         /* Set agc transfer: synced inbetween frames */
612         reg_w(gspca_dev, 0x00, 0x820f, 0x01);
613         /* Init SDRAM - needed for SDRAM access */
614         reg_w(gspca_dev, 0x00, 0x870a, 0x04);
615         /*Start init sequence or stream */
616         reg_w(gspca_dev, 0, 0x8003, 0x00);
617         /* switch to video camera mode */
618         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
619         msleep(2000);
620         if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
621                 reg_r(gspca_dev, 0x816b, 1);
622                 Data = gspca_dev->usb_buf[0];
623                 reg_w(gspca_dev, 0x00, 0x816b, Data);
624         }
625 }
626
627 /* this function is called at probe time */
628 static int sd_config(struct gspca_dev *gspca_dev,
629                         const struct usb_device_id *id)
630 {
631         struct sd *sd = (struct sd *) gspca_dev;
632         struct cam *cam;
633         __u16 vendor;
634         __u16 product;
635
636         vendor = id->idVendor;
637         product = id->idProduct;
638         switch (vendor) {
639         case 0x040a:            /* Kodak cameras */
640 /*              switch (product) { */
641 /*              case 0x0300: */
642                         sd->subtype = KodakEZ200;
643 /*                      break; */
644 /*              } */
645                 break;
646         case 0x041e:            /* Creative cameras */
647 /*              switch (product) { */
648 /*              case 0x400a: */
649                         sd->subtype = CreativePCCam300;
650 /*                      break; */
651 /*              } */
652                 break;
653         case 0x046d:            /* Logitech Labtec */
654                 switch (product) {
655                 case 0x0890:
656                         sd->subtype = LogitechTraveler;
657                         break;
658                 case 0x0900:
659                         sd->subtype = LogitechClickSmart310;
660                         break;
661                 case 0x0901:
662                         sd->subtype = LogitechClickSmart510;
663                         break;
664                 }
665                 break;
666         case 0x04a5:            /* Benq */
667 /*              switch (product) { */
668 /*              case 0x300c: */
669                         sd->subtype = BenqDC1016;
670 /*                      break; */
671 /*              } */
672                 break;
673         case 0x04fc:            /* SunPlus */
674 /*              switch (product) { */
675 /*              case 0x7333: */
676                         sd->subtype = PalmPixDC85;
677 /*                      break; */
678 /*              } */
679                 break;
680         case 0x055f:            /* Mustek cameras */
681                 switch (product) {
682                 case 0xc200:
683                         sd->subtype = MustekGsmart300;
684                         break;
685                 case 0xc220:
686                         sd->subtype = Gsmartmini;
687                         break;
688                 }
689                 break;
690         case 0x06bd:            /* Agfa Cl20 */
691 /*              switch (product) { */
692 /*              case 0x0404: */
693                         sd->subtype = AgfaCl20;
694 /*                      break; */
695 /*              } */
696                 break;
697         case 0x06be:            /* Optimedia */
698 /*              switch (product) { */
699 /*              case 0x0800: */
700                         sd->subtype = Optimedia;
701 /*                      break; */
702 /*              } */
703                 break;
704         case 0x084d:            /* D-Link / Minton */
705 /*              switch (product) { */
706 /*              case 0x0003:     * DSC-350 / S-Cam F5 */
707                         sd->subtype = DLinkDSC350;
708 /*                      break; */
709 /*              } */
710                 break;
711         case 0x08ca:            /* Aiptek */
712 /*              switch (product) { */
713 /*              case 0x0103: */
714                         sd->subtype = AiptekPocketDV;
715 /*                      break; */
716 /*              } */
717                 break;
718         case 0x2899:            /* ToptroIndustrial */
719 /*              switch (product) { */
720 /*              case 0x012c: */
721                         sd->subtype = ToptroIndus;
722 /*                      break; */
723 /*              } */
724                 break;
725         case 0x8086:            /* Intel */
726 /*              switch (product) { */
727 /*              case 0x0630:     * Pocket PC Camera */
728                         sd->subtype = IntelPocketPCCamera;
729 /*                      break; */
730 /*              } */
731                 break;
732         }
733         cam = &gspca_dev->cam;
734         cam->dev_name = (char *) id->driver_info;
735         cam->epaddr = 0x01;
736         if (sd->subtype != LogitechClickSmart310) {
737                 cam->cam_mode = vga_mode;
738                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
739         } else {
740                 cam->cam_mode = sif_mode;
741                 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
742         }
743         sd->qindex = 5;
744         sd->brightness = BRIGHTNESS_DEF;
745         sd->contrast = CONTRAST_DEF;
746         sd->colors = COLOR_DEF;
747         return 0;
748 }
749
750 /* this function is called at open time */
751 static int sd_open(struct gspca_dev *gspca_dev)
752 {
753         struct sd *sd = (struct sd *) gspca_dev;
754
755         /* initialisation of spca500 based cameras is deferred */
756         PDEBUG(D_STREAM, "SPCA500 init");
757         if (sd->subtype == LogitechClickSmart310)
758                 spca500_clksmart310_init(gspca_dev);
759 /*      else
760                 spca500_initialise(gspca_dev); */
761         PDEBUG(D_STREAM, "SPCA500 init done");
762         return 0;
763 }
764
765 static void sd_start(struct gspca_dev *gspca_dev)
766 {
767         struct sd *sd = (struct sd *) gspca_dev;
768         int err;
769         __u8 Data;
770         __u8 xmult, ymult;
771
772         if (sd->subtype == LogitechClickSmart310) {
773                 xmult = 0x16;
774                 ymult = 0x12;
775         } else {
776                 xmult = 0x28;
777                 ymult = 0x1e;
778         }
779
780         /* is there a sensor here ? */
781         reg_r(gspca_dev, 0x8a04, 1);
782         PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
783                 gspca_dev->usb_buf[0]);
784         PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
785                 gspca_dev->curr_mode, xmult, ymult);
786
787         /* setup qtable */
788         switch (sd->subtype) {
789         case LogitechClickSmart310:
790                  spca500_setmode(gspca_dev, xmult, ymult);
791
792                 /* enable drop packet */
793                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
794                 reg_w(gspca_dev, 0x00, 0x8880, 3);
795                 err = spca50x_setup_qtable(gspca_dev,
796                                            0x00, 0x8800, 0x8840,
797                                            qtable_creative_pccam);
798                 if (err < 0)
799                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
800                 /* Init SDRAM - needed for SDRAM access */
801                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
802
803                 /* switch to video camera mode */
804                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
805                 msleep(500);
806                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
807                         PDEBUG(D_ERR, "reg_r_wait() failed");
808
809                 reg_r(gspca_dev, 0x816b, 1);
810                 Data = gspca_dev->usb_buf[0];
811                 reg_w(gspca_dev, 0x00, 0x816b, Data);
812
813                 spca500_synch310(gspca_dev);
814
815                 write_vector(gspca_dev, spca500_visual_defaults);
816                 spca500_setmode(gspca_dev, xmult, ymult);
817                 /* enable drop packet */
818                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
819                         PDEBUG(D_ERR, "failed to enable drop packet");
820                 reg_w(gspca_dev, 0x00, 0x8880, 3);
821                 err = spca50x_setup_qtable(gspca_dev,
822                                            0x00, 0x8800, 0x8840,
823                                            qtable_creative_pccam);
824                 if (err < 0)
825                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
826
827                 /* Init SDRAM - needed for SDRAM access */
828                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
829
830                 /* switch to video camera mode */
831                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
832
833                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
834                         PDEBUG(D_ERR, "reg_r_wait() failed");
835
836                 reg_r(gspca_dev, 0x816b, 1);
837                 Data = gspca_dev->usb_buf[0];
838                 reg_w(gspca_dev, 0x00, 0x816b, Data);
839                 break;
840         case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
841         case IntelPocketPCCamera:       /* FIXME: Temporary fix for
842                                          *      Intel Pocket PC Camera
843                                          *      - NWG (Sat 29th March 2003) */
844
845                 /* do a full reset */
846                 err = spca500_full_reset(gspca_dev);
847                 if (err < 0)
848                         PDEBUG(D_ERR, "spca500_full_reset failed");
849
850                 /* enable drop packet */
851                 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
852                 if (err < 0)
853                         PDEBUG(D_ERR, "failed to enable drop packet");
854                 reg_w(gspca_dev, 0x00, 0x8880, 3);
855                 err = spca50x_setup_qtable(gspca_dev,
856                                            0x00, 0x8800, 0x8840,
857                                            qtable_creative_pccam);
858                 if (err < 0)
859                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
860
861                 spca500_setmode(gspca_dev, xmult, ymult);
862                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
863
864                 /* switch to video camera mode */
865                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
866
867                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
868                         PDEBUG(D_ERR, "reg_r_wait() failed");
869
870                 reg_r(gspca_dev, 0x816b, 1);
871                 Data = gspca_dev->usb_buf[0];
872                 reg_w(gspca_dev, 0x00, 0x816b, Data);
873
874 /*              write_vector(gspca_dev, spca500_visual_defaults); */
875                 break;
876         case KodakEZ200:                /* Kodak EZ200 */
877
878                 /* do a full reset */
879                 err = spca500_full_reset(gspca_dev);
880                 if (err < 0)
881                         PDEBUG(D_ERR, "spca500_full_reset failed");
882                 /* enable drop packet */
883                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
884                 reg_w(gspca_dev, 0x00, 0x8880, 0);
885                 err = spca50x_setup_qtable(gspca_dev,
886                                            0x00, 0x8800, 0x8840,
887                                            qtable_kodak_ez200);
888                 if (err < 0)
889                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
890                 spca500_setmode(gspca_dev, xmult, ymult);
891
892                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
893
894                 /* switch to video camera mode */
895                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
896
897                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
898                         PDEBUG(D_ERR, "reg_r_wait() failed");
899
900                 reg_r(gspca_dev, 0x816b, 1);
901                 Data = gspca_dev->usb_buf[0];
902                 reg_w(gspca_dev, 0x00, 0x816b, Data);
903
904 /*              write_vector(gspca_dev, spca500_visual_defaults); */
905                 break;
906
907         case BenqDC1016:
908         case DLinkDSC350:               /* FamilyCam 300 */
909         case AiptekPocketDV:            /* Aiptek PocketDV */
910         case Gsmartmini:                /*Mustek Gsmart Mini */
911         case MustekGsmart300:           /* Mustek Gsmart 300 */
912         case PalmPixDC85:
913         case Optimedia:
914         case ToptroIndus:
915         case AgfaCl20:
916                 spca500_reinit(gspca_dev);
917                 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
918                 /* enable drop packet */
919                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
920
921                 err = spca50x_setup_qtable(gspca_dev,
922                                    0x00, 0x8800, 0x8840, qtable_pocketdv);
923                 if (err < 0)
924                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
925                 reg_w(gspca_dev, 0x00, 0x8880, 2);
926
927                 /* familycam Quicksmart pocketDV stuff */
928                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
929                 /* Set agc transfer: synced inbetween frames */
930                 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
931                 /* Init SDRAM - needed for SDRAM access */
932                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
933
934                 spca500_setmode(gspca_dev, xmult, ymult);
935                 /* switch to video camera mode */
936                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
937
938                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
939
940                 reg_r(gspca_dev, 0x816b, 1);
941                 Data = gspca_dev->usb_buf[0];
942                 reg_w(gspca_dev, 0x00, 0x816b, Data);
943                 break;
944         case LogitechTraveler:
945         case LogitechClickSmart510:
946                 reg_w(gspca_dev, 0x02, 0x00, 0x00);
947                 /* enable drop packet */
948                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
949
950                 err = spca50x_setup_qtable(gspca_dev,
951                                         0x00, 0x8800,
952                                         0x8840, qtable_creative_pccam);
953                 if (err < 0)
954                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
955                 reg_w(gspca_dev, 0x00, 0x8880, 3);
956                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
957                 /* Init SDRAM - needed for SDRAM access */
958                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
959
960                 spca500_setmode(gspca_dev, xmult, ymult);
961
962                 /* switch to video camera mode */
963                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
964                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
965
966                 reg_r(gspca_dev, 0x816b, 1);
967                 Data = gspca_dev->usb_buf[0];
968                 reg_w(gspca_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         reg_w(gspca_dev, 0, 0x8003, 0x00);
977
978         /* switch to video camera mode */
979         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
980         reg_r(gspca_dev, 0x8000, 1);
981         PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
982                 gspca_dev->usb_buf[0]);
983 }
984
985 static void sd_stop0(struct gspca_dev *gspca_dev)
986 {
987 }
988
989 static void sd_close(struct gspca_dev *gspca_dev)
990 {
991 }
992
993 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
994                         struct gspca_frame *frame,      /* target */
995                         __u8 *data,                     /* isoc packet */
996                         int len)                        /* iso packet length */
997 {
998         struct sd *sd = (struct sd *) gspca_dev;
999         int i;
1000         __u8 *s, *d;
1001         static __u8 ffd9[] = {0xff, 0xd9};
1002
1003 /* frames are jpeg 4.1.1 without 0xff escape */
1004         if (data[0] == 0xff) {
1005                 if (data[1] != 0x01) {  /* drop packet */
1006 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1007                         return;
1008                 }
1009                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1010                                         ffd9, 2);
1011
1012                 /* put the JPEG header in the new frame */
1013                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
1014
1015                 data += SPCA500_OFFSET_DATA;
1016                 len -= SPCA500_OFFSET_DATA;
1017         } else {
1018                 data += 1;
1019                 len -= 1;
1020         }
1021
1022         /* add 0x00 after 0xff */
1023         for (i = len; --i >= 0; )
1024                 if (data[i] == 0xff)
1025                         break;
1026         if (i < 0) {                    /* no 0xff */
1027                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1028                 return;
1029         }
1030         s = data;
1031         d = sd->packet;
1032         for (i = 0; i < len; i++) {
1033                 *d++ = *s++;
1034                 if (s[-1] == 0xff)
1035                         *d++ = 0x00;
1036         }
1037         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1038                         sd->packet, d - sd->packet);
1039 }
1040
1041 static void setbrightness(struct gspca_dev *gspca_dev)
1042 {
1043         struct sd *sd = (struct sd *) gspca_dev;
1044
1045         reg_w(gspca_dev, 0x00, 0x8167,
1046                         (__u8) (sd->brightness - 128));
1047 }
1048
1049 static void getbrightness(struct gspca_dev *gspca_dev)
1050 {
1051         struct sd *sd = (struct sd *) gspca_dev;
1052         int ret;
1053
1054         ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
1055         if (ret >= 0)
1056                 sd->brightness = ret + 128;
1057 }
1058
1059 static void setcontrast(struct gspca_dev *gspca_dev)
1060 {
1061         struct sd *sd = (struct sd *) gspca_dev;
1062
1063         reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
1064 }
1065
1066 static void getcontrast(struct gspca_dev *gspca_dev)
1067 {
1068         struct sd *sd = (struct sd *) gspca_dev;
1069         int ret;
1070
1071         ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
1072         if (ret >= 0)
1073                 sd->contrast = ret;
1074 }
1075
1076 static void setcolors(struct gspca_dev *gspca_dev)
1077 {
1078         struct sd *sd = (struct sd *) gspca_dev;
1079
1080         reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
1081 }
1082
1083 static void getcolors(struct gspca_dev *gspca_dev)
1084 {
1085         struct sd *sd = (struct sd *) gspca_dev;
1086         int ret;
1087
1088         ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
1089         if (ret >= 0)
1090                 sd->colors = ret;
1091 }
1092
1093 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1094 {
1095         struct sd *sd = (struct sd *) gspca_dev;
1096
1097         sd->brightness = val;
1098         if (gspca_dev->streaming)
1099                 setbrightness(gspca_dev);
1100         return 0;
1101 }
1102
1103 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1104 {
1105         struct sd *sd = (struct sd *) gspca_dev;
1106
1107         getbrightness(gspca_dev);
1108         *val = sd->brightness;
1109         return 0;
1110 }
1111
1112 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1113 {
1114         struct sd *sd = (struct sd *) gspca_dev;
1115
1116         sd->contrast = val;
1117         if (gspca_dev->streaming)
1118                 setcontrast(gspca_dev);
1119         return 0;
1120 }
1121
1122 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1123 {
1124         struct sd *sd = (struct sd *) gspca_dev;
1125
1126         getcontrast(gspca_dev);
1127         *val = sd->contrast;
1128         return 0;
1129 }
1130
1131 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1132 {
1133         struct sd *sd = (struct sd *) gspca_dev;
1134
1135         sd->colors = val;
1136         if (gspca_dev->streaming)
1137                 setcolors(gspca_dev);
1138         return 0;
1139 }
1140
1141 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1142 {
1143         struct sd *sd = (struct sd *) gspca_dev;
1144
1145         getcolors(gspca_dev);
1146         *val = sd->colors;
1147         return 0;
1148 }
1149
1150 /* sub-driver description */
1151 static struct sd_desc sd_desc = {
1152         .name = MODULE_NAME,
1153         .ctrls = sd_ctrls,
1154         .nctrls = ARRAY_SIZE(sd_ctrls),
1155         .config = sd_config,
1156         .open = sd_open,
1157         .start = sd_start,
1158         .stopN = sd_stopN,
1159         .stop0 = sd_stop0,
1160         .close = sd_close,
1161         .pkt_scan = sd_pkt_scan,
1162 };
1163
1164 /* -- module initialisation -- */
1165 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1166 static const __devinitdata struct usb_device_id device_table[] = {
1167         {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1168         {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1169         {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1170         {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1171         {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1172         {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1173         {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1174         {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1175         {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1176         {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1177         {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1178         {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1179         {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1180         {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1181         {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1182         {}
1183 };
1184 MODULE_DEVICE_TABLE(usb, device_table);
1185
1186 /* -- device connect -- */
1187 static int sd_probe(struct usb_interface *intf,
1188                         const struct usb_device_id *id)
1189 {
1190         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1191                                 THIS_MODULE);
1192 }
1193
1194 static struct usb_driver sd_driver = {
1195         .name = MODULE_NAME,
1196         .id_table = device_table,
1197         .probe = sd_probe,
1198         .disconnect = gspca_disconnect,
1199 };
1200
1201 /* -- module insert / remove -- */
1202 static int __init sd_mod_init(void)
1203 {
1204         if (usb_register(&sd_driver) < 0)
1205                 return -1;
1206         PDEBUG(D_PROBE, "v%s registered", version);
1207         return 0;
1208 }
1209 static void __exit sd_mod_exit(void)
1210 {
1211         usb_deregister(&sd_driver);
1212         PDEBUG(D_PROBE, "deregistered");
1213 }
1214
1215 module_init(sd_mod_init);
1216 module_exit(sd_mod_exit);