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 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
30 MODULE_LICENSE("GPL");
32 /* specific webcam descriptor */
34 struct gspca_dev gspca_dev
; /* !! must be the first item */
36 unsigned char brightness
;
37 unsigned char contrast
;
40 #define QUALITY_MIN 30
41 #define QUALITY_MAX 60
42 #define QUALITY_DEF 40
47 /* V4L2 controls supported by the driver */
48 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
49 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
50 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
51 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
52 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
53 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
55 static struct ctrl sd_ctrls
[] = {
58 .id
= V4L2_CID_BRIGHTNESS
,
59 .type
= V4L2_CTRL_TYPE_INTEGER
,
64 #define BRIGHTNESS_DEF 0xd4
65 .default_value
= BRIGHTNESS_DEF
,
67 .set
= sd_setbrightness
,
68 .get
= sd_getbrightness
,
72 .id
= V4L2_CID_CONTRAST
,
73 .type
= V4L2_CTRL_TYPE_INTEGER
,
78 #define CONTRAST_DEF 0x0c
79 .default_value
= CONTRAST_DEF
,
81 .set
= sd_setcontrast
,
82 .get
= sd_getcontrast
,
86 .id
= V4L2_CID_SATURATION
,
87 .type
= V4L2_CTRL_TYPE_INTEGER
,
93 .default_value
= COLOR_DEF
,
100 static const struct v4l2_pix_format vga_mode
[] = {
101 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
103 .sizeimage
= 176 * 144 * 3 / 8 + 590,
104 .colorspace
= V4L2_COLORSPACE_JPEG
,
106 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
108 .sizeimage
= 320 * 240 * 3 / 8 + 590,
109 .colorspace
= V4L2_COLORSPACE_JPEG
,
111 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
113 .sizeimage
= 352 * 288 * 3 / 8 + 590,
114 .colorspace
= V4L2_COLORSPACE_JPEG
,
116 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
118 .sizeimage
= 640 * 480 * 3 / 8 + 590,
119 .colorspace
= V4L2_COLORSPACE_JPEG
,
123 /* the read bytes are found in gspca_dev->usb_buf */
124 static void reg_r(struct gspca_dev
*gspca_dev
,
128 struct usb_device
*dev
= gspca_dev
->dev
;
131 if (len
> USB_BUF_SZ
) {
132 err("reg_r: buffer overflow");
137 usb_rcvctrlpipe(dev
, 0),
139 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
141 index
, gspca_dev
->usb_buf
, len
,
143 PDEBUG(D_USBI
, "reg read [%02x] -> %02x ..",
144 index
, gspca_dev
->usb_buf
[0]);
147 /* the bytes to write are in gspca_dev->usb_buf */
148 static void reg_w_val(struct gspca_dev
*gspca_dev
,
152 struct usb_device
*dev
= gspca_dev
->dev
;
154 gspca_dev
->usb_buf
[0] = val
;
156 usb_sndctrlpipe(dev
, 0),
158 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
160 index
, gspca_dev
->usb_buf
, 1, 500);
163 static void reg_w(struct gspca_dev
*gspca_dev
,
168 struct usb_device
*dev
= gspca_dev
->dev
;
171 if (len
> USB_BUF_SZ
) {
172 err("reg_w: buffer overflow");
175 PDEBUG(D_USBO
, "reg write [%02x] = %02x..", index
, *buffer
);
177 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
179 usb_sndctrlpipe(dev
, 0),
181 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
183 index
, gspca_dev
->usb_buf
, len
, 500);
186 static const __u8 cx_sensor_init
[][4] = {
187 {0x88, 0x11, 0x01, 0x01},
188 {0x88, 0x12, 0x70, 0x01},
189 {0x88, 0x0f, 0x00, 0x01},
190 {0x88, 0x05, 0x01, 0x01},
194 static const __u8 cx11646_fw1
[][3] = {
261 static void cx11646_fw(struct gspca_dev
*gspca_dev
)
265 reg_w_val(gspca_dev
, 0x006a, 0x02);
266 while (cx11646_fw1
[i
][1]) {
267 reg_w(gspca_dev
, 0x006b, cx11646_fw1
[i
], 3);
270 reg_w_val(gspca_dev
, 0x006a, 0x00);
273 static const __u8 cxsensor
[] = {
274 0x88, 0x12, 0x70, 0x01,
275 0x88, 0x0d, 0x02, 0x01,
276 0x88, 0x0f, 0x00, 0x01,
277 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
278 0x88, 0x02, 0x10, 0x01,
279 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
280 0x88, 0x0B, 0x00, 0x01,
281 0x88, 0x0A, 0x0A, 0x01,
282 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
283 0x88, 0x05, 0x01, 0x01,
284 0xA1, 0x18, 0x00, 0x01,
288 static const __u8 reg20
[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
289 static const __u8 reg28
[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
290 static const __u8 reg10
[] = { 0xb1, 0xb1 };
291 static const __u8 reg71a
[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
292 static const __u8 reg71b
[] = { 0x04, 0x0c, 0x05, 0x0f };
293 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
294 static const __u8 reg71c
[] = { 0x02, 0x07, 0x03, 0x09 };
295 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
296 static const __u8 reg71d
[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
297 static const __u8 reg7b
[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
299 static void cx_sensor(struct gspca_dev
*gspca_dev
)
303 const __u8
*ptsensor
= cxsensor
;
305 reg_w(gspca_dev
, 0x0020, reg20
, 8);
306 reg_w(gspca_dev
, 0x0028, reg28
, 8);
307 reg_w(gspca_dev
, 0x0010, reg10
, 8);
308 reg_w_val(gspca_dev
, 0x0092, 0x03);
310 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
312 reg_w(gspca_dev
, 0x0071, reg71a
, 4);
315 reg_w(gspca_dev
, 0x0071, reg71b
, 4);
319 reg_w(gspca_dev
, 0x0071, reg71c
, 4);
322 reg_w(gspca_dev
, 0x0071, reg71d
, 4);
325 reg_w(gspca_dev
, 0x007b, reg7b
, 6);
326 reg_w_val(gspca_dev
, 0x00f8, 0x00);
327 reg_w(gspca_dev
, 0x0010, reg10
, 8);
328 reg_w_val(gspca_dev
, 0x0098, 0x41);
329 for (i
= 0; i
< 11; i
++) {
330 if (i
== 3 || i
== 5 || i
== 8)
334 reg_w(gspca_dev
, 0x00e5, ptsensor
, length
);
336 reg_r(gspca_dev
, 0x00e8, 1);
338 reg_r(gspca_dev
, 0x00e8, length
);
341 reg_r(gspca_dev
, 0x00e7, 8);
344 static const __u8 cx_inits_176
[] = {
345 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
346 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
347 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
348 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
349 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
350 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
351 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
353 static const __u8 cx_inits_320
[] = {
354 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
355 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
356 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
357 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
358 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
359 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
360 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
362 static const __u8 cx_inits_352
[] = {
363 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
364 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
365 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
366 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
367 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
368 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
369 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
371 static const __u8 cx_inits_640
[] = {
372 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
373 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
374 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
375 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
376 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
377 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
378 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
381 static void cx11646_initsize(struct gspca_dev
*gspca_dev
)
384 static const __u8 reg12
[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
385 static const __u8 reg17
[] =
386 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
388 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
390 cxinit
= cx_inits_640
;
393 cxinit
= cx_inits_352
;
397 cxinit
= cx_inits_320
;
400 cxinit
= cx_inits_176
;
403 reg_w_val(gspca_dev
, 0x009a, 0x01);
404 reg_w_val(gspca_dev
, 0x0010, 0x10);
405 reg_w(gspca_dev
, 0x0012, reg12
, 5);
406 reg_w(gspca_dev
, 0x0017, reg17
, 8);
407 reg_w_val(gspca_dev
, 0x00c0, 0x00);
408 reg_w_val(gspca_dev
, 0x00c1, 0x04);
409 reg_w_val(gspca_dev
, 0x00c2, 0x04);
411 reg_w(gspca_dev
, 0x0061, cxinit
, 8);
413 reg_w(gspca_dev
, 0x00ca, cxinit
, 8);
415 reg_w(gspca_dev
, 0x00d2, cxinit
, 8);
417 reg_w(gspca_dev
, 0x00da, cxinit
, 6);
419 reg_w(gspca_dev
, 0x0041, cxinit
, 8);
421 reg_w(gspca_dev
, 0x0049, cxinit
, 8);
423 reg_w(gspca_dev
, 0x0051, cxinit
, 2);
425 reg_r(gspca_dev
, 0x0010, 1);
428 static const __u8 cx_jpeg_init
[][8] = {
429 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
430 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
431 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
432 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
433 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
434 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
435 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
436 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
437 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
438 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
439 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
440 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
441 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
442 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
443 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
444 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
445 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
446 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
447 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
448 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
449 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
450 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
451 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
452 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
453 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
454 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
455 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
456 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
457 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
458 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
459 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
460 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
461 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
462 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
463 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
464 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
465 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
466 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
467 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
468 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
469 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
470 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
471 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
472 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
473 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
474 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
475 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
476 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
477 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
478 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
479 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
480 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
481 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
482 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
483 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
484 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
485 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
486 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
487 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
488 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
489 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
490 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
491 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
492 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
493 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
494 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
495 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
496 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
497 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
498 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
499 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
500 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
501 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
502 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
503 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
504 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
505 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
506 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
507 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
511 static const __u8 cxjpeg_640
[][8] = {
512 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
513 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
514 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
515 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
516 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
517 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
518 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
519 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
520 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
521 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
522 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
523 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
524 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
525 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
526 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
527 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
528 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
529 {0xFF, 0x20, 0x00, 0x1F, 0x00, 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, 0x28, 0xFF},
534 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
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} /* 27 */
540 static const __u8 cxjpeg_352
[][8] = {
541 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
542 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
543 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
544 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
545 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
546 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
547 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
548 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
549 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
550 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
551 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
552 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
553 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
554 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
555 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
556 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
557 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
558 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 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, 0x16, 0xFF},
563 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
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}
569 static const __u8 cxjpeg_320
[][8] = {
570 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
571 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
572 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
573 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
574 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
575 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
576 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
577 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
578 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
579 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
580 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
581 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
582 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
583 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
584 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
585 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
586 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
587 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 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, 0x14, 0xFF},
592 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
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} /* 27 */
598 static const __u8 cxjpeg_176
[][8] = {
599 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
600 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
601 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
602 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
603 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
604 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
605 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
606 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
607 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
608 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
609 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
610 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
611 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
612 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
613 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
614 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
615 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
616 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
617 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
618 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
619 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
620 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
621 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
622 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
623 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
624 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
625 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
627 /* 640 take with the zcx30x part */
628 static const __u8 cxjpeg_qtable
[][8] = {
629 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
630 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
631 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
632 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
633 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
634 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
635 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
636 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
637 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
638 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
639 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
640 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
641 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
642 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
643 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
644 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
645 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
646 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
650 static void cx11646_jpegInit(struct gspca_dev
*gspca_dev
)
655 reg_w_val(gspca_dev
, 0x00c0, 0x01);
656 reg_w_val(gspca_dev
, 0x00c3, 0x00);
657 reg_w_val(gspca_dev
, 0x00c0, 0x00);
658 reg_r(gspca_dev
, 0x0001, 1);
660 for (i
= 0; i
< 79; i
++) {
663 reg_w(gspca_dev
, 0x0008, cx_jpeg_init
[i
], length
);
665 reg_r(gspca_dev
, 0x0002, 1);
666 reg_w_val(gspca_dev
, 0x0055, 0x14);
669 static const __u8 reg12
[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
670 static const __u8 regE5_8
[] =
671 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
672 static const __u8 regE5a
[] = { 0x88, 0x0a, 0x0c, 0x01 };
673 static const __u8 regE5b
[] = { 0x88, 0x0b, 0x12, 0x01 };
674 static const __u8 regE5c
[] = { 0x88, 0x05, 0x01, 0x01 };
675 static const __u8 reg51
[] = { 0x77, 0x03 };
678 static void cx11646_jpeg(struct gspca_dev
*gspca_dev
)
685 reg_w_val(gspca_dev
, 0x00c0, 0x01);
686 reg_w_val(gspca_dev
, 0x00c3, 0x00);
687 reg_w_val(gspca_dev
, 0x00c0, 0x00);
688 reg_r(gspca_dev
, 0x0001, 1);
690 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
692 for (i
= 0; i
< 27; i
++) {
695 reg_w(gspca_dev
, 0x0008, cxjpeg_640
[i
], length
);
700 for (i
= 0; i
< 27; i
++) {
703 reg_w(gspca_dev
, 0x0008, cxjpeg_352
[i
], length
);
709 for (i
= 0; i
< 27; i
++) {
712 reg_w(gspca_dev
, 0x0008, cxjpeg_320
[i
], length
);
717 for (i
= 0; i
< 27; i
++) {
720 reg_w(gspca_dev
, 0x0008, cxjpeg_176
[i
], length
);
726 reg_r(gspca_dev
, 0x0002, 1);
727 reg_w_val(gspca_dev
, 0x0055, Reg55
);
728 reg_r(gspca_dev
, 0x0002, 1);
729 reg_w(gspca_dev
, 0x0010, reg10
, 2);
730 reg_w_val(gspca_dev
, 0x0054, 0x02);
731 reg_w_val(gspca_dev
, 0x0054, 0x01);
732 reg_w_val(gspca_dev
, 0x0000, 0x94);
733 reg_w_val(gspca_dev
, 0x0053, 0xc0);
734 reg_w_val(gspca_dev
, 0x00fc, 0xe1);
735 reg_w_val(gspca_dev
, 0x0000, 0x00);
736 /* wait for completion */
739 reg_r(gspca_dev
, 0x0002, 1);
740 /* 0x07 until 0x00 */
741 if (gspca_dev
->usb_buf
[0] == 0x00)
743 reg_w_val(gspca_dev
, 0x0053, 0x00);
746 PDEBUG(D_ERR
, "Damned Errors sending jpeg Table");
747 /* send the qtable now */
748 reg_r(gspca_dev
, 0x0001, 1); /* -> 0x18 */
750 for (i
= 0; i
< 18; i
++) {
753 reg_w(gspca_dev
, 0x0008, cxjpeg_qtable
[i
], length
);
756 reg_r(gspca_dev
, 0x0002, 1); /* 0x00 */
757 reg_r(gspca_dev
, 0x0053, 1); /* 0x00 */
758 reg_w_val(gspca_dev
, 0x0054, 0x02);
759 reg_w_val(gspca_dev
, 0x0054, 0x01);
760 reg_w_val(gspca_dev
, 0x0000, 0x94);
761 reg_w_val(gspca_dev
, 0x0053, 0xc0);
763 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
764 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
765 reg_r(gspca_dev
, 0x001f, 1); /* 0x38 */
766 reg_w(gspca_dev
, 0x0012, reg12
, 5);
767 reg_w(gspca_dev
, 0x00e5, regE5_8
, 8);
768 reg_r(gspca_dev
, 0x00e8, 8);
769 reg_w(gspca_dev
, 0x00e5, regE5a
, 4);
770 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
771 reg_w_val(gspca_dev
, 0x009a, 0x01);
772 reg_w(gspca_dev
, 0x00e5, regE5b
, 4);
773 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
774 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
775 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
777 reg_w(gspca_dev
, 0x0051, reg51
, 2);
778 reg_w(gspca_dev
, 0x0010, reg10
, 2);
779 reg_w_val(gspca_dev
, 0x0070, reg70
);
782 static void cx11646_init1(struct gspca_dev
*gspca_dev
)
786 reg_w_val(gspca_dev
, 0x0010, 0x00);
787 reg_w_val(gspca_dev
, 0x0053, 0x00);
788 reg_w_val(gspca_dev
, 0x0052, 0x00);
789 reg_w_val(gspca_dev
, 0x009b, 0x2f);
790 reg_w_val(gspca_dev
, 0x009c, 0x10);
791 reg_r(gspca_dev
, 0x0098, 1);
792 reg_w_val(gspca_dev
, 0x0098, 0x40);
793 reg_r(gspca_dev
, 0x0099, 1);
794 reg_w_val(gspca_dev
, 0x0099, 0x07);
795 reg_w_val(gspca_dev
, 0x0039, 0x40);
796 reg_w_val(gspca_dev
, 0x003c, 0xff);
797 reg_w_val(gspca_dev
, 0x003f, 0x1f);
798 reg_w_val(gspca_dev
, 0x003d, 0x40);
799 /* reg_w_val(gspca_dev, 0x003d, 0x60); */
800 reg_r(gspca_dev
, 0x0099, 1); /* ->0x07 */
802 while (cx_sensor_init
[i
][0]) {
803 reg_w_val(gspca_dev
, 0x00e5, cx_sensor_init
[i
][0]);
804 reg_r(gspca_dev
, 0x00e8, 1); /* -> 0x00 */
806 reg_w_val(gspca_dev
, 0x00ed, 0x01);
807 reg_r(gspca_dev
, 0x00ed, 1); /* -> 0x01 */
811 reg_w_val(gspca_dev
, 0x00c3, 0x00);
814 /* this function is called at probe time */
815 static int sd_config(struct gspca_dev
*gspca_dev
,
816 const struct usb_device_id
*id
)
818 struct sd
*sd
= (struct sd
*) gspca_dev
;
821 cam
= &gspca_dev
->cam
;
822 cam
->cam_mode
= vga_mode
;
823 cam
->nmodes
= sizeof vga_mode
/ sizeof vga_mode
[0];
825 sd
->brightness
= BRIGHTNESS_DEF
;
826 sd
->contrast
= CONTRAST_DEF
;
827 sd
->colors
= COLOR_DEF
;
828 sd
->quality
= QUALITY_DEF
;
832 /* this function is called at probe and resume time */
833 static int sd_init(struct gspca_dev
*gspca_dev
)
835 cx11646_init1(gspca_dev
);
836 cx11646_initsize(gspca_dev
);
837 cx11646_fw(gspca_dev
);
838 cx_sensor(gspca_dev
);
839 cx11646_jpegInit(gspca_dev
);
843 static int sd_start(struct gspca_dev
*gspca_dev
)
845 struct sd
*sd
= (struct sd
*) gspca_dev
;
847 /* create the JPEG header */
848 sd
->jpeg_hdr
= kmalloc(JPEG_HDR_SZ
, GFP_KERNEL
);
851 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->height
, gspca_dev
->width
,
852 0x22); /* JPEG 411 */
853 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
855 cx11646_initsize(gspca_dev
);
856 cx11646_fw(gspca_dev
);
857 cx_sensor(gspca_dev
);
858 cx11646_jpeg(gspca_dev
);
862 /* called on streamoff with alt 0 and on disconnect */
863 static void sd_stop0(struct gspca_dev
*gspca_dev
)
865 struct sd
*sd
= (struct sd
*) gspca_dev
;
870 if (!gspca_dev
->present
)
872 reg_w_val(gspca_dev
, 0x0000, 0x00);
873 reg_r(gspca_dev
, 0x0002, 1);
874 reg_w_val(gspca_dev
, 0x0053, 0x00);
877 /* reg_r(gspca_dev, 0x0002, 1);*/
878 reg_r(gspca_dev
, 0x0053, 1);
879 if (gspca_dev
->usb_buf
[0] == 0)
882 reg_w_val(gspca_dev
, 0x0000, 0x00);
883 reg_r(gspca_dev
, 0x0002, 1);
885 reg_w_val(gspca_dev
, 0x0010, 0x00);
886 reg_r(gspca_dev
, 0x0033, 1);
887 reg_w_val(gspca_dev
, 0x00fc, 0xe0);
890 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
891 struct gspca_frame
*frame
, /* target */
892 __u8
*data
, /* isoc packet */
893 int len
) /* iso packet length */
895 struct sd
*sd
= (struct sd
*) gspca_dev
;
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 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
905 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
909 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
912 static void setbrightness(struct gspca_dev
*gspca_dev
)
914 struct sd
*sd
= (struct sd
*) gspca_dev
;
915 __u8 regE5cbx
[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
920 bright
= sd
->brightness
;
921 regE5cbx
[2] = bright
;
922 reg_w(gspca_dev
, 0x00e5, regE5cbx
, 8);
923 reg_r(gspca_dev
, 0x00e8, 8);
924 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
925 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
930 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
931 reg_w(gspca_dev
, 0x0010, reg10
, 2);
932 reg_w_val(gspca_dev
, 0x0070, reg70
);
935 static void setcontrast(struct gspca_dev
*gspca_dev
)
937 struct sd
*sd
= (struct sd
*) gspca_dev
;
938 __u8 regE5acx
[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
939 /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
942 regE5acx
[2] = sd
->contrast
;
943 reg_w(gspca_dev
, 0x00e5, regE5acx
, 4);
944 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
946 reg51c
[1] = sd
->colors
;
947 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
948 reg_w(gspca_dev
, 0x0010, reg10
, 2);
949 reg_w_val(gspca_dev
, 0x0070, reg70
);
952 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
954 struct sd
*sd
= (struct sd
*) gspca_dev
;
956 sd
->brightness
= val
;
957 if (gspca_dev
->streaming
)
958 setbrightness(gspca_dev
);
962 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
964 struct sd
*sd
= (struct sd
*) gspca_dev
;
966 *val
= sd
->brightness
;
970 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
972 struct sd
*sd
= (struct sd
*) gspca_dev
;
975 if (gspca_dev
->streaming
)
976 setcontrast(gspca_dev
);
980 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
982 struct sd
*sd
= (struct sd
*) gspca_dev
;
988 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
990 struct sd
*sd
= (struct sd
*) gspca_dev
;
993 if (gspca_dev
->streaming
) {
994 setbrightness(gspca_dev
);
995 setcontrast(gspca_dev
);
1000 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1002 struct sd
*sd
= (struct sd
*) gspca_dev
;
1008 static int sd_set_jcomp(struct gspca_dev
*gspca_dev
,
1009 struct v4l2_jpegcompression
*jcomp
)
1011 struct sd
*sd
= (struct sd
*) gspca_dev
;
1013 if (jcomp
->quality
< QUALITY_MIN
)
1014 sd
->quality
= QUALITY_MIN
;
1015 else if (jcomp
->quality
> QUALITY_MAX
)
1016 sd
->quality
= QUALITY_MAX
;
1018 sd
->quality
= jcomp
->quality
;
1019 if (gspca_dev
->streaming
)
1020 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
1024 static int sd_get_jcomp(struct gspca_dev
*gspca_dev
,
1025 struct v4l2_jpegcompression
*jcomp
)
1027 struct sd
*sd
= (struct sd
*) gspca_dev
;
1029 memset(jcomp
, 0, sizeof *jcomp
);
1030 jcomp
->quality
= sd
->quality
;
1031 jcomp
->jpeg_markers
= V4L2_JPEG_MARKER_DHT
1032 | V4L2_JPEG_MARKER_DQT
;
1036 /* sub-driver description */
1037 static struct sd_desc sd_desc
= {
1038 .name
= MODULE_NAME
,
1040 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1041 .config
= sd_config
,
1045 .pkt_scan
= sd_pkt_scan
,
1046 .get_jcomp
= sd_get_jcomp
,
1047 .set_jcomp
= sd_set_jcomp
,
1050 /* -- module initialisation -- */
1051 static __devinitdata
struct usb_device_id device_table
[] = {
1052 {USB_DEVICE(0x0572, 0x0041)},
1055 MODULE_DEVICE_TABLE(usb
, device_table
);
1057 /* -- device connect -- */
1058 static int sd_probe(struct usb_interface
*intf
,
1059 const struct usb_device_id
*id
)
1061 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1065 static struct usb_driver sd_driver
= {
1066 .name
= MODULE_NAME
,
1067 .id_table
= device_table
,
1069 .disconnect
= gspca_disconnect
,
1071 .suspend
= gspca_suspend
,
1072 .resume
= gspca_resume
,
1076 /* -- module insert / remove -- */
1077 static int __init
sd_mod_init(void)
1080 ret
= usb_register(&sd_driver
);
1083 PDEBUG(D_PROBE
, "registered");
1086 static void __exit
sd_mod_exit(void)
1088 usb_deregister(&sd_driver
);
1089 PDEBUG(D_PROBE
, "deregistered");
1092 module_init(sd_mod_init
);
1093 module_exit(sd_mod_exit
);