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.
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 #define MODULE_NAME "conex"
23 #define CONEX_CAM 1 /* special JPEG header */
26 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
27 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
28 MODULE_LICENSE("GPL");
32 /* specific webcam descriptor */
34 struct gspca_dev gspca_dev
; /* !! must be the first item */
35 struct v4l2_ctrl
*brightness
;
36 struct v4l2_ctrl
*contrast
;
37 struct v4l2_ctrl
*sat
;
39 u8 jpeg_hdr
[JPEG_HDR_SZ
];
42 static const struct v4l2_pix_format vga_mode
[] = {
43 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
45 .sizeimage
= 176 * 144 * 3 / 8 + 590,
46 .colorspace
= V4L2_COLORSPACE_JPEG
,
48 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
50 .sizeimage
= 320 * 240 * 3 / 8 + 590,
51 .colorspace
= V4L2_COLORSPACE_JPEG
,
53 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
55 .sizeimage
= 352 * 288 * 3 / 8 + 590,
56 .colorspace
= V4L2_COLORSPACE_JPEG
,
58 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
60 .sizeimage
= 640 * 480 * 3 / 8 + 590,
61 .colorspace
= V4L2_COLORSPACE_JPEG
,
65 /* the read bytes are found in gspca_dev->usb_buf */
66 static void reg_r(struct gspca_dev
*gspca_dev
,
70 struct usb_device
*dev
= gspca_dev
->dev
;
72 if (len
> USB_BUF_SZ
) {
73 gspca_err(gspca_dev
, "reg_r: buffer overflow\n");
78 usb_rcvctrlpipe(dev
, 0),
80 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
82 index
, gspca_dev
->usb_buf
, len
,
84 gspca_dbg(gspca_dev
, D_USBI
, "reg read [%02x] -> %02x ..\n",
85 index
, gspca_dev
->usb_buf
[0]);
88 /* the bytes to write are in gspca_dev->usb_buf */
89 static void reg_w_val(struct gspca_dev
*gspca_dev
,
93 struct usb_device
*dev
= gspca_dev
->dev
;
95 gspca_dev
->usb_buf
[0] = val
;
97 usb_sndctrlpipe(dev
, 0),
99 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
101 index
, gspca_dev
->usb_buf
, 1, 500);
104 static void reg_w(struct gspca_dev
*gspca_dev
,
109 struct usb_device
*dev
= gspca_dev
->dev
;
111 if (len
> USB_BUF_SZ
) {
112 gspca_err(gspca_dev
, "reg_w: buffer overflow\n");
115 gspca_dbg(gspca_dev
, D_USBO
, "reg write [%02x] = %02x..\n",
118 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
120 usb_sndctrlpipe(dev
, 0),
122 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
124 index
, gspca_dev
->usb_buf
, len
, 500);
127 static const __u8 cx_sensor_init
[][4] = {
128 {0x88, 0x11, 0x01, 0x01},
129 {0x88, 0x12, 0x70, 0x01},
130 {0x88, 0x0f, 0x00, 0x01},
131 {0x88, 0x05, 0x01, 0x01},
135 static const __u8 cx11646_fw1
[][3] = {
202 static void cx11646_fw(struct gspca_dev
*gspca_dev
)
206 reg_w_val(gspca_dev
, 0x006a, 0x02);
207 while (cx11646_fw1
[i
][1]) {
208 reg_w(gspca_dev
, 0x006b, cx11646_fw1
[i
], 3);
211 reg_w_val(gspca_dev
, 0x006a, 0x00);
214 static const __u8 cxsensor
[] = {
215 0x88, 0x12, 0x70, 0x01,
216 0x88, 0x0d, 0x02, 0x01,
217 0x88, 0x0f, 0x00, 0x01,
218 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
219 0x88, 0x02, 0x10, 0x01,
220 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
221 0x88, 0x0B, 0x00, 0x01,
222 0x88, 0x0A, 0x0A, 0x01,
223 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
224 0x88, 0x05, 0x01, 0x01,
225 0xA1, 0x18, 0x00, 0x01,
229 static const __u8 reg20
[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
230 static const __u8 reg28
[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
231 static const __u8 reg10
[] = { 0xb1, 0xb1 };
232 static const __u8 reg71a
[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
233 static const __u8 reg71b
[] = { 0x04, 0x0c, 0x05, 0x0f };
234 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
235 static const __u8 reg71c
[] = { 0x02, 0x07, 0x03, 0x09 };
236 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
237 static const __u8 reg71d
[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
238 static const __u8 reg7b
[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
240 static void cx_sensor(struct gspca_dev
*gspca_dev
)
244 const __u8
*ptsensor
= cxsensor
;
246 reg_w(gspca_dev
, 0x0020, reg20
, 8);
247 reg_w(gspca_dev
, 0x0028, reg28
, 8);
248 reg_w(gspca_dev
, 0x0010, reg10
, 2);
249 reg_w_val(gspca_dev
, 0x0092, 0x03);
251 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
253 reg_w(gspca_dev
, 0x0071, reg71a
, 4);
256 reg_w(gspca_dev
, 0x0071, reg71b
, 4);
260 reg_w(gspca_dev
, 0x0071, reg71c
, 4);
263 reg_w(gspca_dev
, 0x0071, reg71d
, 4);
266 reg_w(gspca_dev
, 0x007b, reg7b
, 6);
267 reg_w_val(gspca_dev
, 0x00f8, 0x00);
268 reg_w(gspca_dev
, 0x0010, reg10
, 2);
269 reg_w_val(gspca_dev
, 0x0098, 0x41);
270 for (i
= 0; i
< 11; i
++) {
271 if (i
== 3 || i
== 5 || i
== 8)
275 reg_w(gspca_dev
, 0x00e5, ptsensor
, length
);
277 reg_r(gspca_dev
, 0x00e8, 1);
279 reg_r(gspca_dev
, 0x00e8, length
);
282 reg_r(gspca_dev
, 0x00e7, 8);
285 static const __u8 cx_inits_176
[] = {
286 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
287 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
288 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
289 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
290 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
291 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
292 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
294 static const __u8 cx_inits_320
[] = {
295 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
296 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
297 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
298 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
299 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
300 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
301 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
303 static const __u8 cx_inits_352
[] = {
304 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
305 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
306 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
307 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
308 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
309 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
310 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
312 static const __u8 cx_inits_640
[] = {
313 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
314 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
315 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
316 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
317 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
318 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
319 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
322 static void cx11646_initsize(struct gspca_dev
*gspca_dev
)
325 static const __u8 reg12
[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
326 static const __u8 reg17
[] =
327 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
329 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
331 cxinit
= cx_inits_640
;
334 cxinit
= cx_inits_352
;
338 cxinit
= cx_inits_320
;
341 cxinit
= cx_inits_176
;
344 reg_w_val(gspca_dev
, 0x009a, 0x01);
345 reg_w_val(gspca_dev
, 0x0010, 0x10);
346 reg_w(gspca_dev
, 0x0012, reg12
, 5);
347 reg_w(gspca_dev
, 0x0017, reg17
, 8);
348 reg_w_val(gspca_dev
, 0x00c0, 0x00);
349 reg_w_val(gspca_dev
, 0x00c1, 0x04);
350 reg_w_val(gspca_dev
, 0x00c2, 0x04);
352 reg_w(gspca_dev
, 0x0061, cxinit
, 8);
354 reg_w(gspca_dev
, 0x00ca, cxinit
, 8);
356 reg_w(gspca_dev
, 0x00d2, cxinit
, 8);
358 reg_w(gspca_dev
, 0x00da, cxinit
, 6);
360 reg_w(gspca_dev
, 0x0041, cxinit
, 8);
362 reg_w(gspca_dev
, 0x0049, cxinit
, 8);
364 reg_w(gspca_dev
, 0x0051, cxinit
, 2);
366 reg_r(gspca_dev
, 0x0010, 1);
369 static const __u8 cx_jpeg_init
[][8] = {
370 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
371 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
372 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
373 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
374 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
375 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
376 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
377 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
378 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
379 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
380 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
381 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
382 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
383 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
384 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
385 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
386 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
387 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
388 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
389 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
390 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
391 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
392 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
393 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
394 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
395 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
396 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
397 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
398 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
399 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
400 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
401 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
402 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
403 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
404 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
405 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
406 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
407 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
408 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
409 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
410 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
411 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
412 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
413 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
414 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
415 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
416 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
417 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
418 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
419 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
420 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
421 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
422 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
423 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
424 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
425 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
426 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
427 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
428 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
429 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
430 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
431 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
432 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
433 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
434 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
435 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
436 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
437 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
438 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
439 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
440 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
441 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
442 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
443 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
444 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
445 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
446 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
447 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
448 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
452 static const __u8 cxjpeg_640
[][8] = {
453 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
454 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
455 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
456 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
457 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
458 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
459 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
460 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
461 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
462 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
463 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
464 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
465 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
466 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
467 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
468 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
469 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
470 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
471 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
472 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
473 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
474 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
475 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
476 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
477 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
478 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
479 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
481 static const __u8 cxjpeg_352
[][8] = {
482 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
483 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
484 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
485 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
486 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
487 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
488 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
489 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
490 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
491 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
492 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
493 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
494 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
495 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
496 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
497 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
498 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
499 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
500 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
501 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
502 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
503 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
504 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
505 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
506 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
507 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
508 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
510 static const __u8 cxjpeg_320
[][8] = {
511 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
512 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
513 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
514 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
515 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
516 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
517 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
518 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
519 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
520 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
521 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
522 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
523 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
524 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
525 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
526 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
527 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
528 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
529 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
530 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
531 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
532 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
533 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
534 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
535 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
536 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
537 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
539 static const __u8 cxjpeg_176
[][8] = {
540 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
541 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
542 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
543 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
544 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
545 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
546 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
547 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
548 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
549 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
550 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
551 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
552 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
553 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
554 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
555 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
556 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
557 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
558 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
559 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
560 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
561 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
562 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
563 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
564 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
565 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
566 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
568 /* 640 take with the zcx30x part */
569 static const __u8 cxjpeg_qtable
[][8] = {
570 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
571 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
572 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
573 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
574 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
575 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
576 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
577 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
578 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
579 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
580 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
581 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
582 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
583 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
584 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
585 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
586 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
587 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
591 static void cx11646_jpegInit(struct gspca_dev
*gspca_dev
)
596 reg_w_val(gspca_dev
, 0x00c0, 0x01);
597 reg_w_val(gspca_dev
, 0x00c3, 0x00);
598 reg_w_val(gspca_dev
, 0x00c0, 0x00);
599 reg_r(gspca_dev
, 0x0001, 1);
601 for (i
= 0; i
< 79; i
++) {
604 reg_w(gspca_dev
, 0x0008, cx_jpeg_init
[i
], length
);
606 reg_r(gspca_dev
, 0x0002, 1);
607 reg_w_val(gspca_dev
, 0x0055, 0x14);
610 static const __u8 reg12
[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
611 static const __u8 regE5_8
[] =
612 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
613 static const __u8 regE5a
[] = { 0x88, 0x0a, 0x0c, 0x01 };
614 static const __u8 regE5b
[] = { 0x88, 0x0b, 0x12, 0x01 };
615 static const __u8 regE5c
[] = { 0x88, 0x05, 0x01, 0x01 };
616 static const __u8 reg51
[] = { 0x77, 0x03 };
619 static void cx11646_jpeg(struct gspca_dev
*gspca_dev
)
626 reg_w_val(gspca_dev
, 0x00c0, 0x01);
627 reg_w_val(gspca_dev
, 0x00c3, 0x00);
628 reg_w_val(gspca_dev
, 0x00c0, 0x00);
629 reg_r(gspca_dev
, 0x0001, 1);
631 switch (gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
) {
633 for (i
= 0; i
< 27; i
++) {
636 reg_w(gspca_dev
, 0x0008, cxjpeg_640
[i
], length
);
641 for (i
= 0; i
< 27; i
++) {
644 reg_w(gspca_dev
, 0x0008, cxjpeg_352
[i
], length
);
650 for (i
= 0; i
< 27; i
++) {
653 reg_w(gspca_dev
, 0x0008, cxjpeg_320
[i
], length
);
658 for (i
= 0; i
< 27; i
++) {
661 reg_w(gspca_dev
, 0x0008, cxjpeg_176
[i
], length
);
667 reg_r(gspca_dev
, 0x0002, 1);
668 reg_w_val(gspca_dev
, 0x0055, Reg55
);
669 reg_r(gspca_dev
, 0x0002, 1);
670 reg_w(gspca_dev
, 0x0010, reg10
, 2);
671 reg_w_val(gspca_dev
, 0x0054, 0x02);
672 reg_w_val(gspca_dev
, 0x0054, 0x01);
673 reg_w_val(gspca_dev
, 0x0000, 0x94);
674 reg_w_val(gspca_dev
, 0x0053, 0xc0);
675 reg_w_val(gspca_dev
, 0x00fc, 0xe1);
676 reg_w_val(gspca_dev
, 0x0000, 0x00);
677 /* wait for completion */
680 reg_r(gspca_dev
, 0x0002, 1);
681 /* 0x07 until 0x00 */
682 if (gspca_dev
->usb_buf
[0] == 0x00)
684 reg_w_val(gspca_dev
, 0x0053, 0x00);
687 gspca_err(gspca_dev
, "Damned Errors sending jpeg Table\n");
688 /* send the qtable now */
689 reg_r(gspca_dev
, 0x0001, 1); /* -> 0x18 */
691 for (i
= 0; i
< 18; i
++) {
694 reg_w(gspca_dev
, 0x0008, cxjpeg_qtable
[i
], length
);
697 reg_r(gspca_dev
, 0x0002, 1); /* 0x00 */
698 reg_r(gspca_dev
, 0x0053, 1); /* 0x00 */
699 reg_w_val(gspca_dev
, 0x0054, 0x02);
700 reg_w_val(gspca_dev
, 0x0054, 0x01);
701 reg_w_val(gspca_dev
, 0x0000, 0x94);
702 reg_w_val(gspca_dev
, 0x0053, 0xc0);
704 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
705 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
706 reg_r(gspca_dev
, 0x001f, 1); /* 0x38 */
707 reg_w(gspca_dev
, 0x0012, reg12
, 5);
708 reg_w(gspca_dev
, 0x00e5, regE5_8
, 8);
709 reg_r(gspca_dev
, 0x00e8, 8);
710 reg_w(gspca_dev
, 0x00e5, regE5a
, 4);
711 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
712 reg_w_val(gspca_dev
, 0x009a, 0x01);
713 reg_w(gspca_dev
, 0x00e5, regE5b
, 4);
714 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
715 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
716 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
718 reg_w(gspca_dev
, 0x0051, reg51
, 2);
719 reg_w(gspca_dev
, 0x0010, reg10
, 2);
720 reg_w_val(gspca_dev
, 0x0070, reg70
);
723 static void cx11646_init1(struct gspca_dev
*gspca_dev
)
727 reg_w_val(gspca_dev
, 0x0010, 0x00);
728 reg_w_val(gspca_dev
, 0x0053, 0x00);
729 reg_w_val(gspca_dev
, 0x0052, 0x00);
730 reg_w_val(gspca_dev
, 0x009b, 0x2f);
731 reg_w_val(gspca_dev
, 0x009c, 0x10);
732 reg_r(gspca_dev
, 0x0098, 1);
733 reg_w_val(gspca_dev
, 0x0098, 0x40);
734 reg_r(gspca_dev
, 0x0099, 1);
735 reg_w_val(gspca_dev
, 0x0099, 0x07);
736 reg_w_val(gspca_dev
, 0x0039, 0x40);
737 reg_w_val(gspca_dev
, 0x003c, 0xff);
738 reg_w_val(gspca_dev
, 0x003f, 0x1f);
739 reg_w_val(gspca_dev
, 0x003d, 0x40);
740 /* reg_w_val(gspca_dev, 0x003d, 0x60); */
741 reg_r(gspca_dev
, 0x0099, 1); /* ->0x07 */
743 while (cx_sensor_init
[i
][0]) {
744 reg_w_val(gspca_dev
, 0x00e5, cx_sensor_init
[i
][0]);
745 reg_r(gspca_dev
, 0x00e8, 1); /* -> 0x00 */
747 reg_w_val(gspca_dev
, 0x00ed, 0x01);
748 reg_r(gspca_dev
, 0x00ed, 1); /* -> 0x01 */
752 reg_w_val(gspca_dev
, 0x00c3, 0x00);
755 /* this function is called at probe time */
756 static int sd_config(struct gspca_dev
*gspca_dev
,
757 const struct usb_device_id
*id
)
761 cam
= &gspca_dev
->cam
;
762 cam
->cam_mode
= vga_mode
;
763 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
767 /* this function is called at probe and resume time */
768 static int sd_init(struct gspca_dev
*gspca_dev
)
770 cx11646_init1(gspca_dev
);
771 cx11646_initsize(gspca_dev
);
772 cx11646_fw(gspca_dev
);
773 cx_sensor(gspca_dev
);
774 cx11646_jpegInit(gspca_dev
);
778 static int sd_start(struct gspca_dev
*gspca_dev
)
780 struct sd
*sd
= (struct sd
*) gspca_dev
;
782 /* create the JPEG header */
783 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->pixfmt
.height
,
784 gspca_dev
->pixfmt
.width
,
785 0x22); /* JPEG 411 */
786 jpeg_set_qual(sd
->jpeg_hdr
, QUALITY
);
788 cx11646_initsize(gspca_dev
);
789 cx11646_fw(gspca_dev
);
790 cx_sensor(gspca_dev
);
791 cx11646_jpeg(gspca_dev
);
795 /* called on streamoff with alt 0 and on disconnect */
796 static void sd_stop0(struct gspca_dev
*gspca_dev
)
800 if (!gspca_dev
->present
)
802 reg_w_val(gspca_dev
, 0x0000, 0x00);
803 reg_r(gspca_dev
, 0x0002, 1);
804 reg_w_val(gspca_dev
, 0x0053, 0x00);
807 /* reg_r(gspca_dev, 0x0002, 1);*/
808 reg_r(gspca_dev
, 0x0053, 1);
809 if (gspca_dev
->usb_buf
[0] == 0)
812 reg_w_val(gspca_dev
, 0x0000, 0x00);
813 reg_r(gspca_dev
, 0x0002, 1);
815 reg_w_val(gspca_dev
, 0x0010, 0x00);
816 reg_r(gspca_dev
, 0x0033, 1);
817 reg_w_val(gspca_dev
, 0x00fc, 0xe0);
820 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
821 u8
*data
, /* isoc packet */
822 int len
) /* iso packet length */
824 struct sd
*sd
= (struct sd
*) gspca_dev
;
826 if (data
[0] == 0xff && data
[1] == 0xd8) {
829 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
831 /* put the JPEG header in the new frame */
832 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
833 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
837 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
840 static void setbrightness(struct gspca_dev
*gspca_dev
, s32 val
, s32 sat
)
842 __u8 regE5cbx
[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
846 reg_w(gspca_dev
, 0x00e5, regE5cbx
, 8);
847 reg_r(gspca_dev
, 0x00e8, 8);
848 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
849 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
853 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
854 reg_w(gspca_dev
, 0x0010, reg10
, 2);
855 reg_w_val(gspca_dev
, 0x0070, reg70
);
858 static void setcontrast(struct gspca_dev
*gspca_dev
, s32 val
, s32 sat
)
860 __u8 regE5acx
[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
861 /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
865 reg_w(gspca_dev
, 0x00e5, regE5acx
, 4);
866 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
869 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
870 reg_w(gspca_dev
, 0x0010, reg10
, 2);
871 reg_w_val(gspca_dev
, 0x0070, reg70
);
874 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
876 struct gspca_dev
*gspca_dev
=
877 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
878 struct sd
*sd
= (struct sd
*)gspca_dev
;
880 gspca_dev
->usb_err
= 0;
882 if (!gspca_dev
->streaming
)
886 case V4L2_CID_BRIGHTNESS
:
887 setbrightness(gspca_dev
, ctrl
->val
, sd
->sat
->cur
.val
);
889 case V4L2_CID_CONTRAST
:
890 setcontrast(gspca_dev
, ctrl
->val
, sd
->sat
->cur
.val
);
892 case V4L2_CID_SATURATION
:
893 setbrightness(gspca_dev
, sd
->brightness
->cur
.val
, ctrl
->val
);
894 setcontrast(gspca_dev
, sd
->contrast
->cur
.val
, ctrl
->val
);
897 return gspca_dev
->usb_err
;
900 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
904 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
906 struct sd
*sd
= (struct sd
*)gspca_dev
;
907 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
909 gspca_dev
->vdev
.ctrl_handler
= hdl
;
910 v4l2_ctrl_handler_init(hdl
, 3);
911 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
912 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 0xd4);
913 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
914 V4L2_CID_CONTRAST
, 0x0a, 0x1f, 1, 0x0c);
915 sd
->sat
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
916 V4L2_CID_SATURATION
, 0, 7, 1, 3);
918 pr_err("Could not initialize controls\n");
924 /* sub-driver description */
925 static const struct sd_desc sd_desc
= {
929 .init_controls
= sd_init_controls
,
932 .pkt_scan
= sd_pkt_scan
,
935 /* -- module initialisation -- */
936 static const struct usb_device_id device_table
[] = {
937 {USB_DEVICE(0x0572, 0x0041)},
940 MODULE_DEVICE_TABLE(usb
, device_table
);
942 /* -- device connect -- */
943 static int sd_probe(struct usb_interface
*intf
,
944 const struct usb_device_id
*id
)
946 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
950 static struct usb_driver sd_driver
= {
952 .id_table
= device_table
,
954 .disconnect
= gspca_disconnect
,
956 .suspend
= gspca_suspend
,
957 .resume
= gspca_resume
,
958 .reset_resume
= gspca_resume
,
962 module_usb_driver(sd_driver
);