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