V4L/DVB (10336): gspca - all subdrivers: Return ret instead of -1 in sd_mod_init.
[safe/jmp/linux-2.6] / drivers / media / video / gspca / spca500.c
1 /*
2  * SPCA500 chip based cameras initialization data
3  *
4  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21
22 #define MODULE_NAME "spca500"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA500 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
42         char qindex;
43         char subtype;
44 #define AgfaCl20 0
45 #define AiptekPocketDV 1
46 #define BenqDC1016 2
47 #define CreativePCCam300 3
48 #define DLinkDSC350 4
49 #define Gsmartmini 5
50 #define IntelPocketPCCamera 6
51 #define KodakEZ200 7
52 #define LogitechClickSmart310 8
53 #define LogitechClickSmart510 9
54 #define LogitechTraveler 10
55 #define MustekGsmart300 11
56 #define Optimedia 12
57 #define PalmPixDC85 13
58 #define ToptroIndus 14
59 };
60
61 /* V4L2 controls supported by the driver */
62 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
68
69 static struct ctrl sd_ctrls[] = {
70         {
71             {
72                 .id      = V4L2_CID_BRIGHTNESS,
73                 .type    = V4L2_CTRL_TYPE_INTEGER,
74                 .name    = "Brightness",
75                 .minimum = 0,
76                 .maximum = 255,
77                 .step    = 1,
78 #define BRIGHTNESS_DEF 127
79                 .default_value = BRIGHTNESS_DEF,
80             },
81             .set = sd_setbrightness,
82             .get = sd_getbrightness,
83         },
84         {
85             {
86                 .id      = V4L2_CID_CONTRAST,
87                 .type    = V4L2_CTRL_TYPE_INTEGER,
88                 .name    = "Contrast",
89                 .minimum = 0,
90                 .maximum = 63,
91                 .step    = 1,
92 #define CONTRAST_DEF 31
93                 .default_value = CONTRAST_DEF,
94             },
95             .set = sd_setcontrast,
96             .get = sd_getcontrast,
97         },
98         {
99             {
100                 .id      = V4L2_CID_SATURATION,
101                 .type    = V4L2_CTRL_TYPE_INTEGER,
102                 .name    = "Color",
103                 .minimum = 0,
104                 .maximum = 63,
105                 .step    = 1,
106 #define COLOR_DEF 31
107                 .default_value = COLOR_DEF,
108             },
109             .set = sd_setcolors,
110             .get = sd_getcolors,
111         },
112 };
113
114 static const struct v4l2_pix_format vga_mode[] = {
115         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
116                 .bytesperline = 320,
117                 .sizeimage = 320 * 240 * 3 / 8 + 590,
118                 .colorspace = V4L2_COLORSPACE_JPEG,
119                 .priv = 1},
120         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
121                 .bytesperline = 640,
122                 .sizeimage = 640 * 480 * 3 / 8 + 590,
123                 .colorspace = V4L2_COLORSPACE_JPEG,
124                 .priv = 0},
125 };
126
127 static const struct v4l2_pix_format sif_mode[] = {
128         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
129                 .bytesperline = 176,
130                 .sizeimage = 176 * 144 * 3 / 8 + 590,
131                 .colorspace = V4L2_COLORSPACE_JPEG,
132                 .priv = 1},
133         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
134                 .bytesperline = 352,
135                 .sizeimage = 352 * 288 * 3 / 8 + 590,
136                 .colorspace = V4L2_COLORSPACE_JPEG,
137                 .priv = 0},
138 };
139
140 /* Frame packet header offsets for the spca500 */
141 #define SPCA500_OFFSET_PADDINGLB 2
142 #define SPCA500_OFFSET_PADDINGHB 3
143 #define SPCA500_OFFSET_MODE      4
144 #define SPCA500_OFFSET_IMGWIDTH  5
145 #define SPCA500_OFFSET_IMGHEIGHT 6
146 #define SPCA500_OFFSET_IMGMODE   7
147 #define SPCA500_OFFSET_QTBLINDEX 8
148 #define SPCA500_OFFSET_FRAMSEQ   9
149 #define SPCA500_OFFSET_CDSPINFO  10
150 #define SPCA500_OFFSET_GPIO      11
151 #define SPCA500_OFFSET_AUGPIO    12
152 #define SPCA500_OFFSET_DATA      16
153
154
155 static const __u16 spca500_visual_defaults[][3] = {
156         {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
157                                  * hue (H byte) = 0,
158                                  * saturation/hue enable,
159                                  * brightness/contrast enable.
160                                  */
161         {0x00, 0x0000, 0x8167}, /* brightness = 0 */
162         {0x00, 0x0020, 0x8168}, /* contrast = 0 */
163         {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
164                                  * hue (H byte) = 0, saturation/hue enable,
165                                  * brightness/contrast enable.
166                                  * was 0x0003, now 0x0000.
167                                  */
168         {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
169         {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
170         {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
171         {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
172         {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
173         {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
174         {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
175         {0x0c, 0x0004, 0x0000},
176         /* set interface */
177         {}
178 };
179 static const __u16 Clicksmart510_defaults[][3] = {
180         {0x00, 0x00, 0x8211},
181         {0x00, 0x01, 0x82c0},
182         {0x00, 0x10, 0x82cb},
183         {0x00, 0x0f, 0x800d},
184         {0x00, 0x82, 0x8225},
185         {0x00, 0x21, 0x8228},
186         {0x00, 0x00, 0x8203},
187         {0x00, 0x00, 0x8204},
188         {0x00, 0x08, 0x8205},
189         {0x00, 0xf8, 0x8206},
190         {0x00, 0x28, 0x8207},
191         {0x00, 0xa0, 0x8208},
192         {0x00, 0x08, 0x824a},
193         {0x00, 0x08, 0x8214},
194         {0x00, 0x80, 0x82c1},
195         {0x00, 0x00, 0x82c2},
196         {0x00, 0x00, 0x82ca},
197         {0x00, 0x80, 0x82c1},
198         {0x00, 0x04, 0x82c2},
199         {0x00, 0x00, 0x82ca},
200         {0x00, 0xfc, 0x8100},
201         {0x00, 0xfc, 0x8105},
202         {0x00, 0x30, 0x8101},
203         {0x00, 0x00, 0x8102},
204         {0x00, 0x00, 0x8103},
205         {0x00, 0x66, 0x8107},
206         {0x00, 0x00, 0x816b},
207         {0x00, 0x00, 0x8155},
208         {0x00, 0x01, 0x8156},
209         {0x00, 0x60, 0x8157},
210         {0x00, 0x40, 0x8158},
211         {0x00, 0x0a, 0x8159},
212         {0x00, 0x06, 0x815a},
213         {0x00, 0x00, 0x813f},
214         {0x00, 0x00, 0x8200},
215         {0x00, 0x19, 0x8201},
216         {0x00, 0x00, 0x82c1},
217         {0x00, 0xa0, 0x82c2},
218         {0x00, 0x00, 0x82ca},
219         {0x00, 0x00, 0x8117},
220         {0x00, 0x00, 0x8118},
221         {0x00, 0x65, 0x8119},
222         {0x00, 0x00, 0x811a},
223         {0x00, 0x00, 0x811b},
224         {0x00, 0x55, 0x811c},
225         {0x00, 0x65, 0x811d},
226         {0x00, 0x55, 0x811e},
227         {0x00, 0x16, 0x811f},
228         {0x00, 0x19, 0x8120},
229         {0x00, 0x80, 0x8103},
230         {0x00, 0x83, 0x816b},
231         {0x00, 0x25, 0x8168},
232         {0x00, 0x01, 0x820f},
233         {0x00, 0xff, 0x8115},
234         {0x00, 0x48, 0x8116},
235         {0x00, 0x50, 0x8151},
236         {0x00, 0x40, 0x8152},
237         {0x00, 0x78, 0x8153},
238         {0x00, 0x40, 0x8154},
239         {0x00, 0x00, 0x8167},
240         {0x00, 0x20, 0x8168},
241         {0x00, 0x00, 0x816a},
242         {0x00, 0x03, 0x816b},
243         {0x00, 0x20, 0x8169},
244         {0x00, 0x60, 0x8157},
245         {0x00, 0x00, 0x8190},
246         {0x00, 0x00, 0x81a1},
247         {0x00, 0x00, 0x81b2},
248         {0x00, 0x27, 0x8191},
249         {0x00, 0x27, 0x81a2},
250         {0x00, 0x27, 0x81b3},
251         {0x00, 0x4b, 0x8192},
252         {0x00, 0x4b, 0x81a3},
253         {0x00, 0x4b, 0x81b4},
254         {0x00, 0x66, 0x8193},
255         {0x00, 0x66, 0x81a4},
256         {0x00, 0x66, 0x81b5},
257         {0x00, 0x79, 0x8194},
258         {0x00, 0x79, 0x81a5},
259         {0x00, 0x79, 0x81b6},
260         {0x00, 0x8a, 0x8195},
261         {0x00, 0x8a, 0x81a6},
262         {0x00, 0x8a, 0x81b7},
263         {0x00, 0x9b, 0x8196},
264         {0x00, 0x9b, 0x81a7},
265         {0x00, 0x9b, 0x81b8},
266         {0x00, 0xa6, 0x8197},
267         {0x00, 0xa6, 0x81a8},
268         {0x00, 0xa6, 0x81b9},
269         {0x00, 0xb2, 0x8198},
270         {0x00, 0xb2, 0x81a9},
271         {0x00, 0xb2, 0x81ba},
272         {0x00, 0xbe, 0x8199},
273         {0x00, 0xbe, 0x81aa},
274         {0x00, 0xbe, 0x81bb},
275         {0x00, 0xc8, 0x819a},
276         {0x00, 0xc8, 0x81ab},
277         {0x00, 0xc8, 0x81bc},
278         {0x00, 0xd2, 0x819b},
279         {0x00, 0xd2, 0x81ac},
280         {0x00, 0xd2, 0x81bd},
281         {0x00, 0xdb, 0x819c},
282         {0x00, 0xdb, 0x81ad},
283         {0x00, 0xdb, 0x81be},
284         {0x00, 0xe4, 0x819d},
285         {0x00, 0xe4, 0x81ae},
286         {0x00, 0xe4, 0x81bf},
287         {0x00, 0xed, 0x819e},
288         {0x00, 0xed, 0x81af},
289         {0x00, 0xed, 0x81c0},
290         {0x00, 0xf7, 0x819f},
291         {0x00, 0xf7, 0x81b0},
292         {0x00, 0xf7, 0x81c1},
293         {0x00, 0xff, 0x81a0},
294         {0x00, 0xff, 0x81b1},
295         {0x00, 0xff, 0x81c2},
296         {0x00, 0x03, 0x8156},
297         {0x00, 0x00, 0x8211},
298         {0x00, 0x20, 0x8168},
299         {0x00, 0x01, 0x8202},
300         {0x00, 0x30, 0x8101},
301         {0x00, 0x00, 0x8111},
302         {0x00, 0x00, 0x8112},
303         {0x00, 0x00, 0x8113},
304         {0x00, 0x00, 0x8114},
305         {}
306 };
307
308 static const __u8 qtable_creative_pccam[2][64] = {
309         {                               /* Q-table Y-components */
310          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
311          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
312          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
313          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
314          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
315          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
316          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
317          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
318         {                               /* Q-table C-components */
319          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
320          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
321          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
322          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
323          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
327 };
328
329 static const __u8 qtable_kodak_ez200[2][64] = {
330         {                               /* Q-table Y-components */
331          0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
332          0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
333          0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
334          0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
335          0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
336          0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
337          0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
338          0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
339         {                               /* Q-table C-components */
340          0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
341          0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
342          0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
343          0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
344          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347          0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
348 };
349
350 static const __u8 qtable_pocketdv[2][64] = {
351         {               /* Q-table Y-components start registers 0x8800 */
352          0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
353          0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
354          0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
355          0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
356          0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
357          0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
358          0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
359          0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
360          },
361         {               /* Q-table C-components start registers 0x8840 */
362          0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
363          0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
364          0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
365          0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
366          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
367          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369          0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
370 };
371
372 /* read 'len' bytes to gspca_dev->usb_buf */
373 static void reg_r(struct gspca_dev *gspca_dev,
374                   __u16 index,
375                   __u16 length)
376 {
377         usb_control_msg(gspca_dev->dev,
378                         usb_rcvctrlpipe(gspca_dev->dev, 0),
379                         0,
380                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
381                         0,              /* value */
382                         index, gspca_dev->usb_buf, length, 500);
383 }
384
385 static int reg_w(struct gspca_dev *gspca_dev,
386                      __u16 req, __u16 index, __u16 value)
387 {
388         int ret;
389
390         PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
391         ret = usb_control_msg(gspca_dev->dev,
392                         usb_sndctrlpipe(gspca_dev->dev, 0),
393                         req,
394                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
395                         value, index, NULL, 0, 500);
396         if (ret < 0)
397                 PDEBUG(D_ERR, "reg write: error %d", ret);
398         return ret;
399 }
400
401 /* returns: negative is error, pos or zero is data */
402 static int reg_r_12(struct gspca_dev *gspca_dev,
403                         __u16 req,      /* bRequest */
404                         __u16 index,    /* wIndex */
405                         __u16 length)   /* wLength (1 or 2 only) */
406 {
407         int ret;
408
409         gspca_dev->usb_buf[1] = 0;
410         ret = usb_control_msg(gspca_dev->dev,
411                         usb_rcvctrlpipe(gspca_dev->dev, 0),
412                         req,
413                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
414                         0,              /* value */
415                         index,
416                         gspca_dev->usb_buf, length,
417                         500);           /* timeout */
418         if (ret < 0) {
419                 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
420                 return -1;
421         }
422         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
423 }
424
425 /*
426  * Simple function to wait for a given 8-bit value to be returned from
427  * a reg_read call.
428  * Returns: negative is error or timeout, zero is success.
429  */
430 static int reg_r_wait(struct gspca_dev *gspca_dev,
431                         __u16 reg, __u16 index, __u16 value)
432 {
433         int ret, cnt = 20;
434
435         while (--cnt > 0) {
436                 ret = reg_r_12(gspca_dev, reg, index, 1);
437                 if (ret == value)
438                         return 0;
439                 msleep(50);
440         }
441         return -EIO;
442 }
443
444 static int write_vector(struct gspca_dev *gspca_dev,
445                         const __u16 data[][3])
446 {
447         int ret, i = 0;
448
449         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
450                 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
451                 if (ret < 0)
452                         return ret;
453                 i++;
454         }
455         return 0;
456 }
457
458 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
459                                 unsigned int request,
460                                 unsigned int ybase,
461                                 unsigned int cbase,
462                                 const __u8 qtable[2][64])
463 {
464         int i, err;
465
466         /* loop over y components */
467         for (i = 0; i < 64; i++) {
468                 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
469                 if (err < 0)
470                         return err;
471         }
472
473         /* loop over c components */
474         for (i = 0; i < 64; i++) {
475                 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
476                 if (err < 0)
477                         return err;
478         }
479         return 0;
480 }
481
482 static void spca500_ping310(struct gspca_dev *gspca_dev)
483 {
484         reg_r(gspca_dev, 0x0d04, 2);
485         PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
486                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
487 }
488
489 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
490 {
491         reg_r(gspca_dev, 0x0d05, 2);
492         PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
493                 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
494         reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
495         spca500_ping310(gspca_dev);
496
497         reg_w(gspca_dev, 0x00, 0x8168, 0x22);
498         reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
499         reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
500         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
501         reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
502         reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
503         reg_w(gspca_dev, 0x00, 0x813f, 0x03);
504         reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
505         reg_w(gspca_dev, 0x00, 0x8153, 0x78);
506         reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
507                                                 /* 00 for adjust shutter */
508         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
509         reg_w(gspca_dev, 0x00, 0x8169, 0x25);
510         reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
511 }
512
513 static void spca500_setmode(struct gspca_dev *gspca_dev,
514                         __u8 xmult, __u8 ymult)
515 {
516         int mode;
517
518         /* set x multiplier */
519         reg_w(gspca_dev, 0, 0x8001, xmult);
520
521         /* set y multiplier */
522         reg_w(gspca_dev, 0, 0x8002, ymult);
523
524         /* use compressed mode, VGA, with mode specific subsample */
525         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
526         reg_w(gspca_dev, 0, 0x8003, mode << 4);
527 }
528
529 static int spca500_full_reset(struct gspca_dev *gspca_dev)
530 {
531         int err;
532
533         /* send the reset command */
534         err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
535         if (err < 0)
536                 return err;
537
538         /* wait for the reset to complete */
539         err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
540         if (err < 0)
541                 return err;
542         err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
543         if (err < 0)
544                 return err;
545         err = reg_r_wait(gspca_dev, 0x06, 0, 0);
546         if (err < 0) {
547                 PDEBUG(D_ERR, "reg_r_wait() failed");
548                 return err;
549         }
550         /* all ok */
551         return 0;
552 }
553
554 /* Synchro the Bridge with sensor */
555 /* Maybe that will work on all spca500 chip */
556 /* because i only own a clicksmart310 try for that chip */
557 /* using spca50x_set_packet_size() cause an Ooops here */
558 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
559 /* up-port the same feature as in 2.4.x kernel */
560 static int spca500_synch310(struct gspca_dev *gspca_dev)
561 {
562         if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
563                 PDEBUG(D_ERR, "Set packet size: set interface error");
564                 goto error;
565         }
566         spca500_ping310(gspca_dev);
567
568         reg_r(gspca_dev, 0x0d00, 1);
569
570         /* need alt setting here */
571         PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
572
573         /* Windoze use pipe with altsetting 6 why 7 here */
574         if (usb_set_interface(gspca_dev->dev,
575                                 gspca_dev->iface,
576                                 gspca_dev->alt) < 0) {
577                 PDEBUG(D_ERR, "Set packet size: set interface error");
578                 goto error;
579         }
580         return 0;
581 error:
582         return -EBUSY;
583 }
584
585 static void spca500_reinit(struct gspca_dev *gspca_dev)
586 {
587         int err;
588         __u8 Data;
589
590         /* some unknow command from Aiptek pocket dv and family300 */
591
592         reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
593         reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
594         reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
595
596         /* enable drop packet */
597         reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
598
599         err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
600                                  qtable_pocketdv);
601         if (err < 0)
602                 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
603
604         /* set qtable index */
605         reg_w(gspca_dev, 0x00, 0x8880, 2);
606         /* family cam Quicksmart stuff */
607         reg_w(gspca_dev, 0x00, 0x800a, 0x00);
608         /* Set agc transfer: synced inbetween frames */
609         reg_w(gspca_dev, 0x00, 0x820f, 0x01);
610         /* Init SDRAM - needed for SDRAM access */
611         reg_w(gspca_dev, 0x00, 0x870a, 0x04);
612         /*Start init sequence or stream */
613         reg_w(gspca_dev, 0, 0x8003, 0x00);
614         /* switch to video camera mode */
615         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
616         msleep(2000);
617         if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
618                 reg_r(gspca_dev, 0x816b, 1);
619                 Data = gspca_dev->usb_buf[0];
620                 reg_w(gspca_dev, 0x00, 0x816b, Data);
621         }
622 }
623
624 /* this function is called at probe time */
625 static int sd_config(struct gspca_dev *gspca_dev,
626                         const struct usb_device_id *id)
627 {
628         struct sd *sd = (struct sd *) gspca_dev;
629         struct cam *cam;
630
631         cam = &gspca_dev->cam;
632         sd->subtype = id->driver_info;
633         if (sd->subtype != LogitechClickSmart310) {
634                 cam->cam_mode = vga_mode;
635                 cam->nmodes = ARRAY_SIZE(vga_mode);
636         } else {
637                 cam->cam_mode = sif_mode;
638                 cam->nmodes = ARRAY_SIZE(sif_mode);
639         }
640         sd->qindex = 5;
641         sd->brightness = BRIGHTNESS_DEF;
642         sd->contrast = CONTRAST_DEF;
643         sd->colors = COLOR_DEF;
644         return 0;
645 }
646
647 /* this function is called at probe and resume time */
648 static int sd_init(struct gspca_dev *gspca_dev)
649 {
650         struct sd *sd = (struct sd *) gspca_dev;
651
652         /* initialisation of spca500 based cameras is deferred */
653         PDEBUG(D_STREAM, "SPCA500 init");
654         if (sd->subtype == LogitechClickSmart310)
655                 spca500_clksmart310_init(gspca_dev);
656 /*      else
657                 spca500_initialise(gspca_dev); */
658         PDEBUG(D_STREAM, "SPCA500 init done");
659         return 0;
660 }
661
662 static int sd_start(struct gspca_dev *gspca_dev)
663 {
664         struct sd *sd = (struct sd *) gspca_dev;
665         int err;
666         __u8 Data;
667         __u8 xmult, ymult;
668
669         if (sd->subtype == LogitechClickSmart310) {
670                 xmult = 0x16;
671                 ymult = 0x12;
672         } else {
673                 xmult = 0x28;
674                 ymult = 0x1e;
675         }
676
677         /* is there a sensor here ? */
678         reg_r(gspca_dev, 0x8a04, 1);
679         PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
680                 gspca_dev->usb_buf[0]);
681         PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
682                 gspca_dev->curr_mode, xmult, ymult);
683
684         /* setup qtable */
685         switch (sd->subtype) {
686         case LogitechClickSmart310:
687                  spca500_setmode(gspca_dev, xmult, ymult);
688
689                 /* enable drop packet */
690                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
691                 reg_w(gspca_dev, 0x00, 0x8880, 3);
692                 err = spca50x_setup_qtable(gspca_dev,
693                                            0x00, 0x8800, 0x8840,
694                                            qtable_creative_pccam);
695                 if (err < 0)
696                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
697                 /* Init SDRAM - needed for SDRAM access */
698                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
699
700                 /* switch to video camera mode */
701                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
702                 msleep(500);
703                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
704                         PDEBUG(D_ERR, "reg_r_wait() failed");
705
706                 reg_r(gspca_dev, 0x816b, 1);
707                 Data = gspca_dev->usb_buf[0];
708                 reg_w(gspca_dev, 0x00, 0x816b, Data);
709
710                 spca500_synch310(gspca_dev);
711
712                 write_vector(gspca_dev, spca500_visual_defaults);
713                 spca500_setmode(gspca_dev, xmult, ymult);
714                 /* enable drop packet */
715                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
716                         PDEBUG(D_ERR, "failed to enable drop packet");
717                 reg_w(gspca_dev, 0x00, 0x8880, 3);
718                 err = spca50x_setup_qtable(gspca_dev,
719                                            0x00, 0x8800, 0x8840,
720                                            qtable_creative_pccam);
721                 if (err < 0)
722                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
723
724                 /* Init SDRAM - needed for SDRAM access */
725                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
726
727                 /* switch to video camera mode */
728                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
729
730                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
731                         PDEBUG(D_ERR, "reg_r_wait() failed");
732
733                 reg_r(gspca_dev, 0x816b, 1);
734                 Data = gspca_dev->usb_buf[0];
735                 reg_w(gspca_dev, 0x00, 0x816b, Data);
736                 break;
737         case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
738         case IntelPocketPCCamera:       /* FIXME: Temporary fix for
739                                          *      Intel Pocket PC Camera
740                                          *      - NWG (Sat 29th March 2003) */
741
742                 /* do a full reset */
743                 err = spca500_full_reset(gspca_dev);
744                 if (err < 0)
745                         PDEBUG(D_ERR, "spca500_full_reset failed");
746
747                 /* enable drop packet */
748                 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
749                 if (err < 0)
750                         PDEBUG(D_ERR, "failed to enable drop packet");
751                 reg_w(gspca_dev, 0x00, 0x8880, 3);
752                 err = spca50x_setup_qtable(gspca_dev,
753                                            0x00, 0x8800, 0x8840,
754                                            qtable_creative_pccam);
755                 if (err < 0)
756                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
757
758                 spca500_setmode(gspca_dev, xmult, ymult);
759                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
760
761                 /* switch to video camera mode */
762                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
763
764                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
765                         PDEBUG(D_ERR, "reg_r_wait() failed");
766
767                 reg_r(gspca_dev, 0x816b, 1);
768                 Data = gspca_dev->usb_buf[0];
769                 reg_w(gspca_dev, 0x00, 0x816b, Data);
770
771 /*              write_vector(gspca_dev, spca500_visual_defaults); */
772                 break;
773         case KodakEZ200:                /* Kodak EZ200 */
774
775                 /* do a full reset */
776                 err = spca500_full_reset(gspca_dev);
777                 if (err < 0)
778                         PDEBUG(D_ERR, "spca500_full_reset failed");
779                 /* enable drop packet */
780                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
781                 reg_w(gspca_dev, 0x00, 0x8880, 0);
782                 err = spca50x_setup_qtable(gspca_dev,
783                                            0x00, 0x8800, 0x8840,
784                                            qtable_kodak_ez200);
785                 if (err < 0)
786                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
787                 spca500_setmode(gspca_dev, xmult, ymult);
788
789                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
790
791                 /* switch to video camera mode */
792                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
793
794                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
795                         PDEBUG(D_ERR, "reg_r_wait() failed");
796
797                 reg_r(gspca_dev, 0x816b, 1);
798                 Data = gspca_dev->usb_buf[0];
799                 reg_w(gspca_dev, 0x00, 0x816b, Data);
800
801 /*              write_vector(gspca_dev, spca500_visual_defaults); */
802                 break;
803
804         case BenqDC1016:
805         case DLinkDSC350:               /* FamilyCam 300 */
806         case AiptekPocketDV:            /* Aiptek PocketDV */
807         case Gsmartmini:                /*Mustek Gsmart Mini */
808         case MustekGsmart300:           /* Mustek Gsmart 300 */
809         case PalmPixDC85:
810         case Optimedia:
811         case ToptroIndus:
812         case AgfaCl20:
813                 spca500_reinit(gspca_dev);
814                 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
815                 /* enable drop packet */
816                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
817
818                 err = spca50x_setup_qtable(gspca_dev,
819                                    0x00, 0x8800, 0x8840, qtable_pocketdv);
820                 if (err < 0)
821                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
822                 reg_w(gspca_dev, 0x00, 0x8880, 2);
823
824                 /* familycam Quicksmart pocketDV stuff */
825                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
826                 /* Set agc transfer: synced inbetween frames */
827                 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
828                 /* Init SDRAM - needed for SDRAM access */
829                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
830
831                 spca500_setmode(gspca_dev, xmult, ymult);
832                 /* switch to video camera mode */
833                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
834
835                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
836
837                 reg_r(gspca_dev, 0x816b, 1);
838                 Data = gspca_dev->usb_buf[0];
839                 reg_w(gspca_dev, 0x00, 0x816b, Data);
840                 break;
841         case LogitechTraveler:
842         case LogitechClickSmart510:
843                 reg_w(gspca_dev, 0x02, 0x00, 0x00);
844                 /* enable drop packet */
845                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
846
847                 err = spca50x_setup_qtable(gspca_dev,
848                                         0x00, 0x8800,
849                                         0x8840, qtable_creative_pccam);
850                 if (err < 0)
851                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
852                 reg_w(gspca_dev, 0x00, 0x8880, 3);
853                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
854                 /* Init SDRAM - needed for SDRAM access */
855                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
856
857                 spca500_setmode(gspca_dev, xmult, ymult);
858
859                 /* switch to video camera mode */
860                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
861                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
862
863                 reg_r(gspca_dev, 0x816b, 1);
864                 Data = gspca_dev->usb_buf[0];
865                 reg_w(gspca_dev, 0x00, 0x816b, Data);
866                 write_vector(gspca_dev, Clicksmart510_defaults);
867                 break;
868         }
869         return 0;
870 }
871
872 static void sd_stopN(struct gspca_dev *gspca_dev)
873 {
874         reg_w(gspca_dev, 0, 0x8003, 0x00);
875
876         /* switch to video camera mode */
877         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
878         reg_r(gspca_dev, 0x8000, 1);
879         PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
880                 gspca_dev->usb_buf[0]);
881 }
882
883 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
884                         struct gspca_frame *frame,      /* target */
885                         __u8 *data,                     /* isoc packet */
886                         int len)                        /* iso packet length */
887 {
888         struct sd *sd = (struct sd *) gspca_dev;
889         int i;
890         __u8 *s, *d;
891         static __u8 ffd9[] = {0xff, 0xd9};
892
893 /* frames are jpeg 4.1.1 without 0xff escape */
894         if (data[0] == 0xff) {
895                 if (data[1] != 0x01) {  /* drop packet */
896 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
897                         return;
898                 }
899                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
900                                         ffd9, 2);
901
902                 /* put the JPEG header in the new frame */
903                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
904
905                 data += SPCA500_OFFSET_DATA;
906                 len -= SPCA500_OFFSET_DATA;
907         } else {
908                 data += 1;
909                 len -= 1;
910         }
911
912         /* add 0x00 after 0xff */
913         for (i = len; --i >= 0; )
914                 if (data[i] == 0xff)
915                         break;
916         if (i < 0) {                    /* no 0xff */
917                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
918                 return;
919         }
920         s = data;
921         d = sd->packet;
922         for (i = 0; i < len; i++) {
923                 *d++ = *s++;
924                 if (s[-1] == 0xff)
925                         *d++ = 0x00;
926         }
927         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
928                         sd->packet, d - sd->packet);
929 }
930
931 static void setbrightness(struct gspca_dev *gspca_dev)
932 {
933         struct sd *sd = (struct sd *) gspca_dev;
934
935         reg_w(gspca_dev, 0x00, 0x8167,
936                         (__u8) (sd->brightness - 128));
937 }
938
939 static void getbrightness(struct gspca_dev *gspca_dev)
940 {
941         struct sd *sd = (struct sd *) gspca_dev;
942         int ret;
943
944         ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
945         if (ret >= 0)
946                 sd->brightness = ret + 128;
947 }
948
949 static void setcontrast(struct gspca_dev *gspca_dev)
950 {
951         struct sd *sd = (struct sd *) gspca_dev;
952
953         reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
954 }
955
956 static void getcontrast(struct gspca_dev *gspca_dev)
957 {
958         struct sd *sd = (struct sd *) gspca_dev;
959         int ret;
960
961         ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
962         if (ret >= 0)
963                 sd->contrast = ret;
964 }
965
966 static void setcolors(struct gspca_dev *gspca_dev)
967 {
968         struct sd *sd = (struct sd *) gspca_dev;
969
970         reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
971 }
972
973 static void getcolors(struct gspca_dev *gspca_dev)
974 {
975         struct sd *sd = (struct sd *) gspca_dev;
976         int ret;
977
978         ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
979         if (ret >= 0)
980                 sd->colors = ret;
981 }
982
983 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
984 {
985         struct sd *sd = (struct sd *) gspca_dev;
986
987         sd->brightness = val;
988         if (gspca_dev->streaming)
989                 setbrightness(gspca_dev);
990         return 0;
991 }
992
993 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
994 {
995         struct sd *sd = (struct sd *) gspca_dev;
996
997         getbrightness(gspca_dev);
998         *val = sd->brightness;
999         return 0;
1000 }
1001
1002 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1003 {
1004         struct sd *sd = (struct sd *) gspca_dev;
1005
1006         sd->contrast = val;
1007         if (gspca_dev->streaming)
1008                 setcontrast(gspca_dev);
1009         return 0;
1010 }
1011
1012 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1013 {
1014         struct sd *sd = (struct sd *) gspca_dev;
1015
1016         getcontrast(gspca_dev);
1017         *val = sd->contrast;
1018         return 0;
1019 }
1020
1021 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1022 {
1023         struct sd *sd = (struct sd *) gspca_dev;
1024
1025         sd->colors = val;
1026         if (gspca_dev->streaming)
1027                 setcolors(gspca_dev);
1028         return 0;
1029 }
1030
1031 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1032 {
1033         struct sd *sd = (struct sd *) gspca_dev;
1034
1035         getcolors(gspca_dev);
1036         *val = sd->colors;
1037         return 0;
1038 }
1039
1040 /* sub-driver description */
1041 static struct sd_desc sd_desc = {
1042         .name = MODULE_NAME,
1043         .ctrls = sd_ctrls,
1044         .nctrls = ARRAY_SIZE(sd_ctrls),
1045         .config = sd_config,
1046         .init = sd_init,
1047         .start = sd_start,
1048         .stopN = sd_stopN,
1049         .pkt_scan = sd_pkt_scan,
1050 };
1051
1052 /* -- module initialisation -- */
1053 static const __devinitdata struct usb_device_id device_table[] = {
1054         {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1055         {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1056         {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1057         {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1058         {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1059         {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1060         {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1061         {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1062         {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1063         {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1064         {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1065         {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1066         {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1067         {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1068         {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1069         {}
1070 };
1071 MODULE_DEVICE_TABLE(usb, device_table);
1072
1073 /* -- device connect -- */
1074 static int sd_probe(struct usb_interface *intf,
1075                         const struct usb_device_id *id)
1076 {
1077         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1078                                 THIS_MODULE);
1079 }
1080
1081 static struct usb_driver sd_driver = {
1082         .name = MODULE_NAME,
1083         .id_table = device_table,
1084         .probe = sd_probe,
1085         .disconnect = gspca_disconnect,
1086 #ifdef CONFIG_PM
1087         .suspend = gspca_suspend,
1088         .resume = gspca_resume,
1089 #endif
1090 };
1091
1092 /* -- module insert / remove -- */
1093 static int __init sd_mod_init(void)
1094 {
1095         int ret;
1096         ret = usb_register(&sd_driver);
1097         if (ret < 0)
1098                 return ret;
1099         PDEBUG(D_PROBE, "registered");
1100         return 0;
1101 }
1102 static void __exit sd_mod_exit(void)
1103 {
1104         usb_deregister(&sd_driver);
1105         PDEBUG(D_PROBE, "deregistered");
1106 }
1107
1108 module_init(sd_mod_init);
1109 module_exit(sd_mod_exit);