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