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, 5)
29 static const char version
[] = "2.1.5";
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
[] = {
57 .id
= V4L2_CID_BRIGHTNESS
,
58 .type
= V4L2_CTRL_TYPE_INTEGER
,
63 #define BRIGHTNESS_DEF 0xd4
64 .default_value
= BRIGHTNESS_DEF
,
66 .set
= sd_setbrightness
,
67 .get
= sd_getbrightness
,
71 .id
= V4L2_CID_CONTRAST
,
72 .type
= V4L2_CTRL_TYPE_INTEGER
,
77 #define CONTRAST_DEF 0x0c
78 .default_value
= CONTRAST_DEF
,
80 .set
= sd_setcontrast
,
81 .get
= sd_getcontrast
,
85 .id
= V4L2_CID_SATURATION
,
86 .type
= V4L2_CTRL_TYPE_INTEGER
,
92 .default_value
= COLOR_DEF
,
99 static struct v4l2_pix_format vga_mode
[] = {
100 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
102 .sizeimage
= 176 * 144 * 3 / 8 + 590,
103 .colorspace
= V4L2_COLORSPACE_JPEG
,
105 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
107 .sizeimage
= 320 * 240 * 3 / 8 + 590,
108 .colorspace
= V4L2_COLORSPACE_JPEG
,
110 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
112 .sizeimage
= 352 * 288 * 3 / 8 + 590,
113 .colorspace
= V4L2_COLORSPACE_JPEG
,
115 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
117 .sizeimage
= 640 * 480 * 3 / 8 + 590,
118 .colorspace
= V4L2_COLORSPACE_JPEG
,
122 static void reg_r(struct usb_device
*dev
,
124 __u8
*buffer
, __u16 length
)
127 usb_rcvctrlpipe(dev
, 0),
129 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
131 index
, buffer
, length
,
133 PDEBUG(D_USBI
, "reg read [%02x] -> %02x ..", index
, *buffer
);
136 static void reg_w(struct usb_device
*dev
,
138 const __u8
*buffer
, __u16 len
)
142 #ifdef CONFIG_VIDEO_ADV_DEBUG
143 if (len
> sizeof tmpbuf
) {
144 PDEBUG(D_ERR
|D_PACK
, "reg_w: buffer overflow");
147 PDEBUG(D_USBO
, "reg write [%02x] = %02x..", index
, *buffer
);
149 memcpy(tmpbuf
, buffer
, len
);
151 usb_sndctrlpipe(dev
, 0),
153 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
155 index
, tmpbuf
, len
, 500);
158 static const __u8 cx_sensor_init
[][4] = {
159 {0x88, 0x11, 0x01, 0x01},
160 {0x88, 0x12, 0x70, 0x01},
161 {0x88, 0x0f, 0x00, 0x01},
162 {0x88, 0x05, 0x01, 0x01},
166 static const __u8 cx11646_fw1
[][3] = {
233 static void cx11646_fw(struct gspca_dev
*gspca_dev
)
239 reg_w(gspca_dev
->dev
, 0x006a, &val
, 1);
240 while (cx11646_fw1
[i
][1]) {
241 reg_w(gspca_dev
->dev
, 0x006b, cx11646_fw1
[i
], 3);
245 reg_w(gspca_dev
->dev
, 0x006a, &val
, 1);
248 static const __u8 cxsensor
[] = {
249 0x88, 0x12, 0x70, 0x01,
250 0x88, 0x0d, 0x02, 0x01,
251 0x88, 0x0f, 0x00, 0x01,
252 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
253 0x88, 0x02, 0x10, 0x01,
254 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
255 0x88, 0x0B, 0x00, 0x01,
256 0x88, 0x0A, 0x0A, 0x01,
257 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
258 0x88, 0x05, 0x01, 0x01,
259 0xA1, 0x18, 0x00, 0x01,
263 static const __u8 reg20
[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
264 static const __u8 reg28
[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
265 static const __u8 reg10
[] = { 0xb1, 0xb1 };
266 static const __u8 reg71a
[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
267 static const __u8 reg71b
[] = { 0x04, 0x0c, 0x05, 0x0f };
268 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
269 static const __u8 reg71c
[] = { 0x02, 0x07, 0x03, 0x09 };
270 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
271 static const __u8 reg71d
[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
272 static const __u8 reg7b
[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
274 static void cx_sensor(struct gspca_dev
*gspca_dev
)
278 __u8 bufread
[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
280 const __u8
*ptsensor
= cxsensor
;
282 reg_w(gspca_dev
->dev
, 0x0020, reg20
, 8);
283 reg_w(gspca_dev
->dev
, 0x0028, reg28
, 8);
284 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 8);
286 reg_w(gspca_dev
->dev
, 0x0092, &val
, 1);
288 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
290 reg_w(gspca_dev
->dev
, 0x0071, reg71a
, 4);
293 reg_w(gspca_dev
->dev
, 0x0071, reg71b
, 4);
297 reg_w(gspca_dev
->dev
, 0x0071, reg71c
, 4);
300 reg_w(gspca_dev
->dev
, 0x0071, reg71d
, 4);
303 reg_w(gspca_dev
->dev
, 0x007b, reg7b
, 6);
305 reg_w(gspca_dev
->dev
, 0x00f8, &val
, 1);
306 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 8);
308 reg_w(gspca_dev
->dev
, 0x0098, &val
, 1);
309 for (i
= 0; i
< 11; i
++) {
310 if (i
== 3 || i
== 5 || i
== 8)
314 reg_w(gspca_dev
->dev
, 0x00e5, ptsensor
, length
);
316 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1);
318 reg_r(gspca_dev
->dev
, 0x00e8, bufread
, length
);
321 reg_r(gspca_dev
->dev
, 0x00e7, bufread
, 8);
324 static const __u8 cx_inits_176
[] = {
325 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
326 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
327 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
328 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
329 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
330 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
331 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
333 static const __u8 cx_inits_320
[] = {
334 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
335 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
336 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
337 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
338 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
339 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
340 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
342 static const __u8 cx_inits_352
[] = {
343 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
344 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
345 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
346 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
347 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
348 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
349 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
351 static const __u8 cx_inits_640
[] = {
352 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
353 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
354 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
355 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
356 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
357 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
358 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
361 static int cx11646_initsize(struct gspca_dev
*gspca_dev
)
365 static const __u8 reg12
[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
366 static const __u8 reg17
[] =
367 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
369 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
371 cxinit
= cx_inits_640
;
374 cxinit
= cx_inits_352
;
378 cxinit
= cx_inits_320
;
381 cxinit
= cx_inits_176
;
385 reg_w(gspca_dev
->dev
, 0x009a, &val
, 1);
387 reg_w(gspca_dev
->dev
, 0x0010, &val
, 1);
388 reg_w(gspca_dev
->dev
, 0x0012, reg12
, 5);
389 reg_w(gspca_dev
->dev
, 0x0017, reg17
, 8);
391 reg_w(gspca_dev
->dev
, 0x00c0, &val
, 1);
393 reg_w(gspca_dev
->dev
, 0x00c1, &val
, 1);
395 reg_w(gspca_dev
->dev
, 0x00c2, &val
, 1);
397 reg_w(gspca_dev
->dev
, 0x0061, cxinit
, 8);
399 reg_w(gspca_dev
->dev
, 0x00ca, cxinit
, 8);
401 reg_w(gspca_dev
->dev
, 0x00d2, cxinit
, 8);
403 reg_w(gspca_dev
->dev
, 0x00da, cxinit
, 6);
405 reg_w(gspca_dev
->dev
, 0x0041, cxinit
, 8);
407 reg_w(gspca_dev
->dev
, 0x0049, cxinit
, 8);
409 reg_w(gspca_dev
->dev
, 0x0051, cxinit
, 2);
411 reg_r(gspca_dev
->dev
, 0x0010, &val
, 1);
415 static const __u8 cx_jpeg_init
[][8] = {
416 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
417 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
418 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
419 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
420 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
421 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
422 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
423 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
424 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
425 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
426 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
427 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
428 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
429 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
430 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
431 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
432 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
433 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
434 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
435 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
436 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
437 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
438 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
439 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
440 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
441 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
442 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
443 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
444 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
445 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
446 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
447 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
448 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
449 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
450 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
451 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
452 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
453 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
454 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
455 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
456 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
457 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
458 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
459 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
460 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
461 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
462 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
463 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
464 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
465 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
466 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
467 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
468 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
469 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
470 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
471 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
472 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
473 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
474 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
475 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
476 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
477 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
478 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
479 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
480 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
481 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
482 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
483 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
484 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
485 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
486 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
487 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
488 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
489 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
490 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
491 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
492 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
493 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
494 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
498 static const __u8 cxjpeg_640
[][8] = {
499 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
500 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
501 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
502 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
503 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
504 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
505 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
506 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
507 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
508 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
509 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
510 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
511 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
512 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
513 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
514 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
515 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
516 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
517 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
518 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
519 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
520 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
521 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
522 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
523 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
524 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
525 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
527 static const __u8 cxjpeg_352
[][8] = {
528 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
529 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
530 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
531 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
532 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
533 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
534 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
535 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
536 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
537 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
538 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
539 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
540 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
541 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
542 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
543 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
544 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
545 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
546 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
547 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
548 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
549 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
550 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
551 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
552 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
553 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
554 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
556 static const __u8 cxjpeg_320
[][8] = {
557 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
558 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
559 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
560 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
561 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
562 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
563 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
564 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
565 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
566 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
567 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
568 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
569 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
570 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
571 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
572 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
573 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
574 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
575 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
576 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
577 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
578 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
579 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
580 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
581 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
582 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
583 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
585 static const __u8 cxjpeg_176
[][8] = {
586 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
587 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
588 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
589 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
590 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
591 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
592 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
593 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
594 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
595 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
596 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
597 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
598 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
599 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
600 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
601 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
602 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
603 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
604 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
605 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
606 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
607 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
608 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
609 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
610 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
611 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
612 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
614 /* 640 take with the zcx30x part */
615 static const __u8 cxjpeg_qtable
[][8] = {
616 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
617 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
618 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
619 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
620 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
621 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
622 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
623 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
624 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
625 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
626 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
627 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
628 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
629 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
630 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
631 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
632 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
633 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
637 static void cx11646_jpegInit(struct gspca_dev
*gspca_dev
)
644 reg_w(gspca_dev
->dev
, 0x00c0, &val
, 1);
646 reg_w(gspca_dev
->dev
, 0x00c3, &val
, 1);
648 reg_w(gspca_dev
->dev
, 0x00c0, &val
, 1);
649 reg_r(gspca_dev
->dev
, 0x0001, &val
, 1);
651 for (i
= 0; i
< 79; i
++) {
654 reg_w(gspca_dev
->dev
, 0x0008, cx_jpeg_init
[i
], length
);
656 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
658 reg_w(gspca_dev
->dev
, 0x0055, &val
, 1);
661 static const __u8 reg12
[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
662 static const __u8 regE5_8
[] =
663 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
664 static const __u8 regE5a
[] = { 0x88, 0x0a, 0x0c, 0x01 };
665 static const __u8 regE5b
[] = { 0x88, 0x0b, 0x12, 0x01 };
666 static const __u8 regE5c
[] = { 0x88, 0x05, 0x01, 0x01 };
667 static const __u8 reg51
[] = { 0x77, 0x03 };
668 static const __u8 reg70
= 0x03;
670 static void cx11646_jpeg(struct gspca_dev
*gspca_dev
)
680 reg_w(gspca_dev
->dev
, 0x00c0, &val
, 1);
682 reg_w(gspca_dev
->dev
, 0x00c3, &val
, 1);
684 reg_w(gspca_dev
->dev
, 0x00c0, &val
, 1);
685 reg_r(gspca_dev
->dev
, 0x0001, &val
, 1);
687 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
689 for (i
= 0; i
< 27; i
++) {
692 reg_w(gspca_dev
->dev
, 0x0008, cxjpeg_640
[i
], length
);
697 for (i
= 0; i
< 27; i
++) {
700 reg_w(gspca_dev
->dev
, 0x0008, cxjpeg_352
[i
], length
);
706 for (i
= 0; i
< 27; i
++) {
709 reg_w(gspca_dev
->dev
, 0x0008, cxjpeg_320
[i
], length
);
714 for (i
= 0; i
< 27; i
++) {
717 reg_w(gspca_dev
->dev
, 0x0008, cxjpeg_176
[i
], length
);
723 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
725 reg_w(gspca_dev
->dev
, 0x0055, &val
, 1);
726 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
727 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 2);
729 reg_w(gspca_dev
->dev
, 0x0054, &val
, 1);
731 reg_w(gspca_dev
->dev
, 0x0054, &val
, 1);
733 reg_w(gspca_dev
->dev
, 0x0000, &val
, 1);
735 reg_w(gspca_dev
->dev
, 0x0053, &val
, 1);
737 reg_w(gspca_dev
->dev
, 0x00fc, &val
, 1);
739 reg_w(gspca_dev
->dev
, 0x0000, &val
, 1);
740 /* wait for completion */
743 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
744 /* 0x07 until 0x00 */
748 reg_w(gspca_dev
->dev
, 0x0053, &val
, 1);
751 PDEBUG(D_ERR
, "Damned Errors sending jpeg Table");
752 /* send the qtable now */
753 reg_r(gspca_dev
->dev
, 0x0001, &val
, 1); /* -> 0x18 */
755 for (i
= 0; i
< 18; i
++) {
758 reg_w(gspca_dev
->dev
, 0x0008, cxjpeg_qtable
[i
], length
);
761 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1); /* 0x00 */
762 reg_r(gspca_dev
->dev
, 0x0053, &val
, 1); /* 0x00 */
764 reg_w(gspca_dev
->dev
, 0x0054, &val
, 1);
766 reg_w(gspca_dev
->dev
, 0x0054, &val
, 1);
768 reg_w(gspca_dev
->dev
, 0x0000, &val
, 1);
770 reg_w(gspca_dev
->dev
, 0x0053, &val
, 1);
772 reg_r(gspca_dev
->dev
, 0x0038, &val
, 1); /* 0x40 */
773 reg_r(gspca_dev
->dev
, 0x0038, &val
, 1); /* 0x40 */
774 reg_r(gspca_dev
->dev
, 0x001f, &val
, 1); /* 0x38 */
775 reg_w(gspca_dev
->dev
, 0x0012, reg12
, 5);
776 reg_w(gspca_dev
->dev
, 0x00e5, regE5_8
, 8);
777 reg_r(gspca_dev
->dev
, 0x00e8, bufread
, 8);
778 reg_w(gspca_dev
->dev
, 0x00e5, regE5a
, 4);
779 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* 0x00 */
781 reg_w(gspca_dev
->dev
, 0x009a, &val
, 1);
782 reg_w(gspca_dev
->dev
, 0x00e5, regE5b
, 4);
783 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* 0x00 */
784 reg_w(gspca_dev
->dev
, 0x00e5, regE5c
, 4);
785 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* 0x00 */
787 reg_w(gspca_dev
->dev
, 0x0051, reg51
, 2);
788 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 2);
789 reg_w(gspca_dev
->dev
, 0x0070, ®70
, 1);
792 static void cx11646_init1(struct gspca_dev
*gspca_dev
)
798 reg_w(gspca_dev
->dev
, 0x0010, &val
, 1);
799 reg_w(gspca_dev
->dev
, 0x0053, &val
, 1);
800 reg_w(gspca_dev
->dev
, 0x0052, &val
, 1);
802 reg_w(gspca_dev
->dev
, 0x009b, &val
, 1);
804 reg_w(gspca_dev
->dev
, 0x009c, &val
, 1);
805 reg_r(gspca_dev
->dev
, 0x0098, &val
, 1);
807 reg_w(gspca_dev
->dev
, 0x0098, &val
, 1);
808 reg_r(gspca_dev
->dev
, 0x0099, &val
, 1);
810 reg_w(gspca_dev
->dev
, 0x0099, &val
, 1);
812 reg_w(gspca_dev
->dev
, 0x0039, &val
, 1);
814 reg_w(gspca_dev
->dev
, 0x003c, &val
, 1);
816 reg_w(gspca_dev
->dev
, 0x003f, &val
, 1);
818 reg_w(gspca_dev
->dev
, 0x003d, &val
, 1);
820 /* reg_w(gspca_dev->dev, 0x00, 0x00, 0x003d, &val, 1); */
821 reg_r(gspca_dev
->dev
, 0x0099, &val
, 1); /* ->0x07 */
823 while (cx_sensor_init
[i
][0]) {
824 reg_w(gspca_dev
->dev
, 0x00e5, cx_sensor_init
[i
], 1);
825 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* -> 0x00 */
828 reg_w(gspca_dev
->dev
, 0x00ed, &val
, 1);
829 reg_r(gspca_dev
->dev
, 0x00ed, &val
, 1); /* -> 0x01 */
834 reg_w(gspca_dev
->dev
, 0x00c3, &val
, 1);
837 /* this function is called at probe time */
838 static int sd_config(struct gspca_dev
*gspca_dev
,
839 const struct usb_device_id
*id
)
841 struct sd
*sd
= (struct sd
*) gspca_dev
;
844 cam
= &gspca_dev
->cam
;
845 cam
->dev_name
= (char *) id
->driver_info
;
847 cam
->cam_mode
= vga_mode
;
848 cam
->nmodes
= sizeof vga_mode
/ sizeof vga_mode
[0];
850 sd
->qindex
= 0; /* set the quantization */
851 sd
->brightness
= BRIGHTNESS_DEF
;
852 sd
->contrast
= CONTRAST_DEF
;
853 sd
->colors
= COLOR_DEF
;
857 /* this function is called at open time */
858 static int sd_open(struct gspca_dev
*gspca_dev
)
860 cx11646_init1(gspca_dev
);
861 cx11646_initsize(gspca_dev
);
862 cx11646_fw(gspca_dev
);
863 cx_sensor(gspca_dev
);
864 cx11646_jpegInit(gspca_dev
);
868 static void sd_start(struct gspca_dev
*gspca_dev
)
870 cx11646_initsize(gspca_dev
);
871 cx11646_fw(gspca_dev
);
872 cx_sensor(gspca_dev
);
873 cx11646_jpeg(gspca_dev
);
876 static void sd_stopN(struct gspca_dev
*gspca_dev
)
880 static void sd_stop0(struct gspca_dev
*gspca_dev
)
886 reg_w(gspca_dev
->dev
, 0x0000, &val
, 1);
887 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
889 reg_w(gspca_dev
->dev
, 0x0053, &val
, 1);
892 /* reg_r(gspca_dev->dev, 0x0002, &val, 1);*/
893 reg_r(gspca_dev
->dev
, 0x0053, &val
, 1);
898 reg_w(gspca_dev
->dev
, 0x0000, &val
, 1);
899 reg_r(gspca_dev
->dev
, 0x0002, &val
, 1);
902 reg_w(gspca_dev
->dev
, 0x0010, &val
, 1);
903 reg_r(gspca_dev
->dev
, 0x0033, &val
, 1);
905 reg_w(gspca_dev
->dev
, 0x00fc, &val
, 1);
908 static void sd_close(struct gspca_dev
*gspca_dev
)
912 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
913 struct gspca_frame
*frame
, /* target */
914 __u8
*data
, /* isoc packet */
915 int len
) /* iso packet length */
917 if (data
[0] == 0xff && data
[1] == 0xd8) {
920 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
923 /* put the JPEG header in the new frame */
924 jpeg_put_header(gspca_dev
, frame
,
925 ((struct sd
*) gspca_dev
)->qindex
,
930 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
933 static void setbrightness(struct gspca_dev
*gspca_dev
)
935 struct sd
*sd
= (struct sd
*) gspca_dev
;
936 __u8 regE5cbx
[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
943 bright
= sd
->brightness
;
944 regE5cbx
[2] = bright
;
945 reg_w(gspca_dev
->dev
, 0x00e5, regE5cbx
, 8);
946 reg_r(gspca_dev
->dev
, 0x00e8, bufread
, 8);
947 reg_w(gspca_dev
->dev
, 0x00e5, regE5c
, 4);
948 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* 0x00 */
953 reg_w(gspca_dev
->dev
, 0x0051, reg51c
, 2);
954 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 2);
955 reg_w(gspca_dev
->dev
, 0x0070, ®70
, 1);
958 static void setcontrast(struct gspca_dev
*gspca_dev
)
960 struct sd
*sd
= (struct sd
*) gspca_dev
;
961 __u8 regE5acx
[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
962 /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
966 regE5acx
[2] = sd
->contrast
;
967 reg_w(gspca_dev
->dev
, 0x00e5, regE5acx
, 4);
968 reg_r(gspca_dev
->dev
, 0x00e8, &val
, 1); /* 0x00 */
970 reg51c
[1] = sd
->colors
;
971 reg_w(gspca_dev
->dev
, 0x0051, reg51c
, 2);
972 reg_w(gspca_dev
->dev
, 0x0010, reg10
, 2);
973 reg_w(gspca_dev
->dev
, 0x0070, ®70
, 1);
976 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
978 struct sd
*sd
= (struct sd
*) gspca_dev
;
980 sd
->brightness
= val
;
981 if (gspca_dev
->streaming
)
982 setbrightness(gspca_dev
);
986 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
988 struct sd
*sd
= (struct sd
*) gspca_dev
;
990 *val
= sd
->brightness
;
994 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
996 struct sd
*sd
= (struct sd
*) gspca_dev
;
999 if (gspca_dev
->streaming
)
1000 setcontrast(gspca_dev
);
1004 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1006 struct sd
*sd
= (struct sd
*) gspca_dev
;
1008 *val
= sd
->contrast
;
1012 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1014 struct sd
*sd
= (struct sd
*) gspca_dev
;
1017 if (gspca_dev
->streaming
) {
1018 setbrightness(gspca_dev
);
1019 setcontrast(gspca_dev
);
1024 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1026 struct sd
*sd
= (struct sd
*) gspca_dev
;
1032 /* sub-driver description */
1033 static struct sd_desc sd_desc
= {
1034 .name
= MODULE_NAME
,
1036 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1037 .config
= sd_config
,
1043 .pkt_scan
= sd_pkt_scan
,
1046 /* -- module initialisation -- */
1047 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1048 static __devinitdata
struct usb_device_id device_table
[] = {
1049 {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
1052 MODULE_DEVICE_TABLE(usb
, device_table
);
1054 /* -- device connect -- */
1055 static int sd_probe(struct usb_interface
*intf
,
1056 const struct usb_device_id
*id
)
1058 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1062 static struct usb_driver sd_driver
= {
1063 .name
= MODULE_NAME
,
1064 .id_table
= device_table
,
1066 .disconnect
= gspca_disconnect
,
1069 /* -- module insert / remove -- */
1070 static int __init
sd_mod_init(void)
1072 if (usb_register(&sd_driver
) < 0)
1074 PDEBUG(D_PROBE
, "v%s registered", version
);
1077 static void __exit
sd_mod_exit(void)
1079 usb_deregister(&sd_driver
);
1080 PDEBUG(D_PROBE
, "deregistered");
1083 module_init(sd_mod_init
);
1084 module_exit(sd_mod_exit
);