Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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 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 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         cam->epaddr = 0x01;
633         sd->subtype = id->driver_info;
634         if (sd->subtype != LogitechClickSmart310) {
635                 cam->cam_mode = vga_mode;
636                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
637         } else {
638                 cam->cam_mode = sif_mode;
639                 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
640         }
641         sd->qindex = 5;
642         sd->brightness = BRIGHTNESS_DEF;
643         sd->contrast = CONTRAST_DEF;
644         sd->colors = COLOR_DEF;
645         return 0;
646 }
647
648 /* this function is called at probe and resume time */
649 static int sd_init(struct gspca_dev *gspca_dev)
650 {
651         struct sd *sd = (struct sd *) gspca_dev;
652
653         /* initialisation of spca500 based cameras is deferred */
654         PDEBUG(D_STREAM, "SPCA500 init");
655         if (sd->subtype == LogitechClickSmart310)
656                 spca500_clksmart310_init(gspca_dev);
657 /*      else
658                 spca500_initialise(gspca_dev); */
659         PDEBUG(D_STREAM, "SPCA500 init done");
660         return 0;
661 }
662
663 static int sd_start(struct gspca_dev *gspca_dev)
664 {
665         struct sd *sd = (struct sd *) gspca_dev;
666         int err;
667         __u8 Data;
668         __u8 xmult, ymult;
669
670         if (sd->subtype == LogitechClickSmart310) {
671                 xmult = 0x16;
672                 ymult = 0x12;
673         } else {
674                 xmult = 0x28;
675                 ymult = 0x1e;
676         }
677
678         /* is there a sensor here ? */
679         reg_r(gspca_dev, 0x8a04, 1);
680         PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
681                 gspca_dev->usb_buf[0]);
682         PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
683                 gspca_dev->curr_mode, xmult, ymult);
684
685         /* setup qtable */
686         switch (sd->subtype) {
687         case LogitechClickSmart310:
688                  spca500_setmode(gspca_dev, xmult, ymult);
689
690                 /* enable drop packet */
691                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
692                 reg_w(gspca_dev, 0x00, 0x8880, 3);
693                 err = spca50x_setup_qtable(gspca_dev,
694                                            0x00, 0x8800, 0x8840,
695                                            qtable_creative_pccam);
696                 if (err < 0)
697                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
698                 /* Init SDRAM - needed for SDRAM access */
699                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
700
701                 /* switch to video camera mode */
702                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
703                 msleep(500);
704                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
705                         PDEBUG(D_ERR, "reg_r_wait() failed");
706
707                 reg_r(gspca_dev, 0x816b, 1);
708                 Data = gspca_dev->usb_buf[0];
709                 reg_w(gspca_dev, 0x00, 0x816b, Data);
710
711                 spca500_synch310(gspca_dev);
712
713                 write_vector(gspca_dev, spca500_visual_defaults);
714                 spca500_setmode(gspca_dev, xmult, ymult);
715                 /* enable drop packet */
716                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
717                         PDEBUG(D_ERR, "failed to enable drop packet");
718                 reg_w(gspca_dev, 0x00, 0x8880, 3);
719                 err = spca50x_setup_qtable(gspca_dev,
720                                            0x00, 0x8800, 0x8840,
721                                            qtable_creative_pccam);
722                 if (err < 0)
723                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
724
725                 /* Init SDRAM - needed for SDRAM access */
726                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
727
728                 /* switch to video camera mode */
729                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
730
731                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
732                         PDEBUG(D_ERR, "reg_r_wait() failed");
733
734                 reg_r(gspca_dev, 0x816b, 1);
735                 Data = gspca_dev->usb_buf[0];
736                 reg_w(gspca_dev, 0x00, 0x816b, Data);
737                 break;
738         case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
739         case IntelPocketPCCamera:       /* FIXME: Temporary fix for
740                                          *      Intel Pocket PC Camera
741                                          *      - NWG (Sat 29th March 2003) */
742
743                 /* do a full reset */
744                 err = spca500_full_reset(gspca_dev);
745                 if (err < 0)
746                         PDEBUG(D_ERR, "spca500_full_reset failed");
747
748                 /* enable drop packet */
749                 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
750                 if (err < 0)
751                         PDEBUG(D_ERR, "failed to enable drop packet");
752                 reg_w(gspca_dev, 0x00, 0x8880, 3);
753                 err = spca50x_setup_qtable(gspca_dev,
754                                            0x00, 0x8800, 0x8840,
755                                            qtable_creative_pccam);
756                 if (err < 0)
757                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
758
759                 spca500_setmode(gspca_dev, xmult, ymult);
760                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
761
762                 /* switch to video camera mode */
763                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
764
765                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
766                         PDEBUG(D_ERR, "reg_r_wait() failed");
767
768                 reg_r(gspca_dev, 0x816b, 1);
769                 Data = gspca_dev->usb_buf[0];
770                 reg_w(gspca_dev, 0x00, 0x816b, Data);
771
772 /*              write_vector(gspca_dev, spca500_visual_defaults); */
773                 break;
774         case KodakEZ200:                /* Kodak EZ200 */
775
776                 /* do a full reset */
777                 err = spca500_full_reset(gspca_dev);
778                 if (err < 0)
779                         PDEBUG(D_ERR, "spca500_full_reset failed");
780                 /* enable drop packet */
781                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
782                 reg_w(gspca_dev, 0x00, 0x8880, 0);
783                 err = spca50x_setup_qtable(gspca_dev,
784                                            0x00, 0x8800, 0x8840,
785                                            qtable_kodak_ez200);
786                 if (err < 0)
787                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
788                 spca500_setmode(gspca_dev, xmult, ymult);
789
790                 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
791
792                 /* switch to video camera mode */
793                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
794
795                 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
796                         PDEBUG(D_ERR, "reg_r_wait() failed");
797
798                 reg_r(gspca_dev, 0x816b, 1);
799                 Data = gspca_dev->usb_buf[0];
800                 reg_w(gspca_dev, 0x00, 0x816b, Data);
801
802 /*              write_vector(gspca_dev, spca500_visual_defaults); */
803                 break;
804
805         case BenqDC1016:
806         case DLinkDSC350:               /* FamilyCam 300 */
807         case AiptekPocketDV:            /* Aiptek PocketDV */
808         case Gsmartmini:                /*Mustek Gsmart Mini */
809         case MustekGsmart300:           /* Mustek Gsmart 300 */
810         case PalmPixDC85:
811         case Optimedia:
812         case ToptroIndus:
813         case AgfaCl20:
814                 spca500_reinit(gspca_dev);
815                 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
816                 /* enable drop packet */
817                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
818
819                 err = spca50x_setup_qtable(gspca_dev,
820                                    0x00, 0x8800, 0x8840, qtable_pocketdv);
821                 if (err < 0)
822                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
823                 reg_w(gspca_dev, 0x00, 0x8880, 2);
824
825                 /* familycam Quicksmart pocketDV stuff */
826                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
827                 /* Set agc transfer: synced inbetween frames */
828                 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
829                 /* Init SDRAM - needed for SDRAM access */
830                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
831
832                 spca500_setmode(gspca_dev, xmult, ymult);
833                 /* switch to video camera mode */
834                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
835
836                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
837
838                 reg_r(gspca_dev, 0x816b, 1);
839                 Data = gspca_dev->usb_buf[0];
840                 reg_w(gspca_dev, 0x00, 0x816b, Data);
841                 break;
842         case LogitechTraveler:
843         case LogitechClickSmart510:
844                 reg_w(gspca_dev, 0x02, 0x00, 0x00);
845                 /* enable drop packet */
846                 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
847
848                 err = spca50x_setup_qtable(gspca_dev,
849                                         0x00, 0x8800,
850                                         0x8840, qtable_creative_pccam);
851                 if (err < 0)
852                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
853                 reg_w(gspca_dev, 0x00, 0x8880, 3);
854                 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
855                 /* Init SDRAM - needed for SDRAM access */
856                 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
857
858                 spca500_setmode(gspca_dev, xmult, ymult);
859
860                 /* switch to video camera mode */
861                 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
862                 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
863
864                 reg_r(gspca_dev, 0x816b, 1);
865                 Data = gspca_dev->usb_buf[0];
866                 reg_w(gspca_dev, 0x00, 0x816b, Data);
867                 write_vector(gspca_dev, Clicksmart510_defaults);
868                 break;
869         }
870         return 0;
871 }
872
873 static void sd_stopN(struct gspca_dev *gspca_dev)
874 {
875         reg_w(gspca_dev, 0, 0x8003, 0x00);
876
877         /* switch to video camera mode */
878         reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
879         reg_r(gspca_dev, 0x8000, 1);
880         PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
881                 gspca_dev->usb_buf[0]);
882 }
883
884 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
885                         struct gspca_frame *frame,      /* target */
886                         __u8 *data,                     /* isoc packet */
887                         int len)                        /* iso packet length */
888 {
889         struct sd *sd = (struct sd *) gspca_dev;
890         int i;
891         __u8 *s, *d;
892         static __u8 ffd9[] = {0xff, 0xd9};
893
894 /* frames are jpeg 4.1.1 without 0xff escape */
895         if (data[0] == 0xff) {
896                 if (data[1] != 0x01) {  /* drop packet */
897 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
898                         return;
899                 }
900                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
901                                         ffd9, 2);
902
903                 /* put the JPEG header in the new frame */
904                 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
905
906                 data += SPCA500_OFFSET_DATA;
907                 len -= SPCA500_OFFSET_DATA;
908         } else {
909                 data += 1;
910                 len -= 1;
911         }
912
913         /* add 0x00 after 0xff */
914         for (i = len; --i >= 0; )
915                 if (data[i] == 0xff)
916                         break;
917         if (i < 0) {                    /* no 0xff */
918                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
919                 return;
920         }
921         s = data;
922         d = sd->packet;
923         for (i = 0; i < len; i++) {
924                 *d++ = *s++;
925                 if (s[-1] == 0xff)
926                         *d++ = 0x00;
927         }
928         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
929                         sd->packet, d - sd->packet);
930 }
931
932 static void setbrightness(struct gspca_dev *gspca_dev)
933 {
934         struct sd *sd = (struct sd *) gspca_dev;
935
936         reg_w(gspca_dev, 0x00, 0x8167,
937                         (__u8) (sd->brightness - 128));
938 }
939
940 static void getbrightness(struct gspca_dev *gspca_dev)
941 {
942         struct sd *sd = (struct sd *) gspca_dev;
943         int ret;
944
945         ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
946         if (ret >= 0)
947                 sd->brightness = ret + 128;
948 }
949
950 static void setcontrast(struct gspca_dev *gspca_dev)
951 {
952         struct sd *sd = (struct sd *) gspca_dev;
953
954         reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
955 }
956
957 static void getcontrast(struct gspca_dev *gspca_dev)
958 {
959         struct sd *sd = (struct sd *) gspca_dev;
960         int ret;
961
962         ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
963         if (ret >= 0)
964                 sd->contrast = ret;
965 }
966
967 static void setcolors(struct gspca_dev *gspca_dev)
968 {
969         struct sd *sd = (struct sd *) gspca_dev;
970
971         reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
972 }
973
974 static void getcolors(struct gspca_dev *gspca_dev)
975 {
976         struct sd *sd = (struct sd *) gspca_dev;
977         int ret;
978
979         ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
980         if (ret >= 0)
981                 sd->colors = ret;
982 }
983
984 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
985 {
986         struct sd *sd = (struct sd *) gspca_dev;
987
988         sd->brightness = val;
989         if (gspca_dev->streaming)
990                 setbrightness(gspca_dev);
991         return 0;
992 }
993
994 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
995 {
996         struct sd *sd = (struct sd *) gspca_dev;
997
998         getbrightness(gspca_dev);
999         *val = sd->brightness;
1000         return 0;
1001 }
1002
1003 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1004 {
1005         struct sd *sd = (struct sd *) gspca_dev;
1006
1007         sd->contrast = val;
1008         if (gspca_dev->streaming)
1009                 setcontrast(gspca_dev);
1010         return 0;
1011 }
1012
1013 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1014 {
1015         struct sd *sd = (struct sd *) gspca_dev;
1016
1017         getcontrast(gspca_dev);
1018         *val = sd->contrast;
1019         return 0;
1020 }
1021
1022 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1023 {
1024         struct sd *sd = (struct sd *) gspca_dev;
1025
1026         sd->colors = val;
1027         if (gspca_dev->streaming)
1028                 setcolors(gspca_dev);
1029         return 0;
1030 }
1031
1032 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1033 {
1034         struct sd *sd = (struct sd *) gspca_dev;
1035
1036         getcolors(gspca_dev);
1037         *val = sd->colors;
1038         return 0;
1039 }
1040
1041 /* sub-driver description */
1042 static struct sd_desc sd_desc = {
1043         .name = MODULE_NAME,
1044         .ctrls = sd_ctrls,
1045         .nctrls = ARRAY_SIZE(sd_ctrls),
1046         .config = sd_config,
1047         .init = sd_init,
1048         .start = sd_start,
1049         .stopN = sd_stopN,
1050         .pkt_scan = sd_pkt_scan,
1051 };
1052
1053 /* -- module initialisation -- */
1054 static const __devinitdata struct usb_device_id device_table[] = {
1055         {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1056         {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1057         {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1058         {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1059         {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1060         {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1061         {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1062         {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1063         {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1064         {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1065         {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1066         {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1067         {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1068         {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1069         {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1070         {}
1071 };
1072 MODULE_DEVICE_TABLE(usb, device_table);
1073
1074 /* -- device connect -- */
1075 static int sd_probe(struct usb_interface *intf,
1076                         const struct usb_device_id *id)
1077 {
1078         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1079                                 THIS_MODULE);
1080 }
1081
1082 static struct usb_driver sd_driver = {
1083         .name = MODULE_NAME,
1084         .id_table = device_table,
1085         .probe = sd_probe,
1086         .disconnect = gspca_disconnect,
1087 #ifdef CONFIG_PM
1088         .suspend = gspca_suspend,
1089         .resume = gspca_resume,
1090 #endif
1091 };
1092
1093 /* -- module insert / remove -- */
1094 static int __init sd_mod_init(void)
1095 {
1096         if (usb_register(&sd_driver) < 0)
1097                 return -1;
1098         PDEBUG(D_PROBE, "registered");
1099         return 0;
1100 }
1101 static void __exit sd_mod_exit(void)
1102 {
1103         usb_deregister(&sd_driver);
1104         PDEBUG(D_PROBE, "deregistered");
1105 }
1106
1107 module_init(sd_mod_init);
1108 module_exit(sd_mod_exit);