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