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