]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/media/video/gspca/pac7311.c
V4L/DVB (13299): gspca - pac7311: Extract pac_start_frame.
[linux-beck.git] / drivers / media / video / gspca / pac7311.c
1 /*
2  *              Pixart PAC7311 library
3  *              Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 /* Some documentation about various registers as determined by trial and error.
23    When the register addresses differ between the 7202 and the 7311 the 2
24    different addresses are written as 7302addr/7311addr, when one of the 2
25    addresses is a - sign that register description is not valid for the
26    matching IC.
27
28    Register page 1:
29
30    Address      Description
31    -/0x08       Unknown compressor related, must always be 8 except when not
32                 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33    -/0x1b       Auto white balance related, bit 0 is AWB enable (inverted)
34                 bits 345 seem to toggle per color gains on/off (inverted)
35    0x78         Global control, bit 6 controls the LED (inverted)
36    -/0x80       JPEG compression ratio ? Best not touched
37
38    Register page 3/4:
39
40    Address      Description
41    0x02         Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42                 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43    -/0x0f       Master gain 1-245, low value = high gain
44    0x10/-       Master gain 0-31
45    -/0x10       Another gain 0-15, limited influence (1-2x gain I guess)
46    0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47    -/0x27       Seems to toggle various gains on / off, Setting bit 7 seems to
48                 completely disable the analog amplification block. Set to 0x68
49                 for max gain, 0x14 for minimal gain.
50 */
51
52 #define MODULE_NAME "pac7311"
53
54 #include "gspca.h"
55
56 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
57 MODULE_DESCRIPTION("Pixart PAC7311");
58 MODULE_LICENSE("GPL");
59
60 /* specific webcam descriptor */
61 struct sd {
62         struct gspca_dev gspca_dev;             /* !! must be the first item */
63
64         unsigned char brightness;
65         unsigned char contrast;
66         unsigned char colors;
67         unsigned char gain;
68         unsigned char exposure;
69         unsigned char autogain;
70         __u8 hflip;
71         __u8 vflip;
72
73         __u8 sensor;
74 #define SENSOR_PAC7302 0
75 #define SENSOR_PAC7311 1
76
77         u8 sof_read;
78         u8 autogain_ignore_frames;
79
80         atomic_t avg_lum;
81 };
82
83 /* V4L2 controls supported by the driver */
84 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
97 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
98 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
100
101 static struct ctrl sd_ctrls[] = {
102 /* This control is pac7302 only */
103 #define BRIGHTNESS_IDX 0
104         {
105             {
106                 .id      = V4L2_CID_BRIGHTNESS,
107                 .type    = V4L2_CTRL_TYPE_INTEGER,
108                 .name    = "Brightness",
109                 .minimum = 0,
110 #define BRIGHTNESS_MAX 0x20
111                 .maximum = BRIGHTNESS_MAX,
112                 .step    = 1,
113 #define BRIGHTNESS_DEF 0x10
114                 .default_value = BRIGHTNESS_DEF,
115             },
116             .set = sd_setbrightness,
117             .get = sd_getbrightness,
118         },
119 /* This control is for both the 7302 and the 7311 */
120         {
121             {
122                 .id      = V4L2_CID_CONTRAST,
123                 .type    = V4L2_CTRL_TYPE_INTEGER,
124                 .name    = "Contrast",
125                 .minimum = 0,
126 #define CONTRAST_MAX 255
127                 .maximum = CONTRAST_MAX,
128                 .step    = 1,
129 #define CONTRAST_DEF 127
130                 .default_value = CONTRAST_DEF,
131             },
132             .set = sd_setcontrast,
133             .get = sd_getcontrast,
134         },
135 /* This control is pac7302 only */
136 #define SATURATION_IDX 2
137         {
138             {
139                 .id      = V4L2_CID_SATURATION,
140                 .type    = V4L2_CTRL_TYPE_INTEGER,
141                 .name    = "Saturation",
142                 .minimum = 0,
143 #define COLOR_MAX 255
144                 .maximum = COLOR_MAX,
145                 .step    = 1,
146 #define COLOR_DEF 127
147                 .default_value = COLOR_DEF,
148             },
149             .set = sd_setcolors,
150             .get = sd_getcolors,
151         },
152 /* All controls below are for both the 7302 and the 7311 */
153         {
154             {
155                 .id      = V4L2_CID_GAIN,
156                 .type    = V4L2_CTRL_TYPE_INTEGER,
157                 .name    = "Gain",
158                 .minimum = 0,
159 #define GAIN_MAX 255
160                 .maximum = GAIN_MAX,
161                 .step    = 1,
162 #define GAIN_DEF 127
163 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
164                 .default_value = GAIN_DEF,
165             },
166             .set = sd_setgain,
167             .get = sd_getgain,
168         },
169         {
170             {
171                 .id      = V4L2_CID_EXPOSURE,
172                 .type    = V4L2_CTRL_TYPE_INTEGER,
173                 .name    = "Exposure",
174                 .minimum = 0,
175 #define EXPOSURE_MAX 255
176                 .maximum = EXPOSURE_MAX,
177                 .step    = 1,
178 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
179 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
180                 .default_value = EXPOSURE_DEF,
181             },
182             .set = sd_setexposure,
183             .get = sd_getexposure,
184         },
185         {
186             {
187                 .id      = V4L2_CID_AUTOGAIN,
188                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
189                 .name    = "Auto Gain",
190                 .minimum = 0,
191                 .maximum = 1,
192                 .step    = 1,
193 #define AUTOGAIN_DEF 1
194                 .default_value = AUTOGAIN_DEF,
195             },
196             .set = sd_setautogain,
197             .get = sd_getautogain,
198         },
199         {
200             {
201                 .id      = V4L2_CID_HFLIP,
202                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
203                 .name    = "Mirror",
204                 .minimum = 0,
205                 .maximum = 1,
206                 .step    = 1,
207 #define HFLIP_DEF 0
208                 .default_value = HFLIP_DEF,
209             },
210             .set = sd_sethflip,
211             .get = sd_gethflip,
212         },
213         {
214             {
215                 .id      = V4L2_CID_VFLIP,
216                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
217                 .name    = "Vflip",
218                 .minimum = 0,
219                 .maximum = 1,
220                 .step    = 1,
221 #define VFLIP_DEF 0
222                 .default_value = VFLIP_DEF,
223             },
224             .set = sd_setvflip,
225             .get = sd_getvflip,
226         },
227 };
228
229 static const struct v4l2_pix_format vga_mode[] = {
230         {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
231                 .bytesperline = 160,
232                 .sizeimage = 160 * 120 * 3 / 8 + 590,
233                 .colorspace = V4L2_COLORSPACE_JPEG,
234                 .priv = 2},
235         {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
236                 .bytesperline = 320,
237                 .sizeimage = 320 * 240 * 3 / 8 + 590,
238                 .colorspace = V4L2_COLORSPACE_JPEG,
239                 .priv = 1},
240         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
241                 .bytesperline = 640,
242                 .sizeimage = 640 * 480 * 3 / 8 + 590,
243                 .colorspace = V4L2_COLORSPACE_JPEG,
244                 .priv = 0},
245 };
246
247 #define LOAD_PAGE3              255
248 #define LOAD_PAGE4              254
249 #define END_OF_SEQUENCE         0
250
251 /* pac 7302 */
252 static const __u8 init_7302[] = {
253 /*      index,value */
254         0xff, 0x01,             /* page 1 */
255         0x78, 0x00,             /* deactivate */
256         0xff, 0x01,
257         0x78, 0x40,             /* led off */
258 };
259 static const __u8 start_7302[] = {
260 /*      index, len, [value]* */
261         0xff, 1,        0x00,           /* page 0 */
262         0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
263                         0x00, 0x00, 0x00, 0x00,
264         0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
265                         0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
266                         0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
267         0x26, 2,        0xaa, 0xaa,
268         0x2e, 1,        0x31,
269         0x38, 1,        0x01,
270         0x3a, 3,        0x14, 0xff, 0x5a,
271         0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
272                         0x00, 0x54, 0x11,
273         0x55, 1,        0x00,
274         0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
275         0x6b, 1,        0x00,
276         0x6e, 3,        0x08, 0x06, 0x00,
277         0x72, 3,        0x00, 0xff, 0x00,
278         0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
279                         0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
280                         0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
281         0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
282                         0xd2, 0xeb,
283         0xaf, 1,        0x02,
284         0xb5, 2,        0x08, 0x08,
285         0xb8, 2,        0x08, 0x88,
286         0xc4, 4,        0xae, 0x01, 0x04, 0x01,
287         0xcc, 1,        0x00,
288         0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
289                         0xc1, 0xd7, 0xec,
290         0xdc, 1,        0x01,
291         0xff, 1,        0x01,           /* page 1 */
292         0x12, 3,        0x02, 0x00, 0x01,
293         0x3e, 2,        0x00, 0x00,
294         0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
295         0x7c, 1,        0x00,
296         0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
297                         0x02, 0x00,
298         0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
299         0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
300                         0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
301         0xd8, 1,        0x01,
302         0xdb, 2,        0x00, 0x01,
303         0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
304         0xe6, 4,        0x00, 0x00, 0x00, 0x01,
305         0xeb, 1,        0x00,
306         0xff, 1,        0x02,           /* page 2 */
307         0x22, 1,        0x00,
308         0xff, 1,        0x03,           /* page 3 */
309         0, LOAD_PAGE3,                  /* load the page 3 */
310         0x11, 1,        0x01,
311         0xff, 1,        0x02,           /* page 2 */
312         0x13, 1,        0x00,
313         0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
314         0x27, 2,        0x14, 0x0c,
315         0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
316         0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
317         0x6e, 1,        0x08,
318         0xff, 1,        0x01,           /* page 1 */
319         0x78, 1,        0x00,
320         0, END_OF_SEQUENCE              /* end of sequence */
321 };
322
323 #define SKIP            0xaa
324 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
325 static const __u8 page3_7302[] = {
326         0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
327         0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
328         0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329         0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
330         0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
331         0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
332         0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
333         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334         0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
335         0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
336         0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337         0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339         0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
340         0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
341         0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
342         0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
343         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344         0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
345         0x00
346 };
347
348 /* pac 7311 */
349 static const __u8 init_7311[] = {
350         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
351         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
352         0x78, 0x44,     /* Bit_0=start stream, Bit_6=LED */
353         0xff, 0x04,
354         0x27, 0x80,
355         0x28, 0xca,
356         0x29, 0x53,
357         0x2a, 0x0e,
358         0xff, 0x01,
359         0x3e, 0x20,
360 };
361
362 static const __u8 start_7311[] = {
363 /*      index, len, [value]* */
364         0xff, 1,        0x01,           /* page 1 */
365         0x02, 43,       0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
366                         0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
367                         0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
368                         0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
369                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370                         0x00, 0x00, 0x00,
371         0x3e, 42,       0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
372                         0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
373                         0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
374                         0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
375                         0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
376                         0xd0, 0xff,
377         0x78, 6,        0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
378         0x7f, 18,       0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
379                         0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
380                         0x18, 0x20,
381         0x96, 3,        0x01, 0x08, 0x04,
382         0xa0, 4,        0x44, 0x44, 0x44, 0x04,
383         0xf0, 13,       0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
384                         0x3f, 0x00, 0x0a, 0x01, 0x00,
385         0xff, 1,        0x04,           /* page 4 */
386         0, LOAD_PAGE4,                  /* load the page 4 */
387         0x11, 1,        0x01,
388         0, END_OF_SEQUENCE              /* end of sequence */
389 };
390
391 /* page 4 - the value SKIP says skip the index - see reg_w_page() */
392 static const __u8 page4_7311[] = {
393         SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
394         0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
395         0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
396         0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
397         SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
398         0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
399         0x23, 0x28, 0x04, 0x11, 0x00, 0x00
400 };
401
402 static void reg_w_buf(struct gspca_dev *gspca_dev,
403                   __u8 index,
404                   const char *buffer, int len)
405 {
406         memcpy(gspca_dev->usb_buf, buffer, len);
407         usb_control_msg(gspca_dev->dev,
408                         usb_sndctrlpipe(gspca_dev->dev, 0),
409                         1,              /* request */
410                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
411                         0,              /* value */
412                         index, gspca_dev->usb_buf, len,
413                         500);
414 }
415
416
417 static void reg_w(struct gspca_dev *gspca_dev,
418                   __u8 index,
419                   __u8 value)
420 {
421         gspca_dev->usb_buf[0] = value;
422         usb_control_msg(gspca_dev->dev,
423                         usb_sndctrlpipe(gspca_dev->dev, 0),
424                         0,                      /* request */
425                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
426                         0, index, gspca_dev->usb_buf, 1,
427                         500);
428 }
429
430 static void reg_w_seq(struct gspca_dev *gspca_dev,
431                 const __u8 *seq, int len)
432 {
433         while (--len >= 0) {
434                 reg_w(gspca_dev, seq[0], seq[1]);
435                 seq += 2;
436         }
437 }
438
439 /* load the beginning of a page */
440 static void reg_w_page(struct gspca_dev *gspca_dev,
441                         const __u8 *page, int len)
442 {
443         int index;
444
445         for (index = 0; index < len; index++) {
446                 if (page[index] == SKIP)                /* skip this index */
447                         continue;
448                 gspca_dev->usb_buf[0] = page[index];
449                 usb_control_msg(gspca_dev->dev,
450                                 usb_sndctrlpipe(gspca_dev->dev, 0),
451                                 0,                      /* request */
452                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
453                                 0, index, gspca_dev->usb_buf, 1,
454                                 500);
455         }
456 }
457
458 /* output a variable sequence */
459 static void reg_w_var(struct gspca_dev *gspca_dev,
460                         const __u8 *seq)
461 {
462         int index, len;
463
464         for (;;) {
465                 index = *seq++;
466                 len = *seq++;
467                 switch (len) {
468                 case END_OF_SEQUENCE:
469                         return;
470                 case LOAD_PAGE4:
471                         reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
472                         break;
473                 case LOAD_PAGE3:
474                         reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
475                         break;
476                 default:
477                         if (len > USB_BUF_SZ) {
478                                 PDEBUG(D_ERR|D_STREAM,
479                                         "Incorrect variable sequence");
480                                 return;
481                         }
482                         while (len > 0) {
483                                 if (len < 8) {
484                                         reg_w_buf(gspca_dev, index, seq, len);
485                                         seq += len;
486                                         break;
487                                 }
488                                 reg_w_buf(gspca_dev, index, seq, 8);
489                                 seq += 8;
490                                 index += 8;
491                                 len -= 8;
492                         }
493                 }
494         }
495         /* not reached */
496 }
497
498 /* this function is called at probe time */
499 static int sd_config(struct gspca_dev *gspca_dev,
500                         const struct usb_device_id *id)
501 {
502         struct sd *sd = (struct sd *) gspca_dev;
503         struct cam *cam;
504
505         cam = &gspca_dev->cam;
506
507         sd->sensor = id->driver_info;
508         if (sd->sensor == SENSOR_PAC7302) {
509                 PDEBUG(D_CONF, "Find Sensor PAC7302");
510                 cam->cam_mode = &vga_mode[2];   /* only 640x480 */
511                 cam->nmodes = 1;
512         } else {
513                 PDEBUG(D_CONF, "Find Sensor PAC7311");
514                 cam->cam_mode = vga_mode;
515                 cam->nmodes = ARRAY_SIZE(vga_mode);
516                 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
517                                 | (1 << SATURATION_IDX);
518         }
519
520         sd->brightness = BRIGHTNESS_DEF;
521         sd->contrast = CONTRAST_DEF;
522         sd->colors = COLOR_DEF;
523         sd->gain = GAIN_DEF;
524         sd->exposure = EXPOSURE_DEF;
525         sd->autogain = AUTOGAIN_DEF;
526         sd->hflip = HFLIP_DEF;
527         sd->vflip = VFLIP_DEF;
528         return 0;
529 }
530
531 /* This function is used by pac7302 only */
532 static void setbrightcont(struct gspca_dev *gspca_dev)
533 {
534         struct sd *sd = (struct sd *) gspca_dev;
535         int i, v;
536         static const __u8 max[10] =
537                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
538                  0xd4, 0xec};
539         static const __u8 delta[10] =
540                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
541                  0x11, 0x0b};
542
543         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
544         for (i = 0; i < 10; i++) {
545                 v = max[i];
546                 v += (sd->brightness - BRIGHTNESS_MAX)
547                         * 150 / BRIGHTNESS_MAX;         /* 200 ? */
548                 v -= delta[i] * sd->contrast / CONTRAST_MAX;
549                 if (v < 0)
550                         v = 0;
551                 else if (v > 0xff)
552                         v = 0xff;
553                 reg_w(gspca_dev, 0xa2 + i, v);
554         }
555         reg_w(gspca_dev, 0xdc, 0x01);
556 }
557
558 /* This function is used by pac7311 only */
559 static void setcontrast(struct gspca_dev *gspca_dev)
560 {
561         struct sd *sd = (struct sd *) gspca_dev;
562
563         reg_w(gspca_dev, 0xff, 0x04);
564         reg_w(gspca_dev, 0x10, sd->contrast >> 4);
565         /* load registers to sensor (Bit 0, auto clear) */
566         reg_w(gspca_dev, 0x11, 0x01);
567 }
568
569 /* This function is used by pac7302 only */
570 static void setcolors(struct gspca_dev *gspca_dev)
571 {
572         struct sd *sd = (struct sd *) gspca_dev;
573         int i, v;
574         static const int a[9] =
575                 {217, -212, 0, -101, 170, -67, -38, -315, 355};
576         static const int b[9] =
577                 {19, 106, 0, 19, 106, 1, 19, 106, 1};
578
579         reg_w(gspca_dev, 0xff, 0x03);   /* page 3 */
580         reg_w(gspca_dev, 0x11, 0x01);
581         reg_w(gspca_dev, 0xff, 0x00);   /* page 0 */
582         for (i = 0; i < 9; i++) {
583                 v = a[i] * sd->colors / COLOR_MAX + b[i];
584                 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
585                 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
586         }
587         reg_w(gspca_dev, 0xdc, 0x01);
588         PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
589 }
590
591 static void setgain(struct gspca_dev *gspca_dev)
592 {
593         struct sd *sd = (struct sd *) gspca_dev;
594
595         if (sd->sensor == SENSOR_PAC7302) {
596                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
597                 reg_w(gspca_dev, 0x10, sd->gain >> 3);
598         } else {
599                 int gain = GAIN_MAX - sd->gain;
600                 if (gain < 1)
601                         gain = 1;
602                 else if (gain > 245)
603                         gain = 245;
604                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
605                 reg_w(gspca_dev, 0x0e, 0x00);
606                 reg_w(gspca_dev, 0x0f, gain);
607         }
608         /* load registers to sensor (Bit 0, auto clear) */
609         reg_w(gspca_dev, 0x11, 0x01);
610 }
611
612 static void setexposure(struct gspca_dev *gspca_dev)
613 {
614         struct sd *sd = (struct sd *) gspca_dev;
615         __u8 reg;
616
617         /* register 2 of frame 3/4 contains the clock divider configuring the
618            no fps according to the formula: 60 / reg. sd->exposure is the
619            desired exposure time in ms. */
620         reg = 120 * sd->exposure / 1000;
621         if (reg < 2)
622                 reg = 2;
623         else if (reg > 63)
624                 reg = 63;
625
626         if (sd->sensor == SENSOR_PAC7302) {
627                 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
628                    the nearest multiple of 3, except when between 6 and 12? */
629                 if (reg < 6 || reg > 12)
630                         reg = ((reg + 1) / 3) * 3;
631                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
632                 reg_w(gspca_dev, 0x02, reg);
633         } else {
634                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
635                 reg_w(gspca_dev, 0x02, reg);
636                 /* Page 1 register 8 must always be 0x08 except when not in
637                    640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
638                 reg_w(gspca_dev, 0xff, 0x01);
639                 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
640                                 reg <= 3)
641                         reg_w(gspca_dev, 0x08, 0x09);
642                 else
643                         reg_w(gspca_dev, 0x08, 0x08);
644         }
645         /* load registers to sensor (Bit 0, auto clear) */
646         reg_w(gspca_dev, 0x11, 0x01);
647 }
648
649 static void sethvflip(struct gspca_dev *gspca_dev)
650 {
651         struct sd *sd = (struct sd *) gspca_dev;
652         __u8 data;
653
654         if (sd->sensor == SENSOR_PAC7302) {
655                 reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
656                 data = (sd->hflip ? 0x08 : 0x00)
657                         | (sd->vflip ? 0x04 : 0x00);
658         } else {
659                 reg_w(gspca_dev, 0xff, 0x04);           /* page 4 */
660                 data = (sd->hflip ? 0x04 : 0x00)
661                         | (sd->vflip ? 0x08 : 0x00);
662         }
663         reg_w(gspca_dev, 0x21, data);
664         /* load registers to sensor (Bit 0, auto clear) */
665         reg_w(gspca_dev, 0x11, 0x01);
666 }
667
668 /* this function is called at probe and resume time */
669 static int sd_init(struct gspca_dev *gspca_dev)
670 {
671         struct sd *sd = (struct sd *) gspca_dev;
672
673         if (sd->sensor == SENSOR_PAC7302)
674                 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
675         else
676                 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
677
678         return 0;
679 }
680
681 static int sd_start(struct gspca_dev *gspca_dev)
682 {
683         struct sd *sd = (struct sd *) gspca_dev;
684
685         sd->sof_read = 0;
686
687         if (sd->sensor == SENSOR_PAC7302) {
688                 reg_w_var(gspca_dev, start_7302);
689                 setbrightcont(gspca_dev);
690                 setcolors(gspca_dev);
691         } else {
692                 reg_w_var(gspca_dev, start_7311);
693                 setcontrast(gspca_dev);
694         }
695         setgain(gspca_dev);
696         setexposure(gspca_dev);
697         sethvflip(gspca_dev);
698
699         /* set correct resolution */
700         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
701         case 2:                                 /* 160x120 pac7311 */
702                 reg_w(gspca_dev, 0xff, 0x01);
703                 reg_w(gspca_dev, 0x17, 0x20);
704                 reg_w(gspca_dev, 0x87, 0x10);
705                 break;
706         case 1:                                 /* 320x240 pac7311 */
707                 reg_w(gspca_dev, 0xff, 0x01);
708                 reg_w(gspca_dev, 0x17, 0x30);
709                 reg_w(gspca_dev, 0x87, 0x11);
710                 break;
711         case 0:                                 /* 640x480 */
712                 if (sd->sensor == SENSOR_PAC7302)
713                         break;
714                 reg_w(gspca_dev, 0xff, 0x01);
715                 reg_w(gspca_dev, 0x17, 0x00);
716                 reg_w(gspca_dev, 0x87, 0x12);
717                 break;
718         }
719
720         sd->sof_read = 0;
721         sd->autogain_ignore_frames = 0;
722         atomic_set(&sd->avg_lum, -1);
723
724         /* start stream */
725         reg_w(gspca_dev, 0xff, 0x01);
726         if (sd->sensor == SENSOR_PAC7302)
727                 reg_w(gspca_dev, 0x78, 0x01);
728         else
729                 reg_w(gspca_dev, 0x78, 0x05);
730         return 0;
731 }
732
733 static void sd_stopN(struct gspca_dev *gspca_dev)
734 {
735         struct sd *sd = (struct sd *) gspca_dev;
736
737         if (sd->sensor == SENSOR_PAC7302) {
738                 reg_w(gspca_dev, 0xff, 0x01);
739                 reg_w(gspca_dev, 0x78, 0x00);
740                 reg_w(gspca_dev, 0x78, 0x00);
741                 return;
742         }
743         reg_w(gspca_dev, 0xff, 0x04);
744         reg_w(gspca_dev, 0x27, 0x80);
745         reg_w(gspca_dev, 0x28, 0xca);
746         reg_w(gspca_dev, 0x29, 0x53);
747         reg_w(gspca_dev, 0x2a, 0x0e);
748         reg_w(gspca_dev, 0xff, 0x01);
749         reg_w(gspca_dev, 0x3e, 0x20);
750         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
751         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
752         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
753 }
754
755 /* called on streamoff with alt 0 and on disconnect */
756 static void sd_stop0(struct gspca_dev *gspca_dev)
757 {
758         struct sd *sd = (struct sd *) gspca_dev;
759
760         if (!gspca_dev->present)
761                 return;
762         if (sd->sensor == SENSOR_PAC7302) {
763                 reg_w(gspca_dev, 0xff, 0x01);
764                 reg_w(gspca_dev, 0x78, 0x40);
765         }
766 }
767
768 /* Include pac common sof detection functions */
769 #include "pac_common.h"
770
771 static void do_autogain(struct gspca_dev *gspca_dev)
772 {
773         struct sd *sd = (struct sd *) gspca_dev;
774         int avg_lum = atomic_read(&sd->avg_lum);
775         int desired_lum, deadzone;
776
777         if (avg_lum == -1)
778                 return;
779
780         if (sd->sensor == SENSOR_PAC7302) {
781                 desired_lum = 270 + sd->brightness * 4;
782                 /* Hack hack, with the 7202 the first exposure step is
783                    pretty large, so if we're about to make the first
784                    exposure increase make the deadzone large to avoid
785                    oscilating */
786                 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
787                                 sd->exposure > EXPOSURE_DEF &&
788                                 sd->exposure < 42)
789                         deadzone = 90;
790                 else
791                         deadzone = 30;
792         } else {
793                 desired_lum = 200;
794                 deadzone = 20;
795         }
796
797         if (sd->autogain_ignore_frames > 0)
798                 sd->autogain_ignore_frames--;
799         else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
800                         deadzone, GAIN_KNEE, EXPOSURE_KNEE))
801                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
802 }
803
804 /* JPEG header, part 1 */
805 static const unsigned char pac_jpeg_header1[] = {
806   0xff, 0xd8,           /* SOI: Start of Image */
807
808   0xff, 0xc0,           /* SOF0: Start of Frame (Baseline DCT) */
809   0x00, 0x11,           /* length = 17 bytes (including this length field) */
810   0x08                  /* Precision: 8 */
811   /* 2 bytes is placed here: number of image lines */
812   /* 2 bytes is placed here: samples per line */
813 };
814
815 /* JPEG header, continued */
816 static const unsigned char pac_jpeg_header2[] = {
817   0x03,                 /* Number of image components: 3 */
818   0x01, 0x21, 0x00,     /* ID=1, Subsampling 1x1, Quantization table: 0 */
819   0x02, 0x11, 0x01,     /* ID=2, Subsampling 2x1, Quantization table: 1 */
820   0x03, 0x11, 0x01,     /* ID=3, Subsampling 2x1, Quantization table: 1 */
821
822   0xff, 0xda,           /* SOS: Start Of Scan */
823   0x00, 0x0c,           /* length = 12 bytes (including this length field) */
824   0x03,                 /* number of components: 3 */
825   0x01, 0x00,           /* selector 1, table 0x00 */
826   0x02, 0x11,           /* selector 2, table 0x11 */
827   0x03, 0x11,           /* selector 3, table 0x11 */
828   0x00, 0x3f,           /* Spectral selection: 0 .. 63 */
829   0x00                  /* Successive approximation: 0 */
830 };
831
832 static void pac_start_frame(struct gspca_dev *gspca_dev,
833                 struct gspca_frame *frame,
834                 __u16 lines, __u16 samples_per_line)
835 {
836         unsigned char tmpbuf[4];
837
838         gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
839                 pac_jpeg_header1, sizeof(pac_jpeg_header1));
840
841         tmpbuf[0] = lines >> 8;
842         tmpbuf[1] = lines & 0xff;
843         tmpbuf[2] = samples_per_line >> 8;
844         tmpbuf[3] = samples_per_line & 0xff;
845
846         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
847                 tmpbuf, sizeof(tmpbuf));
848         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
849                 pac_jpeg_header2, sizeof(pac_jpeg_header2));
850 }
851
852 /* this function is run at interrupt level */
853 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
854                         struct gspca_frame *frame,      /* target */
855                         __u8 *data,                     /* isoc packet */
856                         int len)                        /* iso packet length */
857 {
858         struct sd *sd = (struct sd *) gspca_dev;
859         unsigned char *sof;
860
861         sof = pac_find_sof(&sd->sof_read, data, len);
862         if (sof) {
863                 int n, lum_offset, footer_length;
864
865                 if (sd->sensor == SENSOR_PAC7302) {
866                   /* 6 bytes after the FF D9 EOF marker a number of lumination
867                      bytes are send corresponding to different parts of the
868                      image, the 14th and 15th byte after the EOF seem to
869                      correspond to the center of the image */
870                   lum_offset = 61 + sizeof pac_sof_marker;
871                   footer_length = 74;
872                 } else {
873                   lum_offset = 24 + sizeof pac_sof_marker;
874                   footer_length = 26;
875                 }
876
877                 /* Finish decoding current frame */
878                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
879                 if (n < 0) {
880                         frame->data_end += n;
881                         n = 0;
882                 }
883                 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
884                                         data, n);
885                 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
886                                 frame->data_end[-2] == 0xff &&
887                                 frame->data_end[-1] == 0xd9)
888                         frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
889                                                 NULL, 0);
890
891                 n = sof - data;
892                 len -= n;
893                 data = sof;
894
895                 /* Get average lumination */
896                 if (gspca_dev->last_packet_type == LAST_PACKET &&
897                                 n >= lum_offset)
898                         atomic_set(&sd->avg_lum, data[-lum_offset] +
899                                                 data[-lum_offset + 1]);
900                 else
901                         atomic_set(&sd->avg_lum, -1);
902
903                 /* Start the new frame with the jpeg header */
904                 if (sd->sensor == SENSOR_PAC7302) {
905                         /* The PAC7302 has the image rotated 90 degrees */
906                         pac_start_frame(gspca_dev, frame,
907                                 gspca_dev->width, gspca_dev->height);
908                 } else {
909                         pac_start_frame(gspca_dev, frame,
910                                 gspca_dev->height, gspca_dev->width);
911                 }
912         }
913         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
914 }
915
916 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
917 {
918         struct sd *sd = (struct sd *) gspca_dev;
919
920         sd->brightness = val;
921         if (gspca_dev->streaming)
922                 setbrightcont(gspca_dev);
923         return 0;
924 }
925
926 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
927 {
928         struct sd *sd = (struct sd *) gspca_dev;
929
930         *val = sd->brightness;
931         return 0;
932 }
933
934 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
935 {
936         struct sd *sd = (struct sd *) gspca_dev;
937
938         sd->contrast = val;
939         if (gspca_dev->streaming) {
940                 if (sd->sensor == SENSOR_PAC7302)
941                         setbrightcont(gspca_dev);
942                 else
943                         setcontrast(gspca_dev);
944         }
945         return 0;
946 }
947
948 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
949 {
950         struct sd *sd = (struct sd *) gspca_dev;
951
952         *val = sd->contrast;
953         return 0;
954 }
955
956 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
957 {
958         struct sd *sd = (struct sd *) gspca_dev;
959
960         sd->colors = val;
961         if (gspca_dev->streaming)
962                 setcolors(gspca_dev);
963         return 0;
964 }
965
966 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
967 {
968         struct sd *sd = (struct sd *) gspca_dev;
969
970         *val = sd->colors;
971         return 0;
972 }
973
974 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
975 {
976         struct sd *sd = (struct sd *) gspca_dev;
977
978         sd->gain = val;
979         if (gspca_dev->streaming)
980                 setgain(gspca_dev);
981         return 0;
982 }
983
984 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
985 {
986         struct sd *sd = (struct sd *) gspca_dev;
987
988         *val = sd->gain;
989         return 0;
990 }
991
992 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
993 {
994         struct sd *sd = (struct sd *) gspca_dev;
995
996         sd->exposure = val;
997         if (gspca_dev->streaming)
998                 setexposure(gspca_dev);
999         return 0;
1000 }
1001
1002 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1003 {
1004         struct sd *sd = (struct sd *) gspca_dev;
1005
1006         *val = sd->exposure;
1007         return 0;
1008 }
1009
1010 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1011 {
1012         struct sd *sd = (struct sd *) gspca_dev;
1013
1014         sd->autogain = val;
1015         /* when switching to autogain set defaults to make sure
1016            we are on a valid point of the autogain gain /
1017            exposure knee graph, and give this change time to
1018            take effect before doing autogain. */
1019         if (sd->autogain) {
1020                 sd->exposure = EXPOSURE_DEF;
1021                 sd->gain = GAIN_DEF;
1022                 if (gspca_dev->streaming) {
1023                         sd->autogain_ignore_frames =
1024                                 PAC_AUTOGAIN_IGNORE_FRAMES;
1025                         setexposure(gspca_dev);
1026                         setgain(gspca_dev);
1027                 }
1028         }
1029
1030         return 0;
1031 }
1032
1033 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1034 {
1035         struct sd *sd = (struct sd *) gspca_dev;
1036
1037         *val = sd->autogain;
1038         return 0;
1039 }
1040
1041 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1042 {
1043         struct sd *sd = (struct sd *) gspca_dev;
1044
1045         sd->hflip = val;
1046         if (gspca_dev->streaming)
1047                 sethvflip(gspca_dev);
1048         return 0;
1049 }
1050
1051 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1052 {
1053         struct sd *sd = (struct sd *) gspca_dev;
1054
1055         *val = sd->hflip;
1056         return 0;
1057 }
1058
1059 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1060 {
1061         struct sd *sd = (struct sd *) gspca_dev;
1062
1063         sd->vflip = val;
1064         if (gspca_dev->streaming)
1065                 sethvflip(gspca_dev);
1066         return 0;
1067 }
1068
1069 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1070 {
1071         struct sd *sd = (struct sd *) gspca_dev;
1072
1073         *val = sd->vflip;
1074         return 0;
1075 }
1076
1077 /* sub-driver description */
1078 static struct sd_desc sd_desc = {
1079         .name = MODULE_NAME,
1080         .ctrls = sd_ctrls,
1081         .nctrls = ARRAY_SIZE(sd_ctrls),
1082         .config = sd_config,
1083         .init = sd_init,
1084         .start = sd_start,
1085         .stopN = sd_stopN,
1086         .stop0 = sd_stop0,
1087         .pkt_scan = sd_pkt_scan,
1088         .dq_callback = do_autogain,
1089 };
1090
1091 /* -- module initialisation -- */
1092 static __devinitdata struct usb_device_id device_table[] = {
1093         {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
1094         {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
1095         {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
1096         {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
1097         {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
1098         {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
1099         {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1100         {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1101         {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1102         {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1103         {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1104         {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1105         {USB_DEVICE(0x093a, 0x2628), .driver_info = SENSOR_PAC7302},
1106         {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
1107         {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1108         {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1109         {}
1110 };
1111 MODULE_DEVICE_TABLE(usb, device_table);
1112
1113 /* -- device connect -- */
1114 static int sd_probe(struct usb_interface *intf,
1115                         const struct usb_device_id *id)
1116 {
1117         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1118                                 THIS_MODULE);
1119 }
1120
1121 static struct usb_driver sd_driver = {
1122         .name = MODULE_NAME,
1123         .id_table = device_table,
1124         .probe = sd_probe,
1125         .disconnect = gspca_disconnect,
1126 #ifdef CONFIG_PM
1127         .suspend = gspca_suspend,
1128         .resume = gspca_resume,
1129 #endif
1130 };
1131
1132 /* -- module insert / remove -- */
1133 static int __init sd_mod_init(void)
1134 {
1135         int ret;
1136         ret = usb_register(&sd_driver);
1137         if (ret < 0)
1138                 return ret;
1139         PDEBUG(D_PROBE, "registered");
1140         return 0;
1141 }
1142 static void __exit sd_mod_exit(void)
1143 {
1144         usb_deregister(&sd_driver);
1145         PDEBUG(D_PROBE, "deregistered");
1146 }
1147
1148 module_init(sd_mod_init);
1149 module_exit(sd_mod_exit);