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