]> Pileus Git - ~andy/linux/blob - drivers/media/video/gspca/sunplus.c
V4L/DVB (8512): gspca: Do not use the driver_info field of usb_device_id.
[~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->epaddr = 0x01;
1025
1026         switch (sd->bridge) {
1027         default:
1028 /*      case BRIDGE_SPCA504B: */
1029 /*      case BRIDGE_SPCA504: */
1030 /*      case BRIDGE_SPCA536: */
1031                 cam->cam_mode = vga_mode;
1032                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
1033                 break;
1034         case BRIDGE_SPCA533:
1035                 cam->cam_mode = custom_mode;
1036                 cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
1037                 break;
1038         case BRIDGE_SPCA504C:
1039                 cam->cam_mode = vga_mode2;
1040                 cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
1041                 break;
1042         }
1043         sd->qindex = 5;                 /* set the quantization table */
1044         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
1045         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
1046         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
1047         return 0;
1048 }
1049
1050 /* this function is called at open time */
1051 static int sd_open(struct gspca_dev *gspca_dev)
1052 {
1053         struct sd *sd = (struct sd *) gspca_dev;
1054         struct usb_device *dev = gspca_dev->dev;
1055         int rc;
1056         __u8 i;
1057         __u8 info[6];
1058         int err_code;
1059
1060         switch (sd->bridge) {
1061         case BRIDGE_SPCA504B:
1062                 reg_w(dev, 0x1d, 0, 0, NULL, 0);
1063                 reg_w(dev, 0, 1, 0x2306, NULL, 0);
1064                 reg_w(dev, 0, 0, 0x0d04, NULL, 0);
1065                 reg_w(dev, 0, 0, 0x2000, NULL, 0);
1066                 reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
1067                 reg_w(dev, 0, 0, 0x2306, NULL, 0);
1068                 /* fall thru */
1069         case BRIDGE_SPCA533:
1070                 rc = spca504B_PollingDataReady(gspca_dev);
1071                 spca50x_GetFirmware(gspca_dev);
1072                 break;
1073         case BRIDGE_SPCA536:
1074                 spca50x_GetFirmware(gspca_dev);
1075                 reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
1076                 gspca_dev->usb_buf[0] = 0;
1077                 reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
1078                 reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
1079                 rc = spca504B_PollingDataReady(gspca_dev);
1080                 reg_w(dev, 0x34, 0, 0, NULL, 0);
1081                 spca504B_WaitCmdStatus(gspca_dev);
1082                 break;
1083         case BRIDGE_SPCA504C:   /* pccam600 */
1084                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
1085                 reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
1086                 reg_w_riv(dev, 0xe0, 0x0000, 0x0001);   /* reset */
1087                 spca504_wait_status(gspca_dev);
1088                 if (sd->subtype == LogitechClickSmart420)
1089                         write_vector(gspca_dev,
1090                                         spca504A_clicksmart420_open_data);
1091                 else
1092                         write_vector(gspca_dev, spca504_pccam600_open_data);
1093                 err_code = spca50x_setup_qtable(gspca_dev,
1094                                                 0x00, 0x2800,
1095                                                 0x2840, qtable_creative_pccam);
1096                 if (err_code < 0) {
1097                         PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
1098                         return err_code;
1099                 }
1100                 break;
1101         default:
1102 /*      case BRIDGE_SPCA504: */
1103                 PDEBUG(D_STREAM, "Opening SPCA504");
1104                 if (sd->subtype == AiptekMiniPenCam13) {
1105                         /*****************************/
1106                         for (i = 0; i < 6; i++)
1107                                 info[i] = reg_r_1(gspca_dev, i);
1108                         PDEBUG(D_STREAM,
1109                                 "Read info: %d %d %d %d %d %d."
1110                                 " Should be 1,0,2,2,0,0",
1111                                 info[0], info[1], info[2],
1112                                 info[3], info[4], info[5]);
1113                         /* spca504a aiptek */
1114                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1115                         spca504A_acknowledged_command(gspca_dev, 0x24,
1116                                                         8, 3, 0x9e, 1);
1117                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1118                         spca504A_acknowledged_command(gspca_dev, 0x24,
1119                                                         8, 3, 0x9e, 0);
1120
1121                         spca504A_acknowledged_command(gspca_dev, 0x24,
1122                                                         0, 0, 0x9d, 1);
1123                         /******************************/
1124                         /* spca504a aiptek */
1125                         spca504A_acknowledged_command(gspca_dev, 0x08,
1126                                                         6, 0, 0x86, 1);
1127 /*                      reg_write (dev, 0, 0x2000, 0); */
1128 /*                      reg_write (dev, 0, 0x2883, 1); */
1129 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
1130                                                         6, 0, 0x86, 1); */
1131 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
1132                                                         0, 0, 0x9D, 1); */
1133                         reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
1134                         reg_w_riv(dev, 0x0, 0x2310, 0x05);
1135                         spca504A_acknowledged_command(gspca_dev, 0x01,
1136                                                         0x0f, 0, 0xff, 0);
1137                 }
1138                 /* setup qtable */
1139                 reg_w_riv(dev, 0, 0x2000, 0);
1140                 reg_w_riv(dev, 0, 0x2883, 1);
1141                 err_code = spca50x_setup_qtable(gspca_dev,
1142                                                 0x00, 0x2800,
1143                                                 0x2840,
1144                                                 qtable_spca504_default);
1145                 if (err_code < 0) {
1146                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
1147                         return err_code;
1148                 }
1149                 break;
1150         }
1151         return 0;
1152 }
1153
1154 static void sd_start(struct gspca_dev *gspca_dev)
1155 {
1156         struct sd *sd = (struct sd *) gspca_dev;
1157         struct usb_device *dev = gspca_dev->dev;
1158         int rc;
1159         int enable;
1160         __u8 i;
1161         __u8 info[6];
1162
1163         if (sd->bridge == BRIDGE_SPCA504B)
1164                 spca504B_setQtable(gspca_dev);
1165         spca504B_SetSizeType(gspca_dev);
1166         switch (sd->bridge) {
1167         default:
1168 /*      case BRIDGE_SPCA504B: */
1169 /*      case BRIDGE_SPCA533: */
1170 /*      case BRIDGE_SPCA536: */
1171                 if (sd->subtype == MegapixV4 ||
1172                     sd->subtype == LogitechClickSmart820) {
1173                         reg_w(dev, 0xf0, 0, 0, NULL, 0);
1174                         spca504B_WaitCmdStatus(gspca_dev);
1175                         reg_r(dev, 0xf0, 4, NULL, 0);
1176                         spca504B_WaitCmdStatus(gspca_dev);
1177                 } else {
1178                         reg_w(dev, 0x31, 0, 4, NULL, 0);
1179                         spca504B_WaitCmdStatus(gspca_dev);
1180                         rc = spca504B_PollingDataReady(gspca_dev);
1181                 }
1182                 break;
1183         case BRIDGE_SPCA504:
1184                 if (sd->subtype == AiptekMiniPenCam13) {
1185                         for (i = 0; i < 6; i++)
1186                                 info[i] = reg_r_1(gspca_dev, i);
1187                         PDEBUG(D_STREAM,
1188                                 "Read info: %d %d %d %d %d %d."
1189                                 " Should be 1,0,2,2,0,0",
1190                                 info[0], info[1], info[2],
1191                                 info[3], info[4], info[5]);
1192                         /* spca504a aiptek */
1193                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1194                         spca504A_acknowledged_command(gspca_dev, 0x24,
1195                                                         8, 3, 0x9e, 1);
1196                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1197                         spca504A_acknowledged_command(gspca_dev, 0x24,
1198                                                         8, 3, 0x9e, 0);
1199                         spca504A_acknowledged_command(gspca_dev, 0x24,
1200                                                         0, 0, 0x9d, 1);
1201                 } else {
1202                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1203                         for (i = 0; i < 6; i++)
1204                                 info[i] = reg_r_1(gspca_dev, i);
1205                         PDEBUG(D_STREAM,
1206                                 "Read info: %d %d %d %d %d %d."
1207                                 " Should be 1,0,2,2,0,0",
1208                                 info[0], info[1], info[2],
1209                                 info[3], info[4], info[5]);
1210                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1211                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1212                 }
1213                 spca504B_SetSizeType(gspca_dev);
1214                 reg_w_riv(dev, 0x0, 0x270c, 0x05);      /* L92 sno1t.txt */
1215                 reg_w_riv(dev, 0x0, 0x2310, 0x05);
1216                 break;
1217         case BRIDGE_SPCA504C:
1218                 if (sd->subtype == LogitechClickSmart420) {
1219                         write_vector(gspca_dev,
1220                                         spca504A_clicksmart420_init_data);
1221                 } else {
1222                         write_vector(gspca_dev, spca504_pccam600_init_data);
1223                 }
1224                 enable = (sd->autogain ? 0x04 : 0x01);
1225                 reg_w_riv(dev, 0x0c, 0x0000, enable);   /* auto exposure */
1226                 reg_w_riv(dev, 0xb0, 0x0000, enable);   /* auto whiteness */
1227
1228                 /* set default exposure compensation and whiteness balance */
1229                 reg_w_riv(dev, 0x30, 0x0001, 800);      /* ~ 20 fps */
1230                 reg_w_riv(dev, 0x30, 0x0002, 1600);
1231                 spca504B_SetSizeType(gspca_dev);
1232                 break;
1233         }
1234         sp5xx_initContBrigHueRegisters(gspca_dev);
1235 }
1236
1237 static void sd_stopN(struct gspca_dev *gspca_dev)
1238 {
1239         struct sd *sd = (struct sd *) gspca_dev;
1240         struct usb_device *dev = gspca_dev->dev;
1241
1242         switch (sd->bridge) {
1243         default:
1244 /*      case BRIDGE_SPCA533: */
1245 /*      case BRIDGE_SPCA536: */
1246 /*      case BRIDGE_SPCA504B: */
1247                 reg_w(dev, 0x31, 0, 0, NULL, 0);
1248                 spca504B_WaitCmdStatus(gspca_dev);
1249                 spca504B_PollingDataReady(gspca_dev);
1250                 break;
1251         case BRIDGE_SPCA504:
1252         case BRIDGE_SPCA504C:
1253                 reg_w_riv(dev, 0x00, 0x2000, 0x0000);
1254
1255                 if (sd->subtype == AiptekMiniPenCam13) {
1256                         /* spca504a aiptek */
1257 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
1258                                                          6, 0, 0x86, 1); */
1259                         spca504A_acknowledged_command(gspca_dev, 0x24,
1260                                                         0x00, 0x00, 0x9d, 1);
1261                         spca504A_acknowledged_command(gspca_dev, 0x01,
1262                                                         0x0f, 0x00, 0xff, 1);
1263                 } else {
1264                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1265                         reg_w_riv(dev, 0x01, 0x000f, 0x00);
1266                 }
1267                 break;
1268         }
1269 }
1270
1271 static void sd_stop0(struct gspca_dev *gspca_dev)
1272 {
1273 }
1274
1275 static void sd_close(struct gspca_dev *gspca_dev)
1276 {
1277 }
1278
1279 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1280                         struct gspca_frame *frame,      /* target */
1281                         __u8 *data,                     /* isoc packet */
1282                         int len)                        /* iso packet length */
1283 {
1284         struct sd *sd = (struct sd *) gspca_dev;
1285         int i, sof = 0;
1286         unsigned char *s, *d;
1287         static unsigned char ffd9[] = {0xff, 0xd9};
1288
1289 /* frames are jpeg 4.1.1 without 0xff escape */
1290         switch (sd->bridge) {
1291         case BRIDGE_SPCA533:
1292                 if (data[0] == 0xff) {
1293                         if (data[1] != 0x01) {  /* drop packet */
1294 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
1295                                 return;
1296                         }
1297                         sof = 1;
1298                         data += SPCA533_OFFSET_DATA;
1299                         len -= SPCA533_OFFSET_DATA;
1300                 } else {
1301                         data += 1;
1302                         len -= 1;
1303                 }
1304                 break;
1305         case BRIDGE_SPCA536:
1306                 if (data[0] == 0xff) {
1307                         sof = 1;
1308                         data += SPCA536_OFFSET_DATA;
1309                         len -= SPCA536_OFFSET_DATA;
1310                 } else {
1311                         data += 2;
1312                         len -= 2;
1313                 }
1314                 break;
1315         default:
1316 /*      case BRIDGE_SPCA504: */
1317 /*      case BRIDGE_SPCA504B: */
1318                 switch (data[0]) {
1319                 case 0xfe:                      /* start of frame */
1320                         sof = 1;
1321                         data += SPCA50X_OFFSET_DATA;
1322                         len -= SPCA50X_OFFSET_DATA;
1323                         break;
1324                 case 0xff:                      /* drop packet */
1325 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1326                         return;
1327                 default:
1328                         data += 1;
1329                         len -= 1;
1330                         break;
1331                 }
1332                 break;
1333         case BRIDGE_SPCA504C:
1334                 switch (data[0]) {
1335                 case 0xfe:                      /* start of frame */
1336                         sof = 1;
1337                         data += SPCA504_PCCAM600_OFFSET_DATA;
1338                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1339                         break;
1340                 case 0xff:                      /* drop packet */
1341 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1342                         return;
1343                 default:
1344                         data += 1;
1345                         len -= 1;
1346                         break;
1347                 }
1348                 break;
1349         }
1350         if (sof) {              /* start of frame */
1351                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1352                                         ffd9, 2);
1353
1354                 /* put the JPEG header in the new frame */
1355                 jpeg_put_header(gspca_dev, frame,
1356                                 ((struct sd *) gspca_dev)->qindex,
1357                                 0x22);
1358         }
1359
1360         /* add 0x00 after 0xff */
1361         for (i = len; --i >= 0; )
1362                 if (data[i] == 0xff)
1363                         break;
1364         if (i < 0) {                    /* no 0xff */
1365                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1366                 return;
1367         }
1368         s = data;
1369         d = sd->packet;
1370         for (i = 0; i < len; i++) {
1371                 *d++ = *s++;
1372                 if (s[-1] == 0xff)
1373                         *d++ = 0x00;
1374         }
1375         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1376                         sd->packet, d - sd->packet);
1377 }
1378
1379 static void setbrightness(struct gspca_dev *gspca_dev)
1380 {
1381         struct sd *sd = (struct sd *) gspca_dev;
1382         struct usb_device *dev = gspca_dev->dev;
1383
1384         switch (sd->bridge) {
1385         default:
1386 /*      case BRIDGE_SPCA533: */
1387 /*      case BRIDGE_SPCA504B: */
1388 /*      case BRIDGE_SPCA504: */
1389 /*      case BRIDGE_SPCA504C: */
1390                 reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
1391                 break;
1392         case BRIDGE_SPCA536:
1393                 reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
1394                 break;
1395         }
1396 }
1397
1398 static void getbrightness(struct gspca_dev *gspca_dev)
1399 {
1400         struct sd *sd = (struct sd *) gspca_dev;
1401         __u16 brightness = 0;
1402
1403         switch (sd->bridge) {
1404         default:
1405 /*      case BRIDGE_SPCA533: */
1406 /*      case BRIDGE_SPCA504B: */
1407 /*      case BRIDGE_SPCA504: */
1408 /*      case BRIDGE_SPCA504C: */
1409                 brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
1410                 break;
1411         case BRIDGE_SPCA536:
1412                 brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
1413                 break;
1414         }
1415         sd->brightness = ((brightness & 0xff) - 128) % 255;
1416 }
1417
1418 static void setcontrast(struct gspca_dev *gspca_dev)
1419 {
1420         struct sd *sd = (struct sd *) gspca_dev;
1421         struct usb_device *dev = gspca_dev->dev;
1422
1423         switch (sd->bridge) {
1424         default:
1425 /*      case BRIDGE_SPCA533: */
1426 /*      case BRIDGE_SPCA504B: */
1427 /*      case BRIDGE_SPCA504: */
1428 /*      case BRIDGE_SPCA504C: */
1429                 reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
1430                 break;
1431         case BRIDGE_SPCA536:
1432                 reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
1433                 break;
1434         }
1435 }
1436
1437 static void getcontrast(struct gspca_dev *gspca_dev)
1438 {
1439         struct sd *sd = (struct sd *) gspca_dev;
1440
1441         switch (sd->bridge) {
1442         default:
1443 /*      case BRIDGE_SPCA533: */
1444 /*      case BRIDGE_SPCA504B: */
1445 /*      case BRIDGE_SPCA504: */
1446 /*      case BRIDGE_SPCA504C: */
1447                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
1448                 break;
1449         case BRIDGE_SPCA536:
1450                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
1451                 break;
1452         }
1453 }
1454
1455 static void setcolors(struct gspca_dev *gspca_dev)
1456 {
1457         struct sd *sd = (struct sd *) gspca_dev;
1458         struct usb_device *dev = gspca_dev->dev;
1459
1460         switch (sd->bridge) {
1461         default:
1462 /*      case BRIDGE_SPCA533: */
1463 /*      case BRIDGE_SPCA504B: */
1464 /*      case BRIDGE_SPCA504: */
1465 /*      case BRIDGE_SPCA504C: */
1466                 reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
1467                 break;
1468         case BRIDGE_SPCA536:
1469                 reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
1470                 break;
1471         }
1472 }
1473
1474 static void getcolors(struct gspca_dev *gspca_dev)
1475 {
1476         struct sd *sd = (struct sd *) gspca_dev;
1477
1478         switch (sd->bridge) {
1479         default:
1480 /*      case BRIDGE_SPCA533: */
1481 /*      case BRIDGE_SPCA504B: */
1482 /*      case BRIDGE_SPCA504: */
1483 /*      case BRIDGE_SPCA504C: */
1484                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
1485                 break;
1486         case BRIDGE_SPCA536:
1487                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
1488                 break;
1489         }
1490 }
1491
1492 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1493 {
1494         struct sd *sd = (struct sd *) gspca_dev;
1495
1496         sd->brightness = val;
1497         if (gspca_dev->streaming)
1498                 setbrightness(gspca_dev);
1499         return 0;
1500 }
1501
1502 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1503 {
1504         struct sd *sd = (struct sd *) gspca_dev;
1505
1506         getbrightness(gspca_dev);
1507         *val = sd->brightness;
1508         return 0;
1509 }
1510
1511 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1512 {
1513         struct sd *sd = (struct sd *) gspca_dev;
1514
1515         sd->contrast = val;
1516         if (gspca_dev->streaming)
1517                 setcontrast(gspca_dev);
1518         return 0;
1519 }
1520
1521 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1522 {
1523         struct sd *sd = (struct sd *) gspca_dev;
1524
1525         getcontrast(gspca_dev);
1526         *val = sd->contrast;
1527         return 0;
1528 }
1529
1530 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1531 {
1532         struct sd *sd = (struct sd *) gspca_dev;
1533
1534         sd->colors = val;
1535         if (gspca_dev->streaming)
1536                 setcolors(gspca_dev);
1537         return 0;
1538 }
1539
1540 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1541 {
1542         struct sd *sd = (struct sd *) gspca_dev;
1543
1544         getcolors(gspca_dev);
1545         *val = sd->colors;
1546         return 0;
1547 }
1548
1549 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1550 {
1551         struct sd *sd = (struct sd *) gspca_dev;
1552
1553         sd->autogain = val;
1554         return 0;
1555 }
1556
1557 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1558 {
1559         struct sd *sd = (struct sd *) gspca_dev;
1560
1561         *val = sd->autogain;
1562         return 0;
1563 }
1564
1565 /* sub-driver description */
1566 static const struct sd_desc sd_desc = {
1567         .name = MODULE_NAME,
1568         .ctrls = sd_ctrls,
1569         .nctrls = ARRAY_SIZE(sd_ctrls),
1570         .config = sd_config,
1571         .open = sd_open,
1572         .start = sd_start,
1573         .stopN = sd_stopN,
1574         .stop0 = sd_stop0,
1575         .close = sd_close,
1576         .pkt_scan = sd_pkt_scan,
1577 };
1578
1579 /* -- module initialisation -- */
1580 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1581 static const __devinitdata struct usb_device_id device_table[] = {
1582         {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")},
1583         {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")},
1584         {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")},
1585         {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")},
1586         {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")},
1587         {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")},
1588         {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")},
1589         {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")},
1590         {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")},
1591         {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")},
1592         {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")},
1593         {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")},
1594         {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")},
1595         {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")},
1596         {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")},
1597         {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")},
1598         {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")},
1599         {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")},
1600         {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")},
1601         {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")},
1602         {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")},
1603         {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")},
1604         {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")},
1605         {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")},
1606         {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")},
1607         {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")},
1608         {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")},
1609         {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")},
1610         {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")},
1611         {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")},
1612         {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")},
1613         {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")},
1614         {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")},
1615         {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")},
1616         {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")},
1617         {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")},
1618         {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")},
1619         {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")},
1620         {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")},
1621         {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")},
1622         {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")},
1623         {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")},
1624         {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")},
1625         {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")},
1626         {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")},
1627         {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")},
1628         {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")},
1629         {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")},
1630         {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")},
1631         {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")},
1632         {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")},
1633         {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")},
1634         {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")},
1635         {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")},
1636         {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")},
1637         {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")},
1638         {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")},
1639         {}
1640 };
1641 MODULE_DEVICE_TABLE(usb, device_table);
1642
1643 /* -- device connect -- */
1644 static int sd_probe(struct usb_interface *intf,
1645                         const struct usb_device_id *id)
1646 {
1647         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1648                                 THIS_MODULE);
1649 }
1650
1651 static struct usb_driver sd_driver = {
1652         .name = MODULE_NAME,
1653         .id_table = device_table,
1654         .probe = sd_probe,
1655         .disconnect = gspca_disconnect,
1656 };
1657
1658 /* -- module insert / remove -- */
1659 static int __init sd_mod_init(void)
1660 {
1661         if (usb_register(&sd_driver) < 0)
1662                 return -1;
1663         PDEBUG(D_PROBE, "registered");
1664         return 0;
1665 }
1666 static void __exit sd_mod_exit(void)
1667 {
1668         usb_deregister(&sd_driver);
1669         PDEBUG(D_PROBE, "deregistered");
1670 }
1671
1672 module_init(sd_mod_init);
1673 module_exit(sd_mod_exit);