V4L/DVB (8370): gspca: Webcam 0461:0821 added.
[linux-2.6] / drivers / media / video / gspca / sunplus.c
1 /*
2  *              Sunplus spca504(abc) spca533 spca536 library
3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "sunplus"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 #define DRIVER_VERSION_NUMBER   KERNEL_VERSION(2, 1, 8)
28 static const char version[] = "2.1.8";
29
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SPCA5xx 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         unsigned char autogain;
45
46         char qindex;
47         char bridge;
48 #define BRIDGE_SPCA504 0
49 #define BRIDGE_SPCA504B 1
50 #define BRIDGE_SPCA504C 2
51 #define BRIDGE_SPCA533 3
52 #define BRIDGE_SPCA536 4
53         char subtype;
54 #define AiptekMiniPenCam13 1
55 #define LogitechClickSmart420 2
56 #define LogitechClickSmart820 3
57 #define MegapixV4 4
58 };
59
60 /* V4L2 controls supported by the driver */
61 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
69
70 static struct ctrl sd_ctrls[] = {
71 #define SD_BRIGHTNESS 0
72         {
73             {
74                 .id      = V4L2_CID_BRIGHTNESS,
75                 .type    = V4L2_CTRL_TYPE_INTEGER,
76                 .name    = "Brightness",
77                 .minimum = 0,
78                 .maximum = 0xff,
79                 .step    = 1,
80                 .default_value = 0,
81             },
82             .set = sd_setbrightness,
83             .get = sd_getbrightness,
84         },
85 #define SD_CONTRAST 1
86         {
87             {
88                 .id      = V4L2_CID_CONTRAST,
89                 .type    = V4L2_CTRL_TYPE_INTEGER,
90                 .name    = "Contrast",
91                 .minimum = 0,
92                 .maximum = 0xff,
93                 .step    = 1,
94                 .default_value = 0x20,
95             },
96             .set = sd_setcontrast,
97             .get = sd_getcontrast,
98         },
99 #define SD_COLOR 2
100         {
101             {
102                 .id      = V4L2_CID_SATURATION,
103                 .type    = V4L2_CTRL_TYPE_INTEGER,
104                 .name    = "Color",
105                 .minimum = 0,
106                 .maximum = 0xff,
107                 .step    = 1,
108                 .default_value = 0x1a,
109             },
110             .set = sd_setcolors,
111             .get = sd_getcolors,
112         },
113 #define SD_AUTOGAIN 3
114         {
115             {
116                 .id      = V4L2_CID_AUTOGAIN,
117                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
118                 .name    = "Auto Gain",
119                 .minimum = 0,
120                 .maximum = 1,
121                 .step    = 1,
122                 .default_value = 1,
123             },
124             .set = sd_setautogain,
125             .get = sd_getautogain,
126         },
127 };
128
129 static struct v4l2_pix_format vga_mode[] = {
130         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
131                 .bytesperline = 320,
132                 .sizeimage = 320 * 240 * 3 / 8 + 590,
133                 .colorspace = V4L2_COLORSPACE_JPEG,
134                 .priv = 2},
135         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136                 .bytesperline = 640,
137                 .sizeimage = 640 * 480 * 3 / 8 + 590,
138                 .colorspace = V4L2_COLORSPACE_JPEG,
139                 .priv = 1},
140 };
141
142 static struct v4l2_pix_format custom_mode[] = {
143         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
144                 .bytesperline = 320,
145                 .sizeimage = 320 * 240 * 3 / 8 + 590,
146                 .colorspace = V4L2_COLORSPACE_JPEG,
147                 .priv = 2},
148         {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
149                 .bytesperline = 464,
150                 .sizeimage = 464 * 480 * 3 / 8 + 590,
151                 .colorspace = V4L2_COLORSPACE_JPEG,
152                 .priv = 1},
153 };
154
155 static struct v4l2_pix_format vga_mode2[] = {
156         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157                 .bytesperline = 176,
158                 .sizeimage = 176 * 144 * 3 / 8 + 590,
159                 .colorspace = V4L2_COLORSPACE_JPEG,
160                 .priv = 4},
161         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
162                 .bytesperline = 320,
163                 .sizeimage = 320 * 240 * 3 / 8 + 590,
164                 .colorspace = V4L2_COLORSPACE_JPEG,
165                 .priv = 3},
166         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
167                 .bytesperline = 352,
168                 .sizeimage = 352 * 288 * 3 / 8 + 590,
169                 .colorspace = V4L2_COLORSPACE_JPEG,
170                 .priv = 2},
171         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
172                 .bytesperline = 640,
173                 .sizeimage = 640 * 480 * 3 / 8 + 590,
174                 .colorspace = V4L2_COLORSPACE_JPEG,
175                 .priv = 1},
176 };
177
178 #define SPCA50X_OFFSET_DATA 10
179 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
180 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
181 #define SPCA504_PCCAM600_OFFSET_MODE     5
182 #define SPCA504_PCCAM600_OFFSET_DATA     14
183  /* Frame packet header offsets for the spca533 */
184 #define SPCA533_OFFSET_DATA      16
185 #define SPCA533_OFFSET_FRAMSEQ  15
186 /* Frame packet header offsets for the spca536 */
187 #define SPCA536_OFFSET_DATA      4
188 #define SPCA536_OFFSET_FRAMSEQ   1
189
190 /* Initialisation data for the Creative PC-CAM 600 */
191 static const __u16 spca504_pccam600_init_data[][3] = {
192 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
193         {0x00, 0x0000, 0x2000},
194         {0x00, 0x0013, 0x2301},
195         {0x00, 0x0003, 0x2000},
196         {0x00, 0x0001, 0x21ac},
197         {0x00, 0x0001, 0x21a6},
198         {0x00, 0x0000, 0x21a7}, /* brightness */
199         {0x00, 0x0020, 0x21a8}, /* contrast */
200         {0x00, 0x0001, 0x21ac}, /* sat/hue */
201         {0x00, 0x0000, 0x21ad}, /* hue */
202         {0x00, 0x001a, 0x21ae}, /* saturation */
203         {0x00, 0x0002, 0x21a3}, /* gamma */
204         {0x30, 0x0154, 0x0008},
205         {0x30, 0x0004, 0x0006},
206         {0x30, 0x0258, 0x0009},
207         {0x30, 0x0004, 0x0000},
208         {0x30, 0x0093, 0x0004},
209         {0x30, 0x0066, 0x0005},
210         {0x00, 0x0000, 0x2000},
211         {0x00, 0x0013, 0x2301},
212         {0x00, 0x0003, 0x2000},
213         {0x00, 0x0013, 0x2301},
214         {0x00, 0x0003, 0x2000},
215         {}
216 };
217
218 /* Creative PC-CAM 600 specific open data, sent before using the
219  * generic initialisation data from spca504_open_data.
220  */
221 static const __u16 spca504_pccam600_open_data[][3] = {
222         {0x00, 0x0001, 0x2501},
223         {0x20, 0x0500, 0x0001}, /* snapshot mode */
224         {0x00, 0x0003, 0x2880},
225         {0x00, 0x0001, 0x2881},
226         {}
227 };
228
229 /* Initialisation data for the logitech clicksmart 420 */
230 static const __u16 spca504A_clicksmart420_init_data[][3] = {
231 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
232         {0x00, 0x0000, 0x2000},
233         {0x00, 0x0013, 0x2301},
234         {0x00, 0x0003, 0x2000},
235         {0x00, 0x0001, 0x21ac},
236         {0x00, 0x0001, 0x21a6},
237         {0x00, 0x0000, 0x21a7}, /* brightness */
238         {0x00, 0x0020, 0x21a8}, /* contrast */
239         {0x00, 0x0001, 0x21ac}, /* sat/hue */
240         {0x00, 0x0000, 0x21ad}, /* hue */
241         {0x00, 0x001a, 0x21ae}, /* saturation */
242         {0x00, 0x0002, 0x21a3}, /* gamma */
243         {0x30, 0x0004, 0x000a},
244         {0xb0, 0x0001, 0x0000},
245
246
247         {0x0a1, 0x0080, 0x0001},
248         {0x30, 0x0049, 0x0000},
249         {0x30, 0x0060, 0x0005},
250         {0x0c, 0x0004, 0x0000},
251         {0x00, 0x0000, 0x0000},
252         {0x00, 0x0000, 0x2000},
253         {0x00, 0x0013, 0x2301},
254         {0x00, 0x0003, 0x2000},
255         {0x00, 0x0000, 0x2000},
256
257         {}
258 };
259
260 /* clicksmart 420 open data ? */
261 static const __u16 spca504A_clicksmart420_open_data[][3] = {
262         {0x00, 0x0001, 0x2501},
263         {0x20, 0x0502, 0x0000},
264         {0x06, 0x0000, 0x0000},
265         {0x00, 0x0004, 0x2880},
266         {0x00, 0x0001, 0x2881},
267 /* look like setting a qTable */
268         {0x00, 0x0006, 0x2800},
269         {0x00, 0x0004, 0x2801},
270         {0x00, 0x0004, 0x2802},
271         {0x00, 0x0006, 0x2803},
272         {0x00, 0x000a, 0x2804},
273         {0x00, 0x0010, 0x2805},
274         {0x00, 0x0014, 0x2806},
275         {0x00, 0x0018, 0x2807},
276         {0x00, 0x0005, 0x2808},
277         {0x00, 0x0005, 0x2809},
278         {0x00, 0x0006, 0x280a},
279         {0x00, 0x0008, 0x280b},
280         {0x00, 0x000a, 0x280c},
281         {0x00, 0x0017, 0x280d},
282         {0x00, 0x0018, 0x280e},
283         {0x00, 0x0016, 0x280f},
284
285         {0x00, 0x0006, 0x2810},
286         {0x00, 0x0005, 0x2811},
287         {0x00, 0x0006, 0x2812},
288         {0x00, 0x000a, 0x2813},
289         {0x00, 0x0010, 0x2814},
290         {0x00, 0x0017, 0x2815},
291         {0x00, 0x001c, 0x2816},
292         {0x00, 0x0016, 0x2817},
293         {0x00, 0x0006, 0x2818},
294         {0x00, 0x0007, 0x2819},
295         {0x00, 0x0009, 0x281a},
296         {0x00, 0x000c, 0x281b},
297         {0x00, 0x0014, 0x281c},
298         {0x00, 0x0023, 0x281d},
299         {0x00, 0x0020, 0x281e},
300         {0x00, 0x0019, 0x281f},
301
302         {0x00, 0x0007, 0x2820},
303         {0x00, 0x0009, 0x2821},
304         {0x00, 0x000f, 0x2822},
305         {0x00, 0x0016, 0x2823},
306         {0x00, 0x001b, 0x2824},
307         {0x00, 0x002c, 0x2825},
308         {0x00, 0x0029, 0x2826},
309         {0x00, 0x001f, 0x2827},
310         {0x00, 0x000a, 0x2828},
311         {0x00, 0x000e, 0x2829},
312         {0x00, 0x0016, 0x282a},
313         {0x00, 0x001a, 0x282b},
314         {0x00, 0x0020, 0x282c},
315         {0x00, 0x002a, 0x282d},
316         {0x00, 0x002d, 0x282e},
317         {0x00, 0x0025, 0x282f},
318
319         {0x00, 0x0014, 0x2830},
320         {0x00, 0x001a, 0x2831},
321         {0x00, 0x001f, 0x2832},
322         {0x00, 0x0023, 0x2833},
323         {0x00, 0x0029, 0x2834},
324         {0x00, 0x0030, 0x2835},
325         {0x00, 0x0030, 0x2836},
326         {0x00, 0x0028, 0x2837},
327         {0x00, 0x001d, 0x2838},
328         {0x00, 0x0025, 0x2839},
329         {0x00, 0x0026, 0x283a},
330         {0x00, 0x0027, 0x283b},
331         {0x00, 0x002d, 0x283c},
332         {0x00, 0x0028, 0x283d},
333         {0x00, 0x0029, 0x283e},
334         {0x00, 0x0028, 0x283f},
335
336         {0x00, 0x0007, 0x2840},
337         {0x00, 0x0007, 0x2841},
338         {0x00, 0x000a, 0x2842},
339         {0x00, 0x0013, 0x2843},
340         {0x00, 0x0028, 0x2844},
341         {0x00, 0x0028, 0x2845},
342         {0x00, 0x0028, 0x2846},
343         {0x00, 0x0028, 0x2847},
344         {0x00, 0x0007, 0x2848},
345         {0x00, 0x0008, 0x2849},
346         {0x00, 0x000a, 0x284a},
347         {0x00, 0x001a, 0x284b},
348         {0x00, 0x0028, 0x284c},
349         {0x00, 0x0028, 0x284d},
350         {0x00, 0x0028, 0x284e},
351         {0x00, 0x0028, 0x284f},
352
353         {0x00, 0x000a, 0x2850},
354         {0x00, 0x000a, 0x2851},
355         {0x00, 0x0016, 0x2852},
356         {0x00, 0x0028, 0x2853},
357         {0x00, 0x0028, 0x2854},
358         {0x00, 0x0028, 0x2855},
359         {0x00, 0x0028, 0x2856},
360         {0x00, 0x0028, 0x2857},
361         {0x00, 0x0013, 0x2858},
362         {0x00, 0x001a, 0x2859},
363         {0x00, 0x0028, 0x285a},
364         {0x00, 0x0028, 0x285b},
365         {0x00, 0x0028, 0x285c},
366         {0x00, 0x0028, 0x285d},
367         {0x00, 0x0028, 0x285e},
368         {0x00, 0x0028, 0x285f},
369
370         {0x00, 0x0028, 0x2860},
371         {0x00, 0x0028, 0x2861},
372         {0x00, 0x0028, 0x2862},
373         {0x00, 0x0028, 0x2863},
374         {0x00, 0x0028, 0x2864},
375         {0x00, 0x0028, 0x2865},
376         {0x00, 0x0028, 0x2866},
377         {0x00, 0x0028, 0x2867},
378         {0x00, 0x0028, 0x2868},
379         {0x00, 0x0028, 0x2869},
380         {0x00, 0x0028, 0x286a},
381         {0x00, 0x0028, 0x286b},
382         {0x00, 0x0028, 0x286c},
383         {0x00, 0x0028, 0x286d},
384         {0x00, 0x0028, 0x286e},
385         {0x00, 0x0028, 0x286f},
386
387         {0x00, 0x0028, 0x2870},
388         {0x00, 0x0028, 0x2871},
389         {0x00, 0x0028, 0x2872},
390         {0x00, 0x0028, 0x2873},
391         {0x00, 0x0028, 0x2874},
392         {0x00, 0x0028, 0x2875},
393         {0x00, 0x0028, 0x2876},
394         {0x00, 0x0028, 0x2877},
395         {0x00, 0x0028, 0x2878},
396         {0x00, 0x0028, 0x2879},
397         {0x00, 0x0028, 0x287a},
398         {0x00, 0x0028, 0x287b},
399         {0x00, 0x0028, 0x287c},
400         {0x00, 0x0028, 0x287d},
401         {0x00, 0x0028, 0x287e},
402         {0x00, 0x0028, 0x287f},
403
404         {0xa0, 0x0000, 0x0503},
405         {}
406 };
407
408 static const __u8 qtable_creative_pccam[2][64] = {
409         {                               /* Q-table Y-components */
410          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
411          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
412          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
413          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
414          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
415          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
416          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
417          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
418         {                               /* Q-table C-components */
419          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
420          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
421          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
422          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
423          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
424          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
425          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
426          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
427 };
428
429 /* FIXME: This Q-table is identical to the Creative PC-CAM one,
430  *              except for one byte. Possibly a typo?
431  *              NWG: 18/05/2003.
432  */
433 static const __u8 qtable_spca504_default[2][64] = {
434         {                               /* Q-table Y-components */
435          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
436          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
437          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
438          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
439          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
440          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
441          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
442          0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
443          },
444         {                               /* Q-table C-components */
445          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
446          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
447          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
448          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
449          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
450          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
451          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
452          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
453 };
454
455 static void reg_r(struct usb_device *dev,
456                            __u16 req,
457                            __u16 index,
458                            __u8 *buffer, __u16 length)
459 {
460         usb_control_msg(dev,
461                         usb_rcvctrlpipe(dev, 0),
462                         req,
463                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
464                         0,              /* value */
465                         index, buffer, length,
466                         500);
467 }
468
469 static void reg_w(struct usb_device *dev,
470                             __u16 req,
471                             __u16 value,
472                             __u16 index,
473                             __u8 *buffer, __u16 length)
474 {
475         usb_control_msg(dev,
476                         usb_sndctrlpipe(dev, 0),
477                         req,
478                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
479                         value, index, buffer, length,
480                         500);
481 }
482
483 /* write req / index / value */
484 static int reg_w_riv(struct usb_device *dev,
485                      __u16 req, __u16 index, __u16 value)
486 {
487         int ret;
488
489         ret = usb_control_msg(dev,
490                         usb_sndctrlpipe(dev, 0),
491                         req,
492                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
493                         value, index, NULL, 0, 500);
494         PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
495                 req, index, value, ret);
496         if (ret < 0)
497                 PDEBUG(D_ERR, "reg write: error %d", ret);
498         return ret;
499 }
500
501 /* read 1 byte */
502 static int reg_r_1(struct gspca_dev *gspca_dev,
503                         __u16 value)    /* wValue */
504 {
505         int ret;
506
507         ret = usb_control_msg(gspca_dev->dev,
508                         usb_rcvctrlpipe(gspca_dev->dev, 0),
509                         0x20,                   /* request */
510                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
511                         value,
512                         0,                      /* index */
513                         gspca_dev->usb_buf, 1,
514                         500);                   /* timeout */
515         if (ret < 0) {
516                 PDEBUG(D_ERR, "reg_r_1 err %d", ret);
517                 return 0;
518         }
519         return gspca_dev->usb_buf[0];
520 }
521
522 /* read 1 or 2 bytes - returns < 0 if error */
523 static int reg_r_12(struct gspca_dev *gspca_dev,
524                         __u16 req,      /* bRequest */
525                         __u16 index,    /* wIndex */
526                         __u16 length)   /* wLength (1 or 2 only) */
527 {
528         int ret;
529
530         gspca_dev->usb_buf[1] = 0;
531         ret = usb_control_msg(gspca_dev->dev,
532                         usb_rcvctrlpipe(gspca_dev->dev, 0),
533                         req,
534                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
535                         0,              /* value */
536                         index,
537                         gspca_dev->usb_buf, length,
538                         500);
539         if (ret < 0) {
540                 PDEBUG(D_ERR, "reg_read err %d", ret);
541                 return -1;
542         }
543         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
544 }
545
546 static int write_vector(struct gspca_dev *gspca_dev,
547                         const __u16 data[][3])
548 {
549         struct usb_device *dev = gspca_dev->dev;
550         int ret, i = 0;
551
552         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
553                 ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
554                 if (ret < 0) {
555                         PDEBUG(D_ERR,
556                                 "Register write failed for 0x%x,0x%x,0x%x",
557                                 data[i][0], data[i][1], data[i][2]);
558                         return ret;
559                 }
560                 i++;
561         }
562         return 0;
563 }
564
565 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
566                                 unsigned int request,
567                                 unsigned int ybase,
568                                 unsigned int cbase,
569                                 const __u8 qtable[2][64])
570 {
571         struct usb_device *dev = gspca_dev->dev;
572         int i, err;
573
574         /* loop over y components */
575         for (i = 0; i < 64; i++) {
576                 err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
577                 if (err < 0)
578                         return err;
579         }
580
581         /* loop over c components */
582         for (i = 0; i < 64; i++) {
583                 err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
584                 if (err < 0)
585                         return err;
586         }
587         return 0;
588 }
589
590 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
591                              __u16 req, __u16 idx, __u16 val)
592 {
593         struct usb_device *dev = gspca_dev->dev;
594         __u8 notdone;
595
596         reg_w_riv(dev, req, idx, val);
597         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
598         reg_w_riv(dev, req, idx, val);
599
600         PDEBUG(D_FRAM, "before wait 0x%x", notdone);
601
602         msleep(200);
603         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
604         PDEBUG(D_FRAM, "after wait 0x%x", notdone);
605 }
606
607 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
608                         __u16 req,
609                         __u16 idx, __u16 val, __u8 stat, __u8 count)
610 {
611         struct usb_device *dev = gspca_dev->dev;
612         __u8 status;
613         __u8 endcode;
614
615         reg_w_riv(dev, req, idx, val);
616         status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
617         endcode = stat;
618         PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
619         if (!count)
620                 return;
621         count = 200;
622         while (--count > 0) {
623                 msleep(10);
624                 /* gsmart mini2 write a each wait setting 1 ms is enought */
625 /*              reg_w_riv(dev, req, idx, val); */
626                 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
627                 if (status == endcode) {
628                         PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
629                                 status, 200 - count);
630                                 break;
631                 }
632         }
633 }
634
635 static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
636 {
637         int count = 10;
638
639         while (--count > 0) {
640                 reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
641                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
642                         break;
643                 msleep(10);
644         }
645         return gspca_dev->usb_buf[0];
646 }
647
648 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
649 {
650         struct usb_device *dev = gspca_dev->dev;
651         int count = 50;
652
653         while (--count > 0) {
654                 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
655                 if (gspca_dev->usb_buf[0] != 0) {
656                         gspca_dev->usb_buf[0] = 0;
657                         reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
658                         reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
659                         spca504B_PollingDataReady(gspca_dev);
660                         break;
661                 }
662                 msleep(10);
663         }
664 }
665
666 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
667 {
668         struct usb_device *dev = gspca_dev->dev;
669         __u8 *data;
670
671         data = kmalloc(64, GFP_KERNEL);
672         reg_r(dev, 0x20, 0, data, 5);
673         PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
674                 data[0], data[1], data[2], data[3], data[4]);
675         reg_r(dev, 0x23, 0, data, 64);
676         reg_r(dev, 0x23, 1, data, 64);
677         kfree(data);
678 }
679
680 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
681 {
682         struct sd *sd = (struct sd *) gspca_dev;
683         struct usb_device *dev = gspca_dev->dev;
684         __u8 Size;
685         __u8 Type;
686         int rc;
687
688         Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
689         Type = 0;
690         switch (sd->bridge) {
691         case BRIDGE_SPCA533:
692                 reg_w(dev, 0x31, 0, 0, NULL, 0);
693                 spca504B_WaitCmdStatus(gspca_dev);
694                 rc = spca504B_PollingDataReady(gspca_dev);
695                 spca50x_GetFirmware(gspca_dev);
696                 gspca_dev->usb_buf[0] = 2;                      /* type */
697                 reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
698                 reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
699
700                 gspca_dev->usb_buf[0] = Size;
701                 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
702                 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);     /* size */
703                 rc = spca504B_PollingDataReady(gspca_dev);
704
705                 /* Init the cam width height with some values get on init ? */
706                 reg_w(dev, 0x31, 0, 4, NULL, 0);
707                 spca504B_WaitCmdStatus(gspca_dev);
708                 rc = spca504B_PollingDataReady(gspca_dev);
709                 break;
710         default:
711 /* case BRIDGE_SPCA504B: */
712 /* case BRIDGE_SPCA536: */
713                 gspca_dev->usb_buf[0] = Size;
714                 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
715                 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);     /* size */
716                 Type = 6;
717                 gspca_dev->usb_buf[0] = Type;
718                 reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
719                 reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1);     /* type */
720                 rc = spca504B_PollingDataReady(gspca_dev);
721                 break;
722         case BRIDGE_SPCA504:
723                 Size += 3;
724                 if (sd->subtype == AiptekMiniPenCam13) {
725                         /* spca504a aiptek */
726                         spca504A_acknowledged_command(gspca_dev,
727                                                 0x08, Size, 0,
728                                                 0x80 | (Size & 0x0f), 1);
729                         spca504A_acknowledged_command(gspca_dev,
730                                                         1, 3, 0, 0x9f, 0);
731                 } else {
732                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
733                 }
734                 break;
735         case BRIDGE_SPCA504C:
736                 /* capture mode */
737                 reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
738                 reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
739                 break;
740         }
741 }
742
743 static void spca504_wait_status(struct gspca_dev *gspca_dev)
744 {
745         int cnt;
746
747         cnt = 256;
748         while (--cnt > 0) {
749                 /* With this we get the status, when return 0 it's all ok */
750                 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
751                         return;
752                 msleep(10);
753         }
754 }
755
756 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
757 {
758         struct usb_device *dev = gspca_dev->dev;
759
760         gspca_dev->usb_buf[0] = 3;
761         reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
762         reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
763         spca504B_PollingDataReady(gspca_dev);
764 }
765
766 static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
767 {
768         struct sd *sd = (struct sd *) gspca_dev;
769         struct usb_device *dev = gspca_dev->dev;
770         int pollreg = 1;
771
772         switch (sd->bridge) {
773         case BRIDGE_SPCA504:
774         case BRIDGE_SPCA504C:
775                 pollreg = 0;
776                 /* fall thru */
777         default:
778 /*      case BRIDGE_SPCA533: */
779 /*      case BRIDGE_SPCA504B: */
780                 reg_w(dev, 0, 0, 0x21a7, NULL, 0);      /* brightness */
781                 reg_w(dev, 0, 0x20, 0x21a8, NULL, 0);   /* contrast */
782                 reg_w(dev, 0, 0, 0x21ad, NULL, 0);      /* hue */
783                 reg_w(dev, 0, 1, 0x21ac, NULL, 0);      /* sat/hue */
784                 reg_w(dev, 0, 0x20, 0x21ae, NULL, 0);   /* saturation */
785                 reg_w(dev, 0, 0, 0x21a3, NULL, 0);      /* gamma */
786                 break;
787         case BRIDGE_SPCA536:
788                 reg_w(dev, 0, 0, 0x20f0, NULL, 0);
789                 reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
790                 reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
791                 reg_w(dev, 0, 1, 0x20f4, NULL, 0);
792                 reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
793                 reg_w(dev, 0, 0, 0x2089, NULL, 0);
794                 break;
795         }
796         if (pollreg)
797                 spca504B_PollingDataReady(gspca_dev);
798 }
799
800 /* this function is called at probe time */
801 static int sd_config(struct gspca_dev *gspca_dev,
802                         const struct usb_device_id *id)
803 {
804         struct sd *sd = (struct sd *) gspca_dev;
805         struct usb_device *dev = gspca_dev->dev;
806         struct cam *cam;
807         __u16 vendor;
808         __u16 product;
809         __u8 fw;
810
811         vendor = id->idVendor;
812         product = id->idProduct;
813         switch (vendor) {
814         case 0x041e:            /* Creative cameras */
815 /*              switch (product) { */
816 /*              case 0x400b: */
817 /*              case 0x4012: */
818 /*              case 0x4013: */
819 /*                      sd->bridge = BRIDGE_SPCA504C; */
820 /*                      break; */
821 /*              } */
822                 break;
823         case 0x0458:            /* Genius KYE cameras */
824 /*              switch (product) { */
825 /*              case 0x7006: */
826                         sd->bridge = BRIDGE_SPCA504B;
827 /*                      break; */
828 /*              } */
829                 break;
830         case 0x0461:            /* MicroInnovation */
831 /*              switch (product) { */
832 /*              case 0x0821: */
833                         sd->bridge = BRIDGE_SPCA533;
834 /*                      break; */
835 /*              } */
836                 break;
837         case 0x046d:            /* Logitech Labtec */
838                 switch (product) {
839                 case 0x0905:
840                         sd->subtype = LogitechClickSmart820;
841                         sd->bridge = BRIDGE_SPCA533;
842                         break;
843                 case 0x0960:
844                         sd->subtype = LogitechClickSmart420;
845                         sd->bridge = BRIDGE_SPCA504C;
846                         break;
847                 }
848                 break;
849         case 0x0471:                            /* Philips */
850 /*              switch (product) { */
851 /*              case 0x0322: */
852                         sd->bridge = BRIDGE_SPCA504B;
853 /*                      break; */
854 /*              } */
855                 break;
856         case 0x04a5:            /* Benq */
857                 switch (product) {
858                 case 0x3003:
859                         sd->bridge = BRIDGE_SPCA504B;
860                         break;
861                 case 0x3008:
862                 case 0x300a:
863                         sd->bridge = BRIDGE_SPCA533;
864                         break;
865                 }
866                 break;
867         case 0x04f1:            /* JVC */
868 /*              switch (product) { */
869 /*              case 0x1001: */
870                         sd->bridge = BRIDGE_SPCA504B;
871 /*                      break; */
872 /*              } */
873                 break;
874         case 0x04fc:            /* SunPlus */
875                 switch (product) {
876                 case 0x500c:
877                         sd->bridge = BRIDGE_SPCA504B;
878                         break;
879                 case 0x504a:
880 /* try to get the firmware as some cam answer 2.0.1.2.2
881  * and should be a spca504b then overwrite that setting */
882                         reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
883                         fw = gspca_dev->usb_buf[0];
884                         if (fw == 1) {
885                                 sd->subtype = AiptekMiniPenCam13;
886                                 sd->bridge = BRIDGE_SPCA504;
887                         } else if (fw == 2) {
888                                 sd->bridge = BRIDGE_SPCA504B;
889                         } else
890                                 return -ENODEV;
891                         break;
892                 case 0x504b:
893                         sd->bridge = BRIDGE_SPCA504B;
894                         break;
895                 case 0x5330:
896                         sd->bridge = BRIDGE_SPCA533;
897                         break;
898                 case 0x5360:
899                         sd->bridge = BRIDGE_SPCA536;
900                         break;
901                 case 0xffff:
902                         sd->bridge = BRIDGE_SPCA504B;
903                         break;
904                 }
905                 break;
906         case 0x052b:            /* ?? Megapix */
907 /*              switch (product) { */
908 /*              case 0x1513: */
909                         sd->subtype = MegapixV4;
910                         sd->bridge = BRIDGE_SPCA533;
911 /*                      break; */
912 /*              } */
913                 break;
914         case 0x0546:            /* Polaroid */
915                 switch (product) {
916                 case 0x3155:
917                         sd->bridge = BRIDGE_SPCA533;
918                         break;
919                 case 0x3191:
920                 case 0x3273:
921                         sd->bridge = BRIDGE_SPCA504B;
922                         break;
923                 }
924                 break;
925         case 0x055f:            /* Mustek cameras */
926                 switch (product) {
927                 case 0xc211:
928                         sd->bridge = BRIDGE_SPCA536;
929                         break;
930                 case 0xc230:
931                 case 0xc232:
932                         sd->bridge = BRIDGE_SPCA533;
933                         break;
934                 case 0xc360:
935                         sd->bridge = BRIDGE_SPCA536;
936                         break;
937                 case 0xc420:
938                         sd->bridge = BRIDGE_SPCA504;
939                         break;
940                 case 0xc430:
941                 case 0xc440:
942                         sd->bridge = BRIDGE_SPCA533;
943                         break;
944                 case 0xc520:
945                         sd->bridge = BRIDGE_SPCA504;
946                         break;
947                 case 0xc530:
948                 case 0xc540:
949                 case 0xc630:
950                 case 0xc650:
951                         sd->bridge = BRIDGE_SPCA533;
952                         break;
953                 }
954                 break;
955         case 0x05da:            /* Digital Dream cameras */
956 /*              switch (product) { */
957 /*              case 0x1018: */
958                         sd->bridge = BRIDGE_SPCA504B;
959 /*                      break; */
960 /*              } */
961                 break;
962         case 0x06d6:            /* Trust */
963 /*              switch (product) { */
964 /*              case 0x0031: */
965                         sd->bridge = BRIDGE_SPCA533;    /* SPCA533A */
966 /*                      break; */
967 /*              } */
968                 break;
969         case 0x0733:    /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
970                 switch (product) {
971                 case 0x1311:
972                 case 0x1314:
973                 case 0x2211:
974                 case 0x2221:
975                         sd->bridge = BRIDGE_SPCA533;
976                         break;
977                 case 0x3261:
978                 case 0x3281:
979                         sd->bridge = BRIDGE_SPCA536;
980                         break;
981                 }
982                 break;
983         case 0x08ca:            /* Aiptek */
984                 switch (product) {
985                 case 0x0104:
986                 case 0x0106:
987                         sd->bridge = BRIDGE_SPCA533;
988                         break;
989                 case 0x2008:
990                         sd->bridge = BRIDGE_SPCA504B;
991                         break;
992                 case 0x2010:
993                         sd->bridge = BRIDGE_SPCA533;
994                         break;
995                 case 0x2016:
996                 case 0x2018:
997                         sd->bridge = BRIDGE_SPCA504B;
998                         break;
999                 case 0x2020:
1000                 case 0x2022:
1001                         sd->bridge = BRIDGE_SPCA533;
1002                         break;
1003                 case 0x2024:
1004                         sd->bridge = BRIDGE_SPCA536;
1005                         break;
1006                 case 0x2028:
1007                         sd->bridge = BRIDGE_SPCA533;
1008                         break;
1009                 case 0x2040:
1010                 case 0x2042:
1011                 case 0x2060:
1012                         sd->bridge = BRIDGE_SPCA536;
1013                         break;
1014                 }
1015                 break;
1016         case 0x0d64:            /* SunPlus */
1017 /*              switch (product) { */
1018 /*              case 0x0303: */
1019                         sd->bridge = BRIDGE_SPCA536;
1020 /*                      break; */
1021 /*              } */
1022                 break;
1023         }
1024
1025         cam = &gspca_dev->cam;
1026         cam->dev_name = (char *) id->driver_info;
1027         cam->epaddr = 0x01;
1028
1029         switch (sd->bridge) {
1030         default:
1031 /*      case BRIDGE_SPCA504B: */
1032 /*      case BRIDGE_SPCA504: */
1033 /*      case BRIDGE_SPCA536: */
1034                 cam->cam_mode = vga_mode;
1035                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
1036                 break;
1037         case BRIDGE_SPCA533:
1038                 cam->cam_mode = custom_mode;
1039                 cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
1040                 break;
1041         case BRIDGE_SPCA504C:
1042                 cam->cam_mode = vga_mode2;
1043                 cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
1044                 break;
1045         }
1046         sd->qindex = 5;                 /* set the quantization table */
1047         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
1048         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
1049         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
1050         return 0;
1051 }
1052
1053 /* this function is called at open time */
1054 static int sd_open(struct gspca_dev *gspca_dev)
1055 {
1056         struct sd *sd = (struct sd *) gspca_dev;
1057         struct usb_device *dev = gspca_dev->dev;
1058         int rc;
1059         __u8 i;
1060         __u8 info[6];
1061         int err_code;
1062
1063         switch (sd->bridge) {
1064         case BRIDGE_SPCA504B:
1065                 reg_w(dev, 0x1d, 0, 0, NULL, 0);
1066                 reg_w(dev, 0, 1, 0x2306, NULL, 0);
1067                 reg_w(dev, 0, 0, 0x0d04, NULL, 0);
1068                 reg_w(dev, 0, 0, 0x2000, NULL, 0);
1069                 reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
1070                 reg_w(dev, 0, 0, 0x2306, NULL, 0);
1071                 /* fall thru */
1072         case BRIDGE_SPCA533:
1073                 rc = spca504B_PollingDataReady(gspca_dev);
1074                 spca50x_GetFirmware(gspca_dev);
1075                 break;
1076         case BRIDGE_SPCA536:
1077                 spca50x_GetFirmware(gspca_dev);
1078                 reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
1079                 gspca_dev->usb_buf[0] = 0;
1080                 reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
1081                 reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
1082                 rc = spca504B_PollingDataReady(gspca_dev);
1083                 reg_w(dev, 0x34, 0, 0, NULL, 0);
1084                 spca504B_WaitCmdStatus(gspca_dev);
1085                 break;
1086         case BRIDGE_SPCA504C:   /* pccam600 */
1087                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
1088                 reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
1089                 reg_w_riv(dev, 0xe0, 0x0000, 0x0001);   /* reset */
1090                 spca504_wait_status(gspca_dev);
1091                 if (sd->subtype == LogitechClickSmart420)
1092                         write_vector(gspca_dev,
1093                                         spca504A_clicksmart420_open_data);
1094                 else
1095                         write_vector(gspca_dev, spca504_pccam600_open_data);
1096                 err_code = spca50x_setup_qtable(gspca_dev,
1097                                                 0x00, 0x2800,
1098                                                 0x2840, qtable_creative_pccam);
1099                 if (err_code < 0) {
1100                         PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
1101                         return err_code;
1102                 }
1103                 break;
1104         default:
1105 /*      case BRIDGE_SPCA504: */
1106                 PDEBUG(D_STREAM, "Opening SPCA504");
1107                 if (sd->subtype == AiptekMiniPenCam13) {
1108                         /*****************************/
1109                         for (i = 0; i < 6; i++)
1110                                 info[i] = reg_r_1(gspca_dev, i);
1111                         PDEBUG(D_STREAM,
1112                                 "Read info: %d %d %d %d %d %d."
1113                                 " Should be 1,0,2,2,0,0",
1114                                 info[0], info[1], info[2],
1115                                 info[3], info[4], info[5]);
1116                         /* spca504a aiptek */
1117                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1118                         spca504A_acknowledged_command(gspca_dev, 0x24,
1119                                                         8, 3, 0x9e, 1);
1120                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1121                         spca504A_acknowledged_command(gspca_dev, 0x24,
1122                                                         8, 3, 0x9e, 0);
1123
1124                         spca504A_acknowledged_command(gspca_dev, 0x24,
1125                                                         0, 0, 0x9d, 1);
1126                         /******************************/
1127                         /* spca504a aiptek */
1128                         spca504A_acknowledged_command(gspca_dev, 0x08,
1129                                                         6, 0, 0x86, 1);
1130 /*                      reg_write (dev, 0, 0x2000, 0); */
1131 /*                      reg_write (dev, 0, 0x2883, 1); */
1132 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
1133                                                         6, 0, 0x86, 1); */
1134 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
1135                                                         0, 0, 0x9D, 1); */
1136                         reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
1137                         reg_w_riv(dev, 0x0, 0x2310, 0x05);
1138                         spca504A_acknowledged_command(gspca_dev, 0x01,
1139                                                         0x0f, 0, 0xff, 0);
1140                 }
1141                 /* setup qtable */
1142                 reg_w_riv(dev, 0, 0x2000, 0);
1143                 reg_w_riv(dev, 0, 0x2883, 1);
1144                 err_code = spca50x_setup_qtable(gspca_dev,
1145                                                 0x00, 0x2800,
1146                                                 0x2840,
1147                                                 qtable_spca504_default);
1148                 if (err_code < 0) {
1149                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
1150                         return err_code;
1151                 }
1152                 break;
1153         }
1154         return 0;
1155 }
1156
1157 static void sd_start(struct gspca_dev *gspca_dev)
1158 {
1159         struct sd *sd = (struct sd *) gspca_dev;
1160         struct usb_device *dev = gspca_dev->dev;
1161         int rc;
1162         int enable;
1163         __u8 i;
1164         __u8 info[6];
1165
1166         if (sd->bridge == BRIDGE_SPCA504B)
1167                 spca504B_setQtable(gspca_dev);
1168         spca504B_SetSizeType(gspca_dev);
1169         switch (sd->bridge) {
1170         default:
1171 /*      case BRIDGE_SPCA504B: */
1172 /*      case BRIDGE_SPCA533: */
1173 /*      case BRIDGE_SPCA536: */
1174                 if (sd->subtype == MegapixV4 ||
1175                     sd->subtype == LogitechClickSmart820) {
1176                         reg_w(dev, 0xf0, 0, 0, NULL, 0);
1177                         spca504B_WaitCmdStatus(gspca_dev);
1178                         reg_r(dev, 0xf0, 4, NULL, 0);
1179                         spca504B_WaitCmdStatus(gspca_dev);
1180                 } else {
1181                         reg_w(dev, 0x31, 0, 4, NULL, 0);
1182                         spca504B_WaitCmdStatus(gspca_dev);
1183                         rc = spca504B_PollingDataReady(gspca_dev);
1184                 }
1185                 break;
1186         case BRIDGE_SPCA504:
1187                 if (sd->subtype == AiptekMiniPenCam13) {
1188                         for (i = 0; i < 6; i++)
1189                                 info[i] = reg_r_1(gspca_dev, i);
1190                         PDEBUG(D_STREAM,
1191                                 "Read info: %d %d %d %d %d %d."
1192                                 " Should be 1,0,2,2,0,0",
1193                                 info[0], info[1], info[2],
1194                                 info[3], info[4], info[5]);
1195                         /* spca504a aiptek */
1196                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1197                         spca504A_acknowledged_command(gspca_dev, 0x24,
1198                                                         8, 3, 0x9e, 1);
1199                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1200                         spca504A_acknowledged_command(gspca_dev, 0x24,
1201                                                         8, 3, 0x9e, 0);
1202                         spca504A_acknowledged_command(gspca_dev, 0x24,
1203                                                         0, 0, 0x9d, 1);
1204                 } else {
1205                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1206                         for (i = 0; i < 6; i++)
1207                                 info[i] = reg_r_1(gspca_dev, i);
1208                         PDEBUG(D_STREAM,
1209                                 "Read info: %d %d %d %d %d %d."
1210                                 " Should be 1,0,2,2,0,0",
1211                                 info[0], info[1], info[2],
1212                                 info[3], info[4], info[5]);
1213                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1214                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1215                 }
1216                 spca504B_SetSizeType(gspca_dev);
1217                 reg_w_riv(dev, 0x0, 0x270c, 0x05);      /* L92 sno1t.txt */
1218                 reg_w_riv(dev, 0x0, 0x2310, 0x05);
1219                 break;
1220         case BRIDGE_SPCA504C:
1221                 if (sd->subtype == LogitechClickSmart420) {
1222                         write_vector(gspca_dev,
1223                                         spca504A_clicksmart420_init_data);
1224                 } else {
1225                         write_vector(gspca_dev, spca504_pccam600_init_data);
1226                 }
1227                 enable = (sd->autogain ? 0x04 : 0x01);
1228                 reg_w_riv(dev, 0x0c, 0x0000, enable);   /* auto exposure */
1229                 reg_w_riv(dev, 0xb0, 0x0000, enable);   /* auto whiteness */
1230
1231                 /* set default exposure compensation and whiteness balance */
1232                 reg_w_riv(dev, 0x30, 0x0001, 800);      /* ~ 20 fps */
1233                 reg_w_riv(dev, 0x30, 0x0002, 1600);
1234                 spca504B_SetSizeType(gspca_dev);
1235                 break;
1236         }
1237         sp5xx_initContBrigHueRegisters(gspca_dev);
1238 }
1239
1240 static void sd_stopN(struct gspca_dev *gspca_dev)
1241 {
1242         struct sd *sd = (struct sd *) gspca_dev;
1243         struct usb_device *dev = gspca_dev->dev;
1244
1245         switch (sd->bridge) {
1246         default:
1247 /*      case BRIDGE_SPCA533: */
1248 /*      case BRIDGE_SPCA536: */
1249 /*      case BRIDGE_SPCA504B: */
1250                 reg_w(dev, 0x31, 0, 0, NULL, 0);
1251                 spca504B_WaitCmdStatus(gspca_dev);
1252                 spca504B_PollingDataReady(gspca_dev);
1253                 break;
1254         case BRIDGE_SPCA504:
1255         case BRIDGE_SPCA504C:
1256                 reg_w_riv(dev, 0x00, 0x2000, 0x0000);
1257
1258                 if (sd->subtype == AiptekMiniPenCam13) {
1259                         /* spca504a aiptek */
1260 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
1261                                                          6, 0, 0x86, 1); */
1262                         spca504A_acknowledged_command(gspca_dev, 0x24,
1263                                                         0x00, 0x00, 0x9d, 1);
1264                         spca504A_acknowledged_command(gspca_dev, 0x01,
1265                                                         0x0f, 0x00, 0xff, 1);
1266                 } else {
1267                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1268                         reg_w_riv(dev, 0x01, 0x000f, 0x00);
1269                 }
1270                 break;
1271         }
1272 }
1273
1274 static void sd_stop0(struct gspca_dev *gspca_dev)
1275 {
1276 }
1277
1278 static void sd_close(struct gspca_dev *gspca_dev)
1279 {
1280 }
1281
1282 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1283                         struct gspca_frame *frame,      /* target */
1284                         __u8 *data,                     /* isoc packet */
1285                         int len)                        /* iso packet length */
1286 {
1287         struct sd *sd = (struct sd *) gspca_dev;
1288         int i, sof = 0;
1289         unsigned char *s, *d;
1290         static unsigned char ffd9[] = {0xff, 0xd9};
1291
1292 /* frames are jpeg 4.1.1 without 0xff escape */
1293         switch (sd->bridge) {
1294         case BRIDGE_SPCA533:
1295                 if (data[0] == 0xff) {
1296                         if (data[1] != 0x01) {  /* drop packet */
1297 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
1298                                 return;
1299                         }
1300                         sof = 1;
1301                         data += SPCA533_OFFSET_DATA;
1302                         len -= SPCA533_OFFSET_DATA;
1303                 } else {
1304                         data += 1;
1305                         len -= 1;
1306                 }
1307                 break;
1308         case BRIDGE_SPCA536:
1309                 if (data[0] == 0xff) {
1310                         sof = 1;
1311                         data += SPCA536_OFFSET_DATA;
1312                         len -= SPCA536_OFFSET_DATA;
1313                 } else {
1314                         data += 2;
1315                         len -= 2;
1316                 }
1317                 break;
1318         default:
1319 /*      case BRIDGE_SPCA504: */
1320 /*      case BRIDGE_SPCA504B: */
1321                 switch (data[0]) {
1322                 case 0xfe:                      /* start of frame */
1323                         sof = 1;
1324                         data += SPCA50X_OFFSET_DATA;
1325                         len -= SPCA50X_OFFSET_DATA;
1326                         break;
1327                 case 0xff:                      /* drop packet */
1328 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1329                         return;
1330                 default:
1331                         data += 1;
1332                         len -= 1;
1333                         break;
1334                 }
1335                 break;
1336         case BRIDGE_SPCA504C:
1337                 switch (data[0]) {
1338                 case 0xfe:                      /* start of frame */
1339                         sof = 1;
1340                         data += SPCA504_PCCAM600_OFFSET_DATA;
1341                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1342                         break;
1343                 case 0xff:                      /* drop packet */
1344 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1345                         return;
1346                 default:
1347                         data += 1;
1348                         len -= 1;
1349                         break;
1350                 }
1351                 break;
1352         }
1353         if (sof) {              /* start of frame */
1354                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1355                                         ffd9, 2);
1356
1357                 /* put the JPEG header in the new frame */
1358                 jpeg_put_header(gspca_dev, frame,
1359                                 ((struct sd *) gspca_dev)->qindex,
1360                                 0x22);
1361         }
1362
1363         /* add 0x00 after 0xff */
1364         for (i = len; --i >= 0; )
1365                 if (data[i] == 0xff)
1366                         break;
1367         if (i < 0) {                    /* no 0xff */
1368                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1369                 return;
1370         }
1371         s = data;
1372         d = sd->packet;
1373         for (i = 0; i < len; i++) {
1374                 *d++ = *s++;
1375                 if (s[-1] == 0xff)
1376                         *d++ = 0x00;
1377         }
1378         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1379                         sd->packet, d - sd->packet);
1380 }
1381
1382 static void setbrightness(struct gspca_dev *gspca_dev)
1383 {
1384         struct sd *sd = (struct sd *) gspca_dev;
1385         struct usb_device *dev = gspca_dev->dev;
1386
1387         switch (sd->bridge) {
1388         default:
1389 /*      case BRIDGE_SPCA533: */
1390 /*      case BRIDGE_SPCA504B: */
1391 /*      case BRIDGE_SPCA504: */
1392 /*      case BRIDGE_SPCA504C: */
1393                 reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
1394                 break;
1395         case BRIDGE_SPCA536:
1396                 reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
1397                 break;
1398         }
1399 }
1400
1401 static void getbrightness(struct gspca_dev *gspca_dev)
1402 {
1403         struct sd *sd = (struct sd *) gspca_dev;
1404         __u16 brightness = 0;
1405
1406         switch (sd->bridge) {
1407         default:
1408 /*      case BRIDGE_SPCA533: */
1409 /*      case BRIDGE_SPCA504B: */
1410 /*      case BRIDGE_SPCA504: */
1411 /*      case BRIDGE_SPCA504C: */
1412                 brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
1413                 break;
1414         case BRIDGE_SPCA536:
1415                 brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
1416                 break;
1417         }
1418         sd->brightness = ((brightness & 0xff) - 128) % 255;
1419 }
1420
1421 static void setcontrast(struct gspca_dev *gspca_dev)
1422 {
1423         struct sd *sd = (struct sd *) gspca_dev;
1424         struct usb_device *dev = gspca_dev->dev;
1425
1426         switch (sd->bridge) {
1427         default:
1428 /*      case BRIDGE_SPCA533: */
1429 /*      case BRIDGE_SPCA504B: */
1430 /*      case BRIDGE_SPCA504: */
1431 /*      case BRIDGE_SPCA504C: */
1432                 reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
1433                 break;
1434         case BRIDGE_SPCA536:
1435                 reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
1436                 break;
1437         }
1438 }
1439
1440 static void getcontrast(struct gspca_dev *gspca_dev)
1441 {
1442         struct sd *sd = (struct sd *) gspca_dev;
1443
1444         switch (sd->bridge) {
1445         default:
1446 /*      case BRIDGE_SPCA533: */
1447 /*      case BRIDGE_SPCA504B: */
1448 /*      case BRIDGE_SPCA504: */
1449 /*      case BRIDGE_SPCA504C: */
1450                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
1451                 break;
1452         case BRIDGE_SPCA536:
1453                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
1454                 break;
1455         }
1456 }
1457
1458 static void setcolors(struct gspca_dev *gspca_dev)
1459 {
1460         struct sd *sd = (struct sd *) gspca_dev;
1461         struct usb_device *dev = gspca_dev->dev;
1462
1463         switch (sd->bridge) {
1464         default:
1465 /*      case BRIDGE_SPCA533: */
1466 /*      case BRIDGE_SPCA504B: */
1467 /*      case BRIDGE_SPCA504: */
1468 /*      case BRIDGE_SPCA504C: */
1469                 reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
1470                 break;
1471         case BRIDGE_SPCA536:
1472                 reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
1473                 break;
1474         }
1475 }
1476
1477 static void getcolors(struct gspca_dev *gspca_dev)
1478 {
1479         struct sd *sd = (struct sd *) gspca_dev;
1480
1481         switch (sd->bridge) {
1482         default:
1483 /*      case BRIDGE_SPCA533: */
1484 /*      case BRIDGE_SPCA504B: */
1485 /*      case BRIDGE_SPCA504: */
1486 /*      case BRIDGE_SPCA504C: */
1487                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
1488                 break;
1489         case BRIDGE_SPCA536:
1490                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
1491                 break;
1492         }
1493 }
1494
1495 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1496 {
1497         struct sd *sd = (struct sd *) gspca_dev;
1498
1499         sd->brightness = val;
1500         if (gspca_dev->streaming)
1501                 setbrightness(gspca_dev);
1502         return 0;
1503 }
1504
1505 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1506 {
1507         struct sd *sd = (struct sd *) gspca_dev;
1508
1509         getbrightness(gspca_dev);
1510         *val = sd->brightness;
1511         return 0;
1512 }
1513
1514 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1515 {
1516         struct sd *sd = (struct sd *) gspca_dev;
1517
1518         sd->contrast = val;
1519         if (gspca_dev->streaming)
1520                 setcontrast(gspca_dev);
1521         return 0;
1522 }
1523
1524 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1525 {
1526         struct sd *sd = (struct sd *) gspca_dev;
1527
1528         getcontrast(gspca_dev);
1529         *val = sd->contrast;
1530         return 0;
1531 }
1532
1533 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1534 {
1535         struct sd *sd = (struct sd *) gspca_dev;
1536
1537         sd->colors = val;
1538         if (gspca_dev->streaming)
1539                 setcolors(gspca_dev);
1540         return 0;
1541 }
1542
1543 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1544 {
1545         struct sd *sd = (struct sd *) gspca_dev;
1546
1547         getcolors(gspca_dev);
1548         *val = sd->colors;
1549         return 0;
1550 }
1551
1552 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1553 {
1554         struct sd *sd = (struct sd *) gspca_dev;
1555
1556         sd->autogain = val;
1557         return 0;
1558 }
1559
1560 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1561 {
1562         struct sd *sd = (struct sd *) gspca_dev;
1563
1564         *val = sd->autogain;
1565         return 0;
1566 }
1567
1568 /* sub-driver description */
1569 static const struct sd_desc sd_desc = {
1570         .name = MODULE_NAME,
1571         .ctrls = sd_ctrls,
1572         .nctrls = ARRAY_SIZE(sd_ctrls),
1573         .config = sd_config,
1574         .open = sd_open,
1575         .start = sd_start,
1576         .stopN = sd_stopN,
1577         .stop0 = sd_stop0,
1578         .close = sd_close,
1579         .pkt_scan = sd_pkt_scan,
1580 };
1581
1582 /* -- module initialisation -- */
1583 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1584 static const __devinitdata struct usb_device_id device_table[] = {
1585         {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")},
1586         {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")},
1587         {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")},
1588         {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")},
1589         {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")},
1590         {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")},
1591         {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")},
1592         {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")},
1593         {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")},
1594         {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")},
1595         {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")},
1596         {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")},
1597         {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")},
1598         {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")},
1599         {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")},
1600         {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")},
1601         {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")},
1602         {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")},
1603         {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")},
1604         {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")},
1605         {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")},
1606         {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")},
1607         {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")},
1608         {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")},
1609         {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")},
1610         {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")},
1611         {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")},
1612         {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")},
1613         {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")},
1614         {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")},
1615         {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")},
1616         {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")},
1617         {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")},
1618         {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")},
1619         {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")},
1620         {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")},
1621         {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")},
1622         {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")},
1623         {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")},
1624         {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")},
1625         {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")},
1626         {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")},
1627         {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")},
1628         {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")},
1629         {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")},
1630         {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")},
1631         {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")},
1632         {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")},
1633         {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")},
1634         {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")},
1635         {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")},
1636         {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")},
1637         {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")},
1638         {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")},
1639         {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")},
1640         {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")},
1641         {}
1642 };
1643 MODULE_DEVICE_TABLE(usb, device_table);
1644
1645 /* -- device connect -- */
1646 static int sd_probe(struct usb_interface *intf,
1647                         const struct usb_device_id *id)
1648 {
1649         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1650                                 THIS_MODULE);
1651 }
1652
1653 static struct usb_driver sd_driver = {
1654         .name = MODULE_NAME,
1655         .id_table = device_table,
1656         .probe = sd_probe,
1657         .disconnect = gspca_disconnect,
1658 };
1659
1660 /* -- module insert / remove -- */
1661 static int __init sd_mod_init(void)
1662 {
1663         if (usb_register(&sd_driver) < 0)
1664                 return -1;
1665         PDEBUG(D_PROBE, "v%s registered", version);
1666         return 0;
1667 }
1668 static void __exit sd_mod_exit(void)
1669 {
1670         usb_deregister(&sd_driver);
1671         PDEBUG(D_PROBE, "deregistered");
1672 }
1673
1674 module_init(sd_mod_init);
1675 module_exit(sd_mod_exit);