2 * Connexant Cx11646 library
3 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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
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.
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
22 #define MODULE_NAME "conex"
25 #define CONEX_CAM 1 /* special JPEG header */
28 #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3)
29 static const char version[] = "2.1.3";
31 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
32 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
33 MODULE_LICENSE("GPL");
35 /* specific webcam descriptor */
37 struct gspca_dev gspca_dev; /* !! must be the first item */
39 unsigned char brightness;
40 unsigned char contrast;
46 /* V4L2 controls supported by the driver */
47 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
48 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
49 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
50 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
51 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
52 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54 static struct ctrl sd_ctrls[] = {
55 #define SD_BRIGHTNESS 0
58 .id = V4L2_CID_BRIGHTNESS,
59 .type = V4L2_CTRL_TYPE_INTEGER,
64 .default_value = 0xd4,
66 .set = sd_setbrightness,
67 .get = sd_getbrightness,
72 .id = V4L2_CID_CONTRAST,
73 .type = V4L2_CTRL_TYPE_INTEGER,
78 .default_value = 0x0c,
80 .set = sd_setcontrast,
81 .get = sd_getcontrast,
86 .id = V4L2_CID_SATURATION,
87 .type = V4L2_CTRL_TYPE_INTEGER,
99 static struct cam_mode vga_mode[] = {
100 {V4L2_PIX_FMT_JPEG, 176, 144, 3},
101 {V4L2_PIX_FMT_JPEG, 320, 240, 2},
102 {V4L2_PIX_FMT_JPEG, 352, 288, 1},
103 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
106 static void reg_r(struct usb_device *dev,
108 __u8 *buffer, __u16 length)
111 usb_rcvctrlpipe(dev, 0),
113 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
115 index, buffer, length,
117 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", index, *buffer);
120 static void reg_w(struct usb_device *dev,
122 const __u8 *buffer, __u16 len)
126 #ifdef CONFIG_VIDEO_ADV_DEBUG
127 if (len > sizeof tmpbuf) {
128 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
131 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
133 memcpy(tmpbuf, buffer, len);
135 usb_sndctrlpipe(dev, 0),
137 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
139 index, tmpbuf, len, 500);
142 static const __u8 cx_sensor_init[][4] = {
143 {0x88, 0x11, 0x01, 0x01},
144 {0x88, 0x12, 0x70, 0x01},
145 {0x88, 0x0f, 0x00, 0x01},
146 {0x88, 0x05, 0x01, 0x01},
150 static const __u8 cx11646_fw1[][3] = {
217 static void cx11646_fw(struct gspca_dev*gspca_dev)
223 reg_w(gspca_dev->dev, 0x006a, &val, 1);
224 while (cx11646_fw1[i][1]) {
225 reg_w(gspca_dev->dev, 0x006b, cx11646_fw1[i], 3);
229 reg_w(gspca_dev->dev, 0x006a, &val, 1);
232 static __u8 cxsensor[] = {
233 0x88, 0x12, 0x70, 0x01,
234 0x88, 0x0d, 0x02, 0x01,
235 0x88, 0x0f, 0x00, 0x01,
236 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
237 0x88, 0x02, 0x10, 0x01,
238 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
239 0x88, 0x0B, 0x00, 0x01,
240 0x88, 0x0A, 0x0A, 0x01,
241 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
242 0x88, 0x05, 0x01, 0x01,
243 0xA1, 0x18, 0x00, 0x01,
247 static __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
248 static __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
249 static __u8 reg10[] = { 0xb1, 0xb1 };
250 static __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
251 static __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
252 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
253 static __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
254 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
255 static __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
256 static __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
258 static void cx_sensor(struct gspca_dev*gspca_dev)
262 __u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
264 __u8 *ptsensor = cxsensor;
266 reg_w(gspca_dev->dev, 0x0020, reg20, 8);
267 reg_w(gspca_dev->dev, 0x0028, reg28, 8);
268 reg_w(gspca_dev->dev, 0x0010, reg10, 8);
270 reg_w(gspca_dev->dev, 0x0092, &val, 1);
272 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) {
274 reg_w(gspca_dev->dev, 0x0071, reg71a, 4);
277 reg_w(gspca_dev->dev, 0x0071, reg71b, 4);
281 reg_w(gspca_dev->dev, 0x0071, reg71c, 4);
284 reg_w(gspca_dev->dev, 0x0071, reg71d, 4);
287 reg_w(gspca_dev->dev, 0x007b, reg7b, 6);
289 reg_w(gspca_dev->dev, 0x00f8, &val, 1);
290 reg_w(gspca_dev->dev, 0x0010, reg10, 8);
292 reg_w(gspca_dev->dev, 0x0098, &val, 1);
293 for (i = 0; i < 11; i++) {
294 if (i == 3 || i == 5 || i == 8)
298 reg_w(gspca_dev->dev, 0x00e5, ptsensor, length);
300 reg_r(gspca_dev->dev, 0x00e8, &val, 1);
302 reg_r(gspca_dev->dev, 0x00e8, bufread, length);
305 reg_r(gspca_dev->dev, 0x00e7, bufread, 8);
308 static __u8 cx_inits_176[] = {
309 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
310 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
311 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
312 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
313 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
314 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
315 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
317 static __u8 cx_inits_320[] = {
318 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
319 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
320 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
321 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
322 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
323 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
324 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
326 static __u8 cx_inits_352[] = {
327 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
328 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
329 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
330 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
331 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
332 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
333 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
335 static __u8 cx_inits_640[] = {
336 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
337 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
338 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
339 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
340 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
341 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
342 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
345 static int cx11646_initsize(struct gspca_dev *gspca_dev)
349 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
350 static const __u8 reg17[] =
351 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
353 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) {
355 cxinit = cx_inits_640;
358 cxinit = cx_inits_352;
362 cxinit = cx_inits_320;
365 cxinit = cx_inits_176;
369 reg_w(gspca_dev->dev, 0x009a, &val, 1);
371 reg_w(gspca_dev->dev, 0x0010, &val, 1);
372 reg_w(gspca_dev->dev, 0x0012, reg12, 5);
373 reg_w(gspca_dev->dev, 0x0017, reg17, 8);
375 reg_w(gspca_dev->dev, 0x00c0, &val, 1);
377 reg_w(gspca_dev->dev, 0x00c1, &val, 1);
379 reg_w(gspca_dev->dev, 0x00c2, &val, 1);
381 reg_w(gspca_dev->dev, 0x0061, cxinit, 8);
383 reg_w(gspca_dev->dev, 0x00ca, cxinit, 8);
385 reg_w(gspca_dev->dev, 0x00d2, cxinit, 8);
387 reg_w(gspca_dev->dev, 0x00da, cxinit, 6);
389 reg_w(gspca_dev->dev, 0x0041, cxinit, 8);
391 reg_w(gspca_dev->dev, 0x0049, cxinit, 8);
393 reg_w(gspca_dev->dev, 0x0051, cxinit, 2);
395 reg_r(gspca_dev->dev, 0x0010, &val, 1);
399 static __u8 cx_jpeg_init[][8] = {
400 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
401 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
402 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
403 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
404 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
405 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
406 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
407 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
408 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
409 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
410 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
411 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
412 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
413 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
414 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
415 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
416 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
417 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
418 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
419 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
420 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
421 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
422 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
423 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
424 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
425 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
426 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
427 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
428 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
429 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
430 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
431 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
432 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
433 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
434 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
435 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
436 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
437 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
438 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
439 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
440 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
441 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
442 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
443 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
444 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
445 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
446 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
447 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
448 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
449 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
450 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
451 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
452 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
453 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
454 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
455 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
456 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
457 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
458 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
459 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
460 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
461 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
462 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
463 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
464 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
465 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
466 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
467 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
468 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
469 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
470 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
471 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
472 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
473 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
474 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
475 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
476 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
477 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
478 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
482 static __u8 cxjpeg_640[][8] = {
483 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
484 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
485 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
486 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
487 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
488 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
489 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
490 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
491 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
492 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
493 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
494 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
495 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
496 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
497 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
498 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
499 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
500 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
501 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
502 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
503 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
504 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
505 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
506 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
507 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
508 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
509 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
511 static __u8 cxjpeg_352[][8] = {
512 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
513 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
514 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
515 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
516 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
517 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
518 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
519 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
520 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
521 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
522 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
523 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
524 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
525 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
526 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
527 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
528 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
529 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
530 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
531 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
532 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
533 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
534 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
535 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
536 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
537 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
538 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
540 static __u8 cxjpeg_320[][8] = {
541 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
542 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
543 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
544 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
545 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
546 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
547 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
548 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
549 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
550 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
551 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
552 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
553 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
554 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
555 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
556 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
557 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
558 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
559 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
560 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
561 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
562 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
563 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
564 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
565 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
566 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
567 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
569 static __u8 cxjpeg_176[][8] = {
570 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
571 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
572 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
573 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
574 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
575 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
576 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
577 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
578 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
579 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
580 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
581 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
582 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
583 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
584 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
585 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
586 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
587 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
588 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
589 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
590 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
591 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
592 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
593 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
594 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
595 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
596 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
598 static __u8 cxjpeg_qtable[][8] = { /* 640 take with the zcx30x part */
599 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
600 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
601 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
602 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
603 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
604 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
605 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
606 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
607 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
608 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
609 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
610 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
611 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
612 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
613 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
614 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
615 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
616 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
620 static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
627 reg_w(gspca_dev->dev, 0x00c0, &val, 1);
629 reg_w(gspca_dev->dev, 0x00c3, &val, 1);
631 reg_w(gspca_dev->dev, 0x00c0, &val, 1);
632 reg_r(gspca_dev->dev, 0x0001, &val, 1);
634 for (i = 0; i < 79; i++) {
637 reg_w(gspca_dev->dev, 0x0008, cx_jpeg_init[i], length);
639 reg_r(gspca_dev->dev, 0x0002, &val, 1);
641 reg_w(gspca_dev->dev, 0x0055, &val, 1);
644 static __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
645 static __u8 regE5_8[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
646 static __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
647 static __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
648 static __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
649 static __u8 reg51[] = { 0x77, 0x03 };
650 static __u8 reg70 = 0x03;
652 static void cx11646_jpeg(struct gspca_dev*gspca_dev)
658 __u8 bufread[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
662 reg_w(gspca_dev->dev, 0x00c0, &val, 1);
664 reg_w(gspca_dev->dev, 0x00c3, &val, 1);
666 reg_w(gspca_dev->dev, 0x00c0, &val, 1);
667 reg_r(gspca_dev->dev, 0x0001, &val, 1);
668 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) {
670 for (i = 0; i < 27; i++) {
673 reg_w(gspca_dev->dev, 0x0008, cxjpeg_640[i], length);
678 for (i = 0; i < 27; i++) {
681 reg_w(gspca_dev->dev, 0x0008, cxjpeg_352[i], length);
687 for (i = 0; i < 27; i++) {
690 reg_w(gspca_dev->dev, 0x0008, cxjpeg_320[i], length);
695 for (i = 0; i < 27; i++) {
698 reg_w(gspca_dev->dev, 0x0008, cxjpeg_176[i], length);
704 reg_r(gspca_dev->dev, 0x0002, &val, 1);
706 reg_w(gspca_dev->dev, 0x0055, &val, 1);
707 reg_r(gspca_dev->dev, 0x0002, &val, 1);
708 reg_w(gspca_dev->dev, 0x0010, reg10, 2);
710 reg_w(gspca_dev->dev, 0x0054, &val, 1);
712 reg_w(gspca_dev->dev, 0x0054, &val, 1);
714 reg_w(gspca_dev->dev, 0x0000, &val, 1);
716 reg_w(gspca_dev->dev, 0x0053, &val, 1);
718 reg_w(gspca_dev->dev, 0x00fc, &val, 1);
720 reg_w(gspca_dev->dev, 0x0000, &val, 1);
721 /* wait for completion */
723 reg_r(gspca_dev->dev, 0x0002, &val, 1);
724 /* 0x07 until 0x00 */
728 reg_w(gspca_dev->dev, 0x0053, &val, 1);
731 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
732 /* send the qtable now */
733 reg_r(gspca_dev->dev, 0x0001, &val, 1); /* -> 0x18 */
735 for (i = 0; i < 18; i++) {
738 reg_w(gspca_dev->dev, 0x0008, cxjpeg_qtable[i], length);
741 reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */
742 reg_r(gspca_dev->dev, 0x0053, &val, 1); /* 0x00 */
744 reg_w(gspca_dev->dev, 0x0054, &val, 1);
746 reg_w(gspca_dev->dev, 0x0054, &val, 1);
748 reg_w(gspca_dev->dev, 0x0000, &val, 1);
750 reg_w(gspca_dev->dev, 0x0053, &val, 1);
752 reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */
753 reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */
754 reg_r(gspca_dev->dev, 0x001f, &val, 1); /* 0x38 */
755 reg_w(gspca_dev->dev, 0x0012, reg12, 5);
756 reg_w(gspca_dev->dev, 0x00e5, regE5_8, 8);
757 reg_r(gspca_dev->dev, 0x00e8, bufread, 8);
758 reg_w(gspca_dev->dev, 0x00e5, regE5a, 4);
759 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
761 reg_w(gspca_dev->dev, 0x009a, &val, 1);
762 reg_w(gspca_dev->dev, 0x00e5, regE5b, 4);
763 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
764 reg_w(gspca_dev->dev, 0x00e5, regE5c, 4);
765 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
767 reg_w(gspca_dev->dev, 0x0051, reg51, 2);
768 reg_w(gspca_dev->dev, 0x0010, reg10, 2);
769 reg_w(gspca_dev->dev, 0x0070, ®70, 1);
772 static void cx11646_init1(struct gspca_dev *gspca_dev)
778 reg_w(gspca_dev->dev, 0x0010, &val, 1);
779 reg_w(gspca_dev->dev, 0x0053, &val, 1);
780 reg_w(gspca_dev->dev, 0x0052, &val, 1);
782 reg_w(gspca_dev->dev, 0x009b, &val, 1);
784 reg_w(gspca_dev->dev, 0x009c, &val, 1);
785 reg_r(gspca_dev->dev, 0x0098, &val, 1);
787 reg_w(gspca_dev->dev, 0x0098, &val, 1);
788 reg_r(gspca_dev->dev, 0x0099, &val, 1);
790 reg_w(gspca_dev->dev, 0x0099, &val, 1);
792 reg_w(gspca_dev->dev, 0x0039, &val, 1);
794 reg_w(gspca_dev->dev, 0x003c, &val, 1);
796 reg_w(gspca_dev->dev, 0x003f, &val, 1);
798 reg_w(gspca_dev->dev, 0x003d, &val, 1);
800 /* reg_w(gspca_dev->dev,0x00,0x00,0x003d,&val,1); */
801 reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */
803 while (cx_sensor_init[i][0]) {
804 reg_w(gspca_dev->dev, 0x00e5, cx_sensor_init[i], 1);
805 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* -> 0x00 */
808 reg_w(gspca_dev->dev, 0x00ed, &val, 1);
809 reg_r(gspca_dev->dev, 0x00ed, &val, 1); /* -> 0x01 */
814 reg_w(gspca_dev->dev, 0x00c3, &val, 1);
817 /* this function is called at probe time */
818 static int sd_config(struct gspca_dev *gspca_dev,
819 const struct usb_device_id *id)
821 struct sd *sd = (struct sd *) gspca_dev;
824 cam = &gspca_dev->cam;
825 cam->dev_name = (char *) id->driver_info;
827 cam->cam_mode = vga_mode;
828 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
830 sd->qindex = 0; /* set the quantization table */
831 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
832 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
833 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
837 /* this function is called at open time */
838 static int sd_open(struct gspca_dev *gspca_dev)
840 cx11646_init1(gspca_dev);
841 cx11646_initsize(gspca_dev);
842 cx11646_fw(gspca_dev);
843 cx_sensor(gspca_dev);
844 cx11646_jpegInit(gspca_dev);
848 static void sd_start(struct gspca_dev *gspca_dev)
850 cx11646_initsize(gspca_dev);
851 cx11646_fw(gspca_dev);
852 cx_sensor(gspca_dev);
853 cx11646_jpeg(gspca_dev);
856 static void sd_stopN(struct gspca_dev *gspca_dev)
860 static void sd_stop0(struct gspca_dev *gspca_dev)
866 reg_w(gspca_dev->dev, 0x0000, &val, 1);
867 reg_r(gspca_dev->dev, 0x0002, &val, 1);
869 reg_w(gspca_dev->dev, 0x0053, &val, 1);
872 /* reg_r(gspca_dev->dev, 0x0002, &val, 1);*/
873 reg_r(gspca_dev->dev, 0x0053, &val, 1);
878 reg_w(gspca_dev->dev, 0x0000, &val, 1);
879 reg_r(gspca_dev->dev, 0x0002, &val, 1);
882 reg_w(gspca_dev->dev, 0x0010, &val, 1);
883 reg_r(gspca_dev->dev, 0x0033, &val, 1);
885 reg_w(gspca_dev->dev, 0x00fc, &val, 1);
888 static void sd_close(struct gspca_dev *gspca_dev)
892 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
893 struct gspca_frame *frame, /* target */
894 unsigned char *data, /* isoc packet */
895 int len) /* iso packet length */
897 if (data[0] == 0xff && data[1] == 0xd8) {
900 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
903 /* put the JPEG header in the new frame */
904 jpeg_put_header(gspca_dev, frame,
905 ((struct sd *) gspca_dev)->qindex,
910 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
913 static void setbrightness(struct gspca_dev*gspca_dev)
915 struct sd *sd = (struct sd *) gspca_dev;
916 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
917 __u8 reg51c[] = { 0x77, 0x03 };
923 bright = sd->brightness;
925 regE5cbx[2] = bright;
927 reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8);
928 reg_r(gspca_dev->dev, 0x00e8, bufread, 8);
929 reg_w(gspca_dev->dev, 0x00e5, regE5c, 4);
930 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
932 reg_w(gspca_dev->dev, 0x0051, reg51c, 2);
933 reg_w(gspca_dev->dev, 0x0010, reg10, 2);
934 reg_w(gspca_dev->dev, 0x0070, ®70, 1);
937 static void setcontrast(struct gspca_dev*gspca_dev)
939 struct sd *sd = (struct sd *) gspca_dev;
940 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
941 /* __u8 regE5bcx[]={0x88,0x0b,0x12,0x01}; // LSB */
942 __u8 reg51c[] = { 0x77, 0x03 };
945 reg51c[1] = sd->colors;
946 regE5acx[2] = sd->contrast;
947 reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4);
948 reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */
949 reg_w(gspca_dev->dev, 0x0051, reg51c, 2);
950 reg_w(gspca_dev->dev, 0x0010, reg10, 2);
951 reg_w(gspca_dev->dev, 0x0070, ®70, 1);
954 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
956 struct sd *sd = (struct sd *) gspca_dev;
958 sd->brightness = val;
959 if (gspca_dev->streaming)
960 setbrightness(gspca_dev);
964 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
966 struct sd *sd = (struct sd *) gspca_dev;
968 *val = sd->brightness;
972 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
974 struct sd *sd = (struct sd *) gspca_dev;
977 if (gspca_dev->streaming)
978 setcontrast(gspca_dev);
982 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
984 struct sd *sd = (struct sd *) gspca_dev;
990 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
992 struct sd *sd = (struct sd *) gspca_dev;
995 if (gspca_dev->streaming) {
996 setbrightness(gspca_dev);
997 setcontrast(gspca_dev);
1002 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1004 struct sd *sd = (struct sd *) gspca_dev;
1010 /* sub-driver description */
1011 static struct sd_desc sd_desc = {
1012 .name = MODULE_NAME,
1014 .nctrls = ARRAY_SIZE(sd_ctrls),
1015 .config = sd_config,
1021 .pkt_scan = sd_pkt_scan,
1024 /* -- module initialisation -- */
1025 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1026 static __devinitdata struct usb_device_id device_table[] = {
1027 {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
1030 MODULE_DEVICE_TABLE(usb, device_table);
1032 /* -- device connect -- */
1033 static int sd_probe(struct usb_interface *intf,
1034 const struct usb_device_id *id)
1036 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1040 static struct usb_driver sd_driver = {
1041 .name = MODULE_NAME,
1042 .id_table = device_table,
1044 .disconnect = gspca_disconnect,
1047 /* -- module insert / remove -- */
1048 static int __init sd_mod_init(void)
1050 if (usb_register(&sd_driver) < 0)
1052 PDEBUG(D_PROBE, "v%s registered", version);
1055 static void __exit sd_mod_exit(void)
1057 usb_deregister(&sd_driver);
1058 PDEBUG(D_PROBE, "deregistered");
1061 module_init(sd_mod_init);
1062 module_exit(sd_mod_exit);