]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/media/video/gspca/spca561.c
V4L/DVB (10367): gspca - spca561: Optimize the isoc scanning function.
[karo-tx-linux.git] / drivers / media / video / gspca / spca561.c
1 /*
2  * Sunplus spca561 subdriver
3  *
4  * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
5  *
6  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22
23 #define MODULE_NAME "spca561"
24
25 #include "gspca.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA561 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         __u16 exposure;                 /* rev12a only */
36 #define EXPOSURE_MIN 1
37 #define EXPOSURE_DEF 200
38 #define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
39
40         __u8 contrast;                  /* rev72a only */
41 #define CONTRAST_MIN 0x00
42 #define CONTRAST_DEF 0x20
43 #define CONTRAST_MAX 0x3f
44
45         __u8 brightness;                /* rev72a only */
46 #define BRIGHTNESS_MIN 0
47 #define BRIGHTNESS_DEF 0x20
48 #define BRIGHTNESS_MAX 0x3f
49
50         __u8 white;
51 #define WHITE_MIN 1
52 #define WHITE_DEF 0x40
53 #define WHITE_MAX 0x7f
54
55         __u8 autogain;
56 #define AUTOGAIN_MIN 0
57 #define AUTOGAIN_DEF 1
58 #define AUTOGAIN_MAX 1
59
60         __u8 gain;                      /* rev12a only */
61 #define GAIN_MIN 0x0
62 #define GAIN_DEF 0x24
63 #define GAIN_MAX 0x24
64
65 #define EXPO12A_DEF 3
66         __u8 expo12a;           /* expo/gain? for rev 12a */
67
68         __u8 chip_revision;
69 #define Rev012A 0
70 #define Rev072A 1
71
72         signed char ag_cnt;
73 #define AG_CNT_START 13
74 };
75
76 static const struct v4l2_pix_format sif_012a_mode[] = {
77         {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
78                 .bytesperline = 160,
79                 .sizeimage = 160 * 120,
80                 .colorspace = V4L2_COLORSPACE_SRGB,
81                 .priv = 3},
82         {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
83                 .bytesperline = 176,
84                 .sizeimage = 176 * 144,
85                 .colorspace = V4L2_COLORSPACE_SRGB,
86                 .priv = 2},
87         {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
88                 .bytesperline = 320,
89                 .sizeimage = 320 * 240 * 4 / 8,
90                 .colorspace = V4L2_COLORSPACE_SRGB,
91                 .priv = 1},
92         {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
93                 .bytesperline = 352,
94                 .sizeimage = 352 * 288 * 4 / 8,
95                 .colorspace = V4L2_COLORSPACE_SRGB,
96                 .priv = 0},
97 };
98
99 static const struct v4l2_pix_format sif_072a_mode[] = {
100         {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
101                 .bytesperline = 160,
102                 .sizeimage = 160 * 120,
103                 .colorspace = V4L2_COLORSPACE_SRGB,
104                 .priv = 3},
105         {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
106                 .bytesperline = 176,
107                 .sizeimage = 176 * 144,
108                 .colorspace = V4L2_COLORSPACE_SRGB,
109                 .priv = 2},
110         {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
111                 .bytesperline = 320,
112                 .sizeimage = 320 * 240,
113                 .colorspace = V4L2_COLORSPACE_SRGB,
114                 .priv = 1},
115         {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
116                 .bytesperline = 352,
117                 .sizeimage = 352 * 288,
118                 .colorspace = V4L2_COLORSPACE_SRGB,
119                 .priv = 0},
120 };
121
122 /*
123  * Initialization data
124  * I'm not very sure how to split initialization from open data
125  * chunks. For now, we'll consider everything as initialization
126  */
127 /* Frame packet header offsets for the spca561 */
128 #define SPCA561_OFFSET_SNAP 1
129 #define SPCA561_OFFSET_TYPE 2
130 #define SPCA561_OFFSET_COMPRESS 3
131 #define SPCA561_OFFSET_FRAMSEQ   4
132 #define SPCA561_OFFSET_GPIO 5
133 #define SPCA561_OFFSET_USBBUFF 6
134 #define SPCA561_OFFSET_WIN2GRAVE 7
135 #define SPCA561_OFFSET_WIN2RAVE 8
136 #define SPCA561_OFFSET_WIN2BAVE 9
137 #define SPCA561_OFFSET_WIN2GBAVE 10
138 #define SPCA561_OFFSET_WIN1GRAVE 11
139 #define SPCA561_OFFSET_WIN1RAVE 12
140 #define SPCA561_OFFSET_WIN1BAVE 13
141 #define SPCA561_OFFSET_WIN1GBAVE 14
142 #define SPCA561_OFFSET_FREQ 15
143 #define SPCA561_OFFSET_VSYNC 16
144 #define SPCA561_INDEX_I2C_BASE 0x8800
145 #define SPCA561_SNAPBIT 0x20
146 #define SPCA561_SNAPCTRL 0x40
147
148 static const __u16 rev72a_init_data1[][2] = {
149         {0x0000, 0x8114},       /* Software GPIO output data */
150         {0x0001, 0x8114},       /* Software GPIO output data */
151         {0x0000, 0x8112},       /* Some kind of reset */
152         {0x0003, 0x8701},       /* PCLK clock delay adjustment */
153         {0x0001, 0x8703},       /* HSYNC from cmos inverted */
154         {0x0011, 0x8118},       /* Enable and conf sensor */
155         {0x0001, 0x8118},       /* Conf sensor */
156         {0x0092, 0x8804},       /* I know nothing about these */
157         {0x0010, 0x8802},       /* 0x88xx registers, so I won't */
158         {0x000d, 0x8805},       /* sensor default setting */
159         {}
160 };
161 static const __u16 rev72a_init_sensor1[][2] = {
162                                 /* ms-win values */
163         {0x0001, 0x0018},       /* 0x01 <- 0x0d */
164         {0x0002, 0x0065},       /* 0x02 <- 0x18 */
165         {0x0004, 0x0121},       /* 0x04 <- 0x0165 */
166         {0x0005, 0x00aa},       /* 0x05 <- 0x21 */
167         {0x0007, 0x0004},       /* 0x07 <- 0xaa */
168         {0x0020, 0x1502},       /* 0x20 <- 0x1504 */
169         {0x0039, 0x0010},       /* 0x39 <- 0x02 */
170         {0x0035, 0x0049},       /* 0x35 <- 0x10 */
171         {0x0009, 0x100b},       /* 0x09 <- 0x1049 */
172         {0x0028, 0x000f},       /* 0x28 <- 0x0b */
173         {0x003b, 0x003c},       /* 0x3b <- 0x0f */
174         {0x003c, 0x0000},       /* 0x3c <- 0x00 */
175         {}
176 };
177 static const __u16 rev72a_init_data2[][2] = {
178         {0x0018, 0x8601},       /* Pixel/line selection for color separation */
179         {0x0000, 0x8602},       /* Optical black level for user setting */
180         {0x0060, 0x8604},       /* Optical black horizontal offset */
181         {0x0002, 0x8605},       /* Optical black vertical offset */
182         {0x0000, 0x8603},       /* Non-automatic optical black level */
183         {0x0002, 0x865b},       /* Horizontal offset for valid pixels */
184         {0x0000, 0x865f},       /* Vertical valid pixels window (x2) */
185         {0x00b0, 0x865d},       /* Horizontal valid pixels window (x2) */
186         {0x0090, 0x865e},       /* Vertical valid lines window (x2) */
187         {0x00e0, 0x8406},       /* Memory buffer threshold */
188         {0x0000, 0x8660},       /* Compensation memory stuff */
189         {0x0002, 0x8201},       /* Output address for r/w serial EEPROM */
190         {0x0008, 0x8200},       /* Clear valid bit for serial EEPROM */
191         {0x0001, 0x8200},       /* OprMode to be executed by hardware */
192         {0x0007, 0x8201},       /* Output address for r/w serial EEPROM */
193         {0x0008, 0x8200},       /* Clear valid bit for serial EEPROM */
194         {0x0001, 0x8200},       /* OprMode to be executed by hardware */
195         {0x0010, 0x8660},       /* Compensation memory stuff */
196         {0x0018, 0x8660},       /* Compensation memory stuff */
197
198         {0x0004, 0x8611},       /* R offset for white balance */
199         {0x0004, 0x8612},       /* Gr offset for white balance */
200         {0x0007, 0x8613},       /* B offset for white balance */
201         {0x0000, 0x8614},       /* Gb offset for white balance */
202 /* from ms-win */
203         {0x0035, 0x8651},       /* R gain for white balance */
204         {0x0040, 0x8652},       /* Gr gain for white balance */
205         {0x005f, 0x8653},       /* B gain for white balance */
206         {0x0040, 0x8654},       /* Gb gain for white balance */
207         {0x0002, 0x8502},       /* Maximum average bit rate stuff */
208
209         {0x0011, 0x8802},
210         {0x0087, 0x8700},       /* Set master clock (96Mhz????) */
211         {0x0081, 0x8702},       /* Master clock output enable */
212
213         {0x0000, 0x8500},       /* Set image type (352x288 no compression) */
214         /* Originally was 0x0010 (352x288 compression) */
215
216         {0x0002, 0x865b},       /* Horizontal offset for valid pixels */
217         {0x0003, 0x865c},       /* Vertical offset for valid lines */
218         {}
219 };
220 static const __u16 rev72a_init_sensor2[][2] = {
221                                 /* ms-win values */
222         {0x0003, 0x0121},       /* 0x03 <- 0x01 0x21 //289 */
223         {0x0004, 0x0165},       /* 0x04 <- 0x01 0x65 //357 */
224         {0x0005, 0x002f},       /* 0x05 <- 0x2f */
225         {0x0006, 0x0000},       /* 0x06 <- 0 */
226         {0x000a, 0x0002},       /* 0x0a <- 2 */
227         {0x0009, 0x1061},       /* 0x09 <- 0x1061 */
228         {0x0035, 0x0014},       /* 0x35 <- 0x14 */
229         {}
230 };
231 static const __u16 rev72a_init_data3[][2] = {
232         {0x0030, 0x8112},       /* ISO and drop packet enable */
233 /*fixme: should stop here*/
234         {0x0000, 0x8112},       /* Some kind of reset ???? */
235         {0x0009, 0x8118},       /* Enable sensor and set standby */
236         {0x0000, 0x8114},       /* Software GPIO output data */
237         {0x0000, 0x8114},       /* Software GPIO output data */
238         {0x0001, 0x8114},       /* Software GPIO output data */
239         {0x0000, 0x8112},       /* Some kind of reset ??? */
240         {0x0003, 0x8701},
241         {0x0001, 0x8703},
242         {0x0011, 0x8118},
243         {0x0001, 0x8118},
244         /***************/
245         {0x0092, 0x8804},
246         {0x0010, 0x8802},
247         {0x000d, 0x8805},
248         {0x0001, 0x8801},
249         {0x0000, 0x8800},
250         {0x0018, 0x8805},
251         {0x0002, 0x8801},
252         {0x0000, 0x8800},
253         {0x0065, 0x8805},
254         {0x0004, 0x8801},
255         {0x0001, 0x8800},
256         {0x0021, 0x8805},
257         {0x0005, 0x8801},
258         {0x0000, 0x8800},
259         {0x00aa, 0x8805},
260         {0x0007, 0x8801},       /* mode 0xaa */
261         {0x0000, 0x8800},
262         {0x0004, 0x8805},
263         {0x0020, 0x8801},
264         {0x0015, 0x8800},       /* mode 0x0415 */
265         {0x0002, 0x8805},
266         {0x0039, 0x8801},
267         {0x0000, 0x8800},
268         {0x0010, 0x8805},
269         {0x0035, 0x8801},
270         {0x0000, 0x8800},
271         {0x0049, 0x8805},
272         {0x0009, 0x8801},
273         {0x0010, 0x8800},
274         {0x000b, 0x8805},
275         {0x0028, 0x8801},
276         {0x0000, 0x8800},
277         {0x000f, 0x8805},
278         {0x003b, 0x8801},
279         {0x0000, 0x8800},
280         {0x0000, 0x8805},
281         {0x003c, 0x8801},
282         {0x0000, 0x8800},
283         {0x0002, 0x8502},
284         {0x0039, 0x8801},
285         {0x0000, 0x8805},
286         {0x0000, 0x8800},
287
288         {0x0087, 0x8700},       /* overwrite by start */
289         {0x0081, 0x8702},
290         {0x0000, 0x8500},
291 /*      {0x0010, 0x8500},  -- Previous line was this */
292         {0x0002, 0x865b},
293         {0x0003, 0x865c},
294         /***************/
295         {0x0003, 0x8801},       /* 0x121-> 289 */
296         {0x0021, 0x8805},
297         {0x0001, 0x8800},
298         {0x0004, 0x8801},       /* 0x165 -> 357 */
299         {0x0065, 0x8805},
300         {0x0001, 0x8800},
301         {0x0005, 0x8801},       /* 0x2f //blanking control colonne */
302         {0x002f, 0x8805},
303         {0x0000, 0x8800},
304         {0x0006, 0x8801},       /* 0x00 //blanking mode row */
305         {0x0000, 0x8805},
306         {0x0000, 0x8800},
307         {0x000a, 0x8801},       /* 0x01 //0x02 */
308         {0x0001, 0x8805},
309         {0x0000, 0x8800},
310         {0x0009, 0x8801},       /* 0x1061 - setexposure times && pixel clock
311                                  * 0001 0 | 000 0110 0001 */
312         {0x0061, 0x8805},       /* 61 31 */
313         {0x0008, 0x8800},       /* 08 */
314         {0x0035, 0x8801},       /* 0x14 - set gain general */
315         {0x001f, 0x8805},       /* 0x14 */
316         {0x0000, 0x8800},
317         {0x000e, 0x8112},       /* white balance - was 30 */
318         {}
319 };
320
321 /******************** QC Express etch2 stuff ********************/
322 static const __u16 Pb100_1map8300[][2] = {
323         /* reg, value */
324         {0x8320, 0x3304},
325
326         {0x8303, 0x0125},       /* image area */
327         {0x8304, 0x0169},
328         {0x8328, 0x000b},
329         {0x833c, 0x0001},               /*fixme: win:07*/
330
331         {0x832f, 0x1904},               /*fixme: was 0419*/
332         {0x8307, 0x00aa},
333         {0x8301, 0x0003},
334         {0x8302, 0x000e},
335         {}
336 };
337 static const __u16 Pb100_2map8300[][2] = {
338         /* reg, value */
339         {0x8339, 0x0000},
340         {0x8307, 0x00aa},
341         {}
342 };
343
344 static const __u16 spca561_161rev12A_data1[][2] = {
345         {0x29, 0x8118},         /* white balance - was 21 */
346         {0x08, 0x8114},         /* white balance - was 01 */
347         {0x0e, 0x8112},         /* white balance - was 00 */
348         {0x00, 0x8102},         /* white balance - new */
349         {0x92, 0x8804},
350         {0x04, 0x8802},         /* windows uses 08 */
351         {}
352 };
353 static const __u16 spca561_161rev12A_data2[][2] = {
354         {0x21, 0x8118},
355         {0x10, 0x8500},
356         {0x07, 0x8601},
357         {0x07, 0x8602},
358         {0x04, 0x8501},
359         {0x21, 0x8118},
360
361         {0x07, 0x8201},         /* windows uses 02 */
362         {0x08, 0x8200},
363         {0x01, 0x8200},
364
365         {0x00, 0x8114},
366         {0x01, 0x8114},         /* windows uses 00 */
367
368         {0x90, 0x8604},
369         {0x00, 0x8605},
370         {0xb0, 0x8603},
371
372         /* sensor gains */
373         {0x07, 0x8601},         /* white balance - new */
374         {0x07, 0x8602},         /* white balance - new */
375         {0x00, 0x8610},         /* *red */
376         {0x00, 0x8611},         /* 3f   *green */
377         {0x00, 0x8612},         /* green *blue */
378         {0x00, 0x8613},         /* blue *green */
379         {0x43, 0x8614},         /* green *red - white balance - was 0x35 */
380         {0x40, 0x8615},         /* 40   *green - white balance - was 0x35 */
381         {0x71, 0x8616},         /* 7a   *blue - white balance - was 0x35 */
382         {0x40, 0x8617},         /* 40   *green - white balance - was 0x35 */
383
384         {0x0c, 0x8620},         /* 0c */
385         {0xc8, 0x8631},         /* c8 */
386         {0xc8, 0x8634},         /* c8 */
387         {0x23, 0x8635},         /* 23 */
388         {0x1f, 0x8636},         /* 1f */
389         {0xdd, 0x8637},         /* dd */
390         {0xe1, 0x8638},         /* e1 */
391         {0x1d, 0x8639},         /* 1d */
392         {0x21, 0x863a},         /* 21 */
393         {0xe3, 0x863b},         /* e3 */
394         {0xdf, 0x863c},         /* df */
395         {0xf0, 0x8505},
396         {0x32, 0x850a},
397 /*      {0x99, 0x8700},          * - white balance - new (removed) */
398         {}
399 };
400
401 static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
402 {
403         int ret;
404
405         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
406                               0,                /* request */
407                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
408                               value, index, NULL, 0, 500);
409         PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
410         if (ret < 0)
411                 PDEBUG(D_ERR, "reg write: error %d", ret);
412 }
413
414 static void write_vector(struct gspca_dev *gspca_dev,
415                         const __u16 data[][2])
416 {
417         struct usb_device *dev = gspca_dev->dev;
418         int i;
419
420         i = 0;
421         while (data[i][1] != 0) {
422                 reg_w_val(dev, data[i][1], data[i][0]);
423                 i++;
424         }
425 }
426
427 /* read 'len' bytes to gspca_dev->usb_buf */
428 static void reg_r(struct gspca_dev *gspca_dev,
429                   __u16 index, __u16 length)
430 {
431         usb_control_msg(gspca_dev->dev,
432                         usb_rcvctrlpipe(gspca_dev->dev, 0),
433                         0,                      /* request */
434                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
435                         0,                      /* value */
436                         index, gspca_dev->usb_buf, length, 500);
437 }
438
439 /* write 'len' bytes from gspca_dev->usb_buf */
440 static void reg_w_buf(struct gspca_dev *gspca_dev,
441                       __u16 index, __u16 len)
442 {
443         usb_control_msg(gspca_dev->dev,
444                         usb_sndctrlpipe(gspca_dev->dev, 0),
445                         0,                      /* request */
446                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
447                         0,                      /* value */
448                         index, gspca_dev->usb_buf, len, 500);
449 }
450
451 static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
452 {
453         int retry = 60;
454
455         reg_w_val(gspca_dev->dev, 0x8801, reg);
456         reg_w_val(gspca_dev->dev, 0x8805, value);
457         reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
458         do {
459                 reg_r(gspca_dev, 0x8803, 1);
460                 if (!gspca_dev->usb_buf[0])
461                         return;
462         } while (--retry);
463 }
464
465 static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
466 {
467         int retry = 60;
468         __u8 value;
469
470         reg_w_val(gspca_dev->dev, 0x8804, 0x92);
471         reg_w_val(gspca_dev->dev, 0x8801, reg);
472         reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
473         do {
474                 reg_r(gspca_dev, 0x8803, 1);
475                 if (!gspca_dev->usb_buf[0]) {
476                         reg_r(gspca_dev, 0x8800, 1);
477                         value = gspca_dev->usb_buf[0];
478                         reg_r(gspca_dev, 0x8805, 1);
479                         return ((int) value << 8) | gspca_dev->usb_buf[0];
480                 }
481         } while (--retry);
482         return -1;
483 }
484
485 static void sensor_mapwrite(struct gspca_dev *gspca_dev,
486                             const __u16 (*sensormap)[2])
487 {
488         while ((*sensormap)[0]) {
489                 gspca_dev->usb_buf[0] = (*sensormap)[1];
490                 gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
491                 reg_w_buf(gspca_dev, (*sensormap)[0], 2);
492                 sensormap++;
493         }
494 }
495
496 static void write_sensor_72a(struct gspca_dev *gspca_dev,
497                             const __u16 (*sensor)[2])
498 {
499         while ((*sensor)[0]) {
500                 i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
501                 sensor++;
502         }
503 }
504
505 static void init_161rev12A(struct gspca_dev *gspca_dev)
506 {
507         write_vector(gspca_dev, spca561_161rev12A_data1);
508         sensor_mapwrite(gspca_dev, Pb100_1map8300);
509 /*fixme: should be in sd_start*/
510         write_vector(gspca_dev, spca561_161rev12A_data2);
511         sensor_mapwrite(gspca_dev, Pb100_2map8300);
512 }
513
514 /* this function is called at probe time */
515 static int sd_config(struct gspca_dev *gspca_dev,
516                      const struct usb_device_id *id)
517 {
518         struct sd *sd = (struct sd *) gspca_dev;
519         struct cam *cam;
520         __u16 vendor, product;
521         __u8 data1, data2;
522
523         /* Read frm global register the USB product and vendor IDs, just to
524          * prove that we can communicate with the device.  This works, which
525          * confirms at we are communicating properly and that the device
526          * is a 561. */
527         reg_r(gspca_dev, 0x8104, 1);
528         data1 = gspca_dev->usb_buf[0];
529         reg_r(gspca_dev, 0x8105, 1);
530         data2 = gspca_dev->usb_buf[0];
531         vendor = (data2 << 8) | data1;
532         reg_r(gspca_dev, 0x8106, 1);
533         data1 = gspca_dev->usb_buf[0];
534         reg_r(gspca_dev, 0x8107, 1);
535         data2 = gspca_dev->usb_buf[0];
536         product = (data2 << 8) | data1;
537         if (vendor != id->idVendor || product != id->idProduct) {
538                 PDEBUG(D_PROBE, "Bad vendor / product from device");
539                 return -EINVAL;
540         }
541
542         cam = &gspca_dev->cam;
543         gspca_dev->nbalt = 7 + 1;       /* choose alternate 7 first */
544
545         sd->chip_revision = id->driver_info;
546         if (sd->chip_revision == Rev012A) {
547                 cam->cam_mode = sif_012a_mode;
548                 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
549         } else {
550                 cam->cam_mode = sif_072a_mode;
551                 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
552         }
553         sd->brightness = BRIGHTNESS_DEF;
554         sd->contrast = CONTRAST_DEF;
555         sd->white = WHITE_DEF;
556         sd->exposure = EXPOSURE_DEF;
557         sd->autogain = AUTOGAIN_DEF;
558         sd->gain = GAIN_DEF;
559         sd->expo12a = EXPO12A_DEF;
560         return 0;
561 }
562
563 /* this function is called at probe and resume time */
564 static int sd_init_12a(struct gspca_dev *gspca_dev)
565 {
566         PDEBUG(D_STREAM, "Chip revision: 012a");
567         init_161rev12A(gspca_dev);
568         return 0;
569 }
570 static int sd_init_72a(struct gspca_dev *gspca_dev)
571 {
572         PDEBUG(D_STREAM, "Chip revision: 072a");
573         write_vector(gspca_dev, rev72a_init_data1);
574         write_sensor_72a(gspca_dev, rev72a_init_sensor1);
575         write_vector(gspca_dev, rev72a_init_data2);
576         write_sensor_72a(gspca_dev, rev72a_init_sensor2);
577         write_vector(gspca_dev, rev72a_init_data3);
578         return 0;
579 }
580
581 /* rev 72a only */
582 static void setbrightness(struct gspca_dev *gspca_dev)
583 {
584         struct sd *sd = (struct sd *) gspca_dev;
585         struct usb_device *dev = gspca_dev->dev;
586         __u8 value;
587
588         value = sd->brightness;
589
590         /* offsets for white balance */
591         reg_w_val(dev, 0x8611, value);          /* R */
592         reg_w_val(dev, 0x8612, value);          /* Gr */
593         reg_w_val(dev, 0x8613, value);          /* B */
594         reg_w_val(dev, 0x8614, value);          /* Gb */
595 }
596
597 static void setwhite(struct gspca_dev *gspca_dev)
598 {
599         struct sd *sd = (struct sd *) gspca_dev;
600         __u16 white;
601         __u8 blue, red;
602         __u16 reg;
603
604         /* try to emulate MS-win as possible */
605         white = sd->white;
606         red = 0x20 + white * 3 / 8;
607         blue = 0x90 - white * 5 / 8;
608         if (sd->chip_revision == Rev012A) {
609                 reg = 0x8614;
610         } else {
611                 reg = 0x8651;
612                 red += sd->contrast - 0x20;
613                 blue += sd->contrast - 0x20;
614         }
615         reg_w_val(gspca_dev->dev, reg, red);
616         reg_w_val(gspca_dev->dev, reg + 2, blue);
617 }
618
619 static void setcontrast(struct gspca_dev *gspca_dev)
620 {
621         struct sd *sd = (struct sd *) gspca_dev;
622         struct usb_device *dev = gspca_dev->dev;
623         __u8 value;
624
625         if (sd->chip_revision != Rev072A)
626                 return;
627         value = sd->contrast + 0x20;
628
629         /* gains for white balance */
630         setwhite(gspca_dev);
631 /*      reg_w_val(dev, 0x8651, value);           * R - done by setwhite */
632         reg_w_val(dev, 0x8652, value);          /* Gr */
633 /*      reg_w_val(dev, 0x8653, value);           * B - done by setwhite */
634         reg_w_val(dev, 0x8654, value);          /* Gb */
635 }
636
637 /* rev 12a only */
638 static void setexposure(struct gspca_dev *gspca_dev)
639 {
640         struct sd *sd = (struct sd *) gspca_dev;
641         int expo;
642         int clock_divider;
643
644         /* Register 0x8309 controls exposure for the spca561,
645            the basic exposure setting goes from 1-2047, where 1 is completely
646            dark and 2047 is very bright. It not only influences exposure but
647            also the framerate (to allow for longer exposure) from 1 - 300 it
648            only raises the exposure time then from 300 - 600 it halves the
649            framerate to be able to further raise the exposure time and for every
650            300 more it halves the framerate again. This allows for a maximum
651            exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
652            Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
653            configure a divider for the base framerate which us used at the
654            exposure setting of 1-300. These bits configure the base framerate
655            according to the following formula: fps = 60 / (value + 2) */
656         if (sd->exposure < 2048) {
657                 expo = sd->exposure;
658                 clock_divider = 0;
659         } else {
660                 /* Add 900 to make the 0 setting of the second part of the
661                    exposure equal to the 2047 setting of the first part. */
662                 expo = (sd->exposure - 2048) + 900;
663                 clock_divider = 3;
664         }
665         expo |= clock_divider << 11;
666         gspca_dev->usb_buf[0] = expo;
667         gspca_dev->usb_buf[1] = expo >> 8;
668         reg_w_buf(gspca_dev, 0x8309, 2);
669 }
670
671 /* rev 12a only */
672 static void setgain(struct gspca_dev *gspca_dev)
673 {
674         struct sd *sd = (struct sd *) gspca_dev;
675
676         gspca_dev->usb_buf[0] = sd->gain;
677         gspca_dev->usb_buf[1] = 0;
678         reg_w_buf(gspca_dev, 0x8335, 2);
679 }
680
681 static void setautogain(struct gspca_dev *gspca_dev)
682 {
683         struct sd *sd = (struct sd *) gspca_dev;
684
685         if (sd->autogain)
686                 sd->ag_cnt = AG_CNT_START;
687         else
688                 sd->ag_cnt = -1;
689 }
690
691 static int sd_start_12a(struct gspca_dev *gspca_dev)
692 {
693         struct usb_device *dev = gspca_dev->dev;
694         int mode;
695         static const __u8 Reg8391[8] =
696                 {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
697
698         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
699         if (mode <= 1) {
700                 /* Use compression on 320x240 and above */
701                 reg_w_val(dev, 0x8500, 0x10 | mode);
702         } else {
703                 /* I couldn't get the compression to work below 320x240
704                  * Fortunately at these resolutions the bandwidth
705                  * is sufficient to push raw frames at ~20fps */
706                 reg_w_val(dev, 0x8500, mode);
707         }               /* -- qq@kuku.eu.org */
708
709         gspca_dev->usb_buf[0] = 0xaa;
710         gspca_dev->usb_buf[1] = 0x00;
711         reg_w_buf(gspca_dev, 0x8307, 2);
712         /* clock - lower 0x8X values lead to fps > 30 */
713         reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
714                                         /* 0x8f 0x85 0x27 clock */
715         reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
716         reg_w_val(gspca_dev->dev, 0x850b, 0x03);
717         memcpy(gspca_dev->usb_buf, Reg8391, 8);
718         reg_w_buf(gspca_dev, 0x8391, 8);
719         reg_w_buf(gspca_dev, 0x8390, 8);
720         setwhite(gspca_dev);
721         setautogain(gspca_dev);
722 /*      setgain(gspca_dev);             */
723         setexposure(gspca_dev);
724         return 0;
725 }
726 static int sd_start_72a(struct gspca_dev *gspca_dev)
727 {
728         struct usb_device *dev = gspca_dev->dev;
729         int Clck;
730         int mode;
731
732         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
733         switch (mode) {
734         default:
735 /*      case 0:
736         case 1: */
737                 Clck = 0x25;
738                 break;
739         case 2:
740                 Clck = 0x22;
741                 break;
742         case 3:
743                 Clck = 0x21;
744                 break;
745         }
746         reg_w_val(dev, 0x8500, mode);   /* mode */
747         reg_w_val(dev, 0x8700, Clck);   /* 0x27 clock */
748         reg_w_val(dev, 0x8112, 0x10 | 0x20);
749         setcontrast(gspca_dev);
750 /*      setbrightness(gspca_dev);        * fixme: bad values */
751         setwhite(gspca_dev);
752         setautogain(gspca_dev);
753         return 0;
754 }
755
756 static void sd_stopN(struct gspca_dev *gspca_dev)
757 {
758         struct sd *sd = (struct sd *) gspca_dev;
759
760         if (sd->chip_revision == Rev012A) {
761                 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
762         } else {
763                 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
764 /*              reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
765         }
766 }
767
768 /* called on streamoff with alt 0 and on disconnect */
769 static void sd_stop0(struct gspca_dev *gspca_dev)
770 {
771         struct sd *sd = (struct sd *) gspca_dev;
772
773         if (!gspca_dev->present)
774                 return;
775         if (sd->chip_revision == Rev012A) {
776                 reg_w_val(gspca_dev->dev, 0x8118, 0x29);
777                 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
778         }
779 /*      reg_w_val(gspca_dev->dev, 0x8114, 0); */
780 }
781
782 static void do_autogain(struct gspca_dev *gspca_dev)
783 {
784         struct sd *sd = (struct sd *) gspca_dev;
785         int expotimes;
786         int pixelclk;
787         int gainG;
788         __u8 R, Gr, Gb, B;
789         int y;
790         __u8 luma_mean = 110;
791         __u8 luma_delta = 20;
792         __u8 spring = 4;
793
794         if (sd->ag_cnt < 0)
795                 return;
796         if (--sd->ag_cnt >= 0)
797                 return;
798         sd->ag_cnt = AG_CNT_START;
799
800         switch (sd->chip_revision) {
801         case Rev072A:
802                 reg_r(gspca_dev, 0x8621, 1);
803                 Gr = gspca_dev->usb_buf[0];
804                 reg_r(gspca_dev, 0x8622, 1);
805                 R = gspca_dev->usb_buf[0];
806                 reg_r(gspca_dev, 0x8623, 1);
807                 B = gspca_dev->usb_buf[0];
808                 reg_r(gspca_dev, 0x8624, 1);
809                 Gb = gspca_dev->usb_buf[0];
810                 y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
811                 /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
812                 /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
813                 /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
814
815                 if (y < luma_mean - luma_delta ||
816                     y > luma_mean + luma_delta) {
817                         expotimes = i2c_read(gspca_dev, 0x09, 0x10);
818                         pixelclk = 0x0800;
819                         expotimes = expotimes & 0x07ff;
820                         /* PDEBUG(D_PACK,
821                                 "Exposition Times 0x%03X Clock 0x%04X ",
822                                 expotimes,pixelclk); */
823                         gainG = i2c_read(gspca_dev, 0x35, 0x10);
824                         /* PDEBUG(D_PACK,
825                                 "reading Gain register %d", gainG); */
826
827                         expotimes += (luma_mean - y) >> spring;
828                         gainG += (luma_mean - y) / 50;
829                         /* PDEBUG(D_PACK,
830                                 "compute expotimes %d gain %d",
831                                 expotimes,gainG); */
832
833                         if (gainG > 0x3f)
834                                 gainG = 0x3f;
835                         else if (gainG < 3)
836                                 gainG = 3;
837                         i2c_write(gspca_dev, gainG, 0x35);
838
839                         if (expotimes > 0x0256)
840                                 expotimes = 0x0256;
841                         else if (expotimes < 3)
842                                 expotimes = 3;
843                         i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
844                 }
845                 break;
846         case Rev012A:
847                 reg_r(gspca_dev, 0x8330, 2);
848                 if (gspca_dev->usb_buf[1] > 0x08) {
849                         gspca_dev->usb_buf[0] = ++sd->expo12a;
850                         gspca_dev->usb_buf[1] = 0;
851                         reg_w_buf(gspca_dev, 0x8339, 2);
852                 } else if (gspca_dev->usb_buf[1] < 0x02) {
853                         gspca_dev->usb_buf[0] = --sd->expo12a;
854                         gspca_dev->usb_buf[1] = 0;
855                         reg_w_buf(gspca_dev, 0x8339, 2);
856                 }
857                 break;
858         }
859 }
860
861 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
862                         struct gspca_frame *frame, /* target */
863                         __u8 *data,             /* isoc packet */
864                         int len)                /* iso packet length */
865 {
866         struct sd *sd = (struct sd *) gspca_dev;
867
868         len--;
869         switch (*data++) {                      /* sequence number */
870         case 0:                                 /* start of frame */
871                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
872                                         data, 0);
873                 if (data[1] & 0x10) {
874                         /* compressed bayer */
875                         gspca_frame_add(gspca_dev, FIRST_PACKET,
876                                         frame, data, len);
877                 } else {
878                         /* raw bayer (with a header, which we skip) */
879                         if (sd->chip_revision == Rev012A) {
880                                 data += 20;
881                                 len -= 20;
882                         } else {
883                                 data += 16;
884                                 len -= 16;
885                         }
886                         gspca_frame_add(gspca_dev, FIRST_PACKET,
887                                                 frame, data, len);
888                 }
889                 return;
890         case 0xff:                      /* drop (empty mpackets) */
891                 return;
892         }
893         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
894 }
895
896 /* rev 72a only */
897 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
898 {
899         struct sd *sd = (struct sd *) gspca_dev;
900
901         sd->brightness = val;
902         if (gspca_dev->streaming)
903                 setbrightness(gspca_dev);
904         return 0;
905 }
906
907 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
908 {
909         struct sd *sd = (struct sd *) gspca_dev;
910
911         *val = sd->brightness;
912         return 0;
913 }
914
915 /* rev 72a only */
916 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
917 {
918         struct sd *sd = (struct sd *) gspca_dev;
919
920         sd->contrast = val;
921         if (gspca_dev->streaming)
922                 setcontrast(gspca_dev);
923         return 0;
924 }
925
926 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
927 {
928         struct sd *sd = (struct sd *) gspca_dev;
929
930         *val = sd->contrast;
931         return 0;
932 }
933
934 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
935 {
936         struct sd *sd = (struct sd *) gspca_dev;
937
938         sd->autogain = val;
939         if (gspca_dev->streaming)
940                 setautogain(gspca_dev);
941         return 0;
942 }
943
944 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
945 {
946         struct sd *sd = (struct sd *) gspca_dev;
947
948         *val = sd->autogain;
949         return 0;
950 }
951
952 static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
953 {
954         struct sd *sd = (struct sd *) gspca_dev;
955
956         sd->white = val;
957         if (gspca_dev->streaming)
958                 setwhite(gspca_dev);
959         return 0;
960 }
961
962 static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
963 {
964         struct sd *sd = (struct sd *) gspca_dev;
965
966         *val = sd->white;
967         return 0;
968 }
969
970 /* rev12a only */
971 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
972 {
973         struct sd *sd = (struct sd *) gspca_dev;
974
975         sd->exposure = val;
976         if (gspca_dev->streaming)
977                 setexposure(gspca_dev);
978         return 0;
979 }
980
981 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
982 {
983         struct sd *sd = (struct sd *) gspca_dev;
984
985         *val = sd->exposure;
986         return 0;
987 }
988
989 /* rev12a only */
990 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
991 {
992         struct sd *sd = (struct sd *) gspca_dev;
993
994         sd->gain = val;
995         if (gspca_dev->streaming)
996                 setgain(gspca_dev);
997         return 0;
998 }
999
1000 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1001 {
1002         struct sd *sd = (struct sd *) gspca_dev;
1003
1004         *val = sd->gain;
1005         return 0;
1006 }
1007
1008 /* control tables */
1009 static struct ctrl sd_ctrls_12a[] = {
1010         {
1011             {
1012                 .id = V4L2_CID_DO_WHITE_BALANCE,
1013                 .type = V4L2_CTRL_TYPE_INTEGER,
1014                 .name = "White Balance",
1015                 .minimum = WHITE_MIN,
1016                 .maximum = WHITE_MAX,
1017                 .step = 1,
1018                 .default_value = WHITE_DEF,
1019             },
1020             .set = sd_setwhite,
1021             .get = sd_getwhite,
1022         },
1023         {
1024             {
1025                 .id = V4L2_CID_EXPOSURE,
1026                 .type = V4L2_CTRL_TYPE_INTEGER,
1027                 .name = "Exposure",
1028                 .minimum = EXPOSURE_MIN,
1029                 .maximum = EXPOSURE_MAX,
1030                 .step = 1,
1031                 .default_value = EXPOSURE_DEF,
1032             },
1033             .set = sd_setexposure,
1034             .get = sd_getexposure,
1035         },
1036         {
1037             {
1038                 .id = V4L2_CID_AUTOGAIN,
1039                 .type = V4L2_CTRL_TYPE_BOOLEAN,
1040                 .name = "Auto Gain",
1041                 .minimum = AUTOGAIN_MIN,
1042                 .maximum = AUTOGAIN_MAX,
1043                 .step = 1,
1044                 .default_value = AUTOGAIN_DEF,
1045             },
1046             .set = sd_setautogain,
1047             .get = sd_getautogain,
1048         },
1049         {
1050             {
1051                 .id = V4L2_CID_GAIN,
1052                 .type = V4L2_CTRL_TYPE_INTEGER,
1053                 .name = "Gain",
1054                 .minimum = GAIN_MIN,
1055                 .maximum = GAIN_MAX,
1056                 .step = 1,
1057                 .default_value = GAIN_DEF,
1058             },
1059             .set = sd_setgain,
1060             .get = sd_getgain,
1061         },
1062 };
1063
1064 static struct ctrl sd_ctrls_72a[] = {
1065         {
1066             {
1067                 .id = V4L2_CID_DO_WHITE_BALANCE,
1068                 .type = V4L2_CTRL_TYPE_INTEGER,
1069                 .name = "White Balance",
1070                 .minimum = WHITE_MIN,
1071                 .maximum = WHITE_MAX,
1072                 .step = 1,
1073                 .default_value = WHITE_DEF,
1074             },
1075             .set = sd_setwhite,
1076             .get = sd_getwhite,
1077         },
1078         {
1079            {
1080                 .id = V4L2_CID_BRIGHTNESS,
1081                 .type = V4L2_CTRL_TYPE_INTEGER,
1082                 .name = "Brightness",
1083                 .minimum = BRIGHTNESS_MIN,
1084                 .maximum = BRIGHTNESS_MAX,
1085                 .step = 1,
1086                 .default_value = BRIGHTNESS_DEF,
1087             },
1088             .set = sd_setbrightness,
1089             .get = sd_getbrightness,
1090         },
1091         {
1092             {
1093                 .id = V4L2_CID_CONTRAST,
1094                 .type = V4L2_CTRL_TYPE_INTEGER,
1095                 .name = "Contrast",
1096                 .minimum = CONTRAST_MIN,
1097                 .maximum = CONTRAST_MAX,
1098                 .step = 1,
1099                 .default_value = CONTRAST_DEF,
1100             },
1101             .set = sd_setcontrast,
1102             .get = sd_getcontrast,
1103         },
1104         {
1105             {
1106                 .id = V4L2_CID_AUTOGAIN,
1107                 .type = V4L2_CTRL_TYPE_BOOLEAN,
1108                 .name = "Auto Gain",
1109                 .minimum = AUTOGAIN_MIN,
1110                 .maximum = AUTOGAIN_MAX,
1111                 .step = 1,
1112                 .default_value = AUTOGAIN_DEF,
1113             },
1114             .set = sd_setautogain,
1115             .get = sd_getautogain,
1116         },
1117 };
1118
1119 /* sub-driver description */
1120 static const struct sd_desc sd_desc_12a = {
1121         .name = MODULE_NAME,
1122         .ctrls = sd_ctrls_12a,
1123         .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1124         .config = sd_config,
1125         .init = sd_init_12a,
1126         .start = sd_start_12a,
1127         .stopN = sd_stopN,
1128         .stop0 = sd_stop0,
1129         .pkt_scan = sd_pkt_scan,
1130 /*      .dq_callback = do_autogain,      * fixme */
1131 };
1132 static const struct sd_desc sd_desc_72a = {
1133         .name = MODULE_NAME,
1134         .ctrls = sd_ctrls_72a,
1135         .nctrls = ARRAY_SIZE(sd_ctrls_72a),
1136         .config = sd_config,
1137         .init = sd_init_72a,
1138         .start = sd_start_72a,
1139         .stopN = sd_stopN,
1140         .stop0 = sd_stop0,
1141         .pkt_scan = sd_pkt_scan,
1142         .dq_callback = do_autogain,
1143 };
1144 static const struct sd_desc *sd_desc[2] = {
1145         &sd_desc_12a,
1146         &sd_desc_72a
1147 };
1148
1149 /* -- module initialisation -- */
1150 static const __devinitdata struct usb_device_id device_table[] = {
1151         {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1152         {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1153         {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1154         {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1155         {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1156         {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1157         {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1158         {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1159         {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1160         {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1161         {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1162         {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1163         {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1164         {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1165         {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1166         {}
1167 };
1168
1169 MODULE_DEVICE_TABLE(usb, device_table);
1170
1171 /* -- device connect -- */
1172 static int sd_probe(struct usb_interface *intf,
1173                     const struct usb_device_id *id)
1174 {
1175         return gspca_dev_probe(intf, id,
1176                                 sd_desc[id->driver_info],
1177                                 sizeof(struct sd),
1178                                THIS_MODULE);
1179 }
1180
1181 static struct usb_driver sd_driver = {
1182         .name = MODULE_NAME,
1183         .id_table = device_table,
1184         .probe = sd_probe,
1185         .disconnect = gspca_disconnect,
1186 #ifdef CONFIG_PM
1187         .suspend = gspca_suspend,
1188         .resume = gspca_resume,
1189 #endif
1190 };
1191
1192 /* -- module insert / remove -- */
1193 static int __init sd_mod_init(void)
1194 {
1195         int ret;
1196         ret = usb_register(&sd_driver);
1197         if (ret < 0)
1198                 return ret;
1199         PDEBUG(D_PROBE, "registered");
1200         return 0;
1201 }
1202 static void __exit sd_mod_exit(void)
1203 {
1204         usb_deregister(&sd_driver);
1205         PDEBUG(D_PROBE, "deregistered");
1206 }
1207
1208 module_init(sd_mod_init);
1209 module_exit(sd_mod_exit);