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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 #define MODULE_NAME "conex"
27 #define CONEX_CAM 1 /* special JPEG header */
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
32 MODULE_LICENSE("GPL");
36 /* specific webcam descriptor */
38 struct gspca_dev gspca_dev
; /* !! must be the first item */
39 struct v4l2_ctrl
*brightness
;
40 struct v4l2_ctrl
*contrast
;
41 struct v4l2_ctrl
*sat
;
43 u8 jpeg_hdr
[JPEG_HDR_SZ
];
46 static const struct v4l2_pix_format vga_mode
[] = {
47 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
49 .sizeimage
= 176 * 144 * 3 / 8 + 590,
50 .colorspace
= V4L2_COLORSPACE_JPEG
,
52 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
54 .sizeimage
= 320 * 240 * 3 / 8 + 590,
55 .colorspace
= V4L2_COLORSPACE_JPEG
,
57 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
59 .sizeimage
= 352 * 288 * 3 / 8 + 590,
60 .colorspace
= V4L2_COLORSPACE_JPEG
,
62 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
64 .sizeimage
= 640 * 480 * 3 / 8 + 590,
65 .colorspace
= V4L2_COLORSPACE_JPEG
,
69 /* the read bytes are found in gspca_dev->usb_buf */
70 static void reg_r(struct gspca_dev
*gspca_dev
,
74 struct usb_device
*dev
= gspca_dev
->dev
;
76 if (len
> USB_BUF_SZ
) {
77 PERR("reg_r: buffer overflow\n");
82 usb_rcvctrlpipe(dev
, 0),
84 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
86 index
, gspca_dev
->usb_buf
, len
,
88 PDEBUG(D_USBI
, "reg read [%02x] -> %02x ..",
89 index
, gspca_dev
->usb_buf
[0]);
92 /* the bytes to write are in gspca_dev->usb_buf */
93 static void reg_w_val(struct gspca_dev
*gspca_dev
,
97 struct usb_device
*dev
= gspca_dev
->dev
;
99 gspca_dev
->usb_buf
[0] = val
;
101 usb_sndctrlpipe(dev
, 0),
103 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
105 index
, gspca_dev
->usb_buf
, 1, 500);
108 static void reg_w(struct gspca_dev
*gspca_dev
,
113 struct usb_device
*dev
= gspca_dev
->dev
;
115 if (len
> USB_BUF_SZ
) {
116 PERR("reg_w: buffer overflow\n");
119 PDEBUG(D_USBO
, "reg write [%02x] = %02x..", index
, *buffer
);
121 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
123 usb_sndctrlpipe(dev
, 0),
125 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
127 index
, gspca_dev
->usb_buf
, len
, 500);
130 static const __u8 cx_sensor_init
[][4] = {
131 {0x88, 0x11, 0x01, 0x01},
132 {0x88, 0x12, 0x70, 0x01},
133 {0x88, 0x0f, 0x00, 0x01},
134 {0x88, 0x05, 0x01, 0x01},
138 static const __u8 cx11646_fw1
[][3] = {
205 static void cx11646_fw(struct gspca_dev
*gspca_dev
)
209 reg_w_val(gspca_dev
, 0x006a, 0x02);
210 while (cx11646_fw1
[i
][1]) {
211 reg_w(gspca_dev
, 0x006b, cx11646_fw1
[i
], 3);
214 reg_w_val(gspca_dev
, 0x006a, 0x00);
217 static const __u8 cxsensor
[] = {
218 0x88, 0x12, 0x70, 0x01,
219 0x88, 0x0d, 0x02, 0x01,
220 0x88, 0x0f, 0x00, 0x01,
221 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
222 0x88, 0x02, 0x10, 0x01,
223 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
224 0x88, 0x0B, 0x00, 0x01,
225 0x88, 0x0A, 0x0A, 0x01,
226 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
227 0x88, 0x05, 0x01, 0x01,
228 0xA1, 0x18, 0x00, 0x01,
232 static const __u8 reg20
[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
233 static const __u8 reg28
[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
234 static const __u8 reg10
[] = { 0xb1, 0xb1 };
235 static const __u8 reg71a
[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
236 static const __u8 reg71b
[] = { 0x04, 0x0c, 0x05, 0x0f };
237 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
238 static const __u8 reg71c
[] = { 0x02, 0x07, 0x03, 0x09 };
239 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
240 static const __u8 reg71d
[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
241 static const __u8 reg7b
[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
243 static void cx_sensor(struct gspca_dev
*gspca_dev
)
247 const __u8
*ptsensor
= cxsensor
;
249 reg_w(gspca_dev
, 0x0020, reg20
, 8);
250 reg_w(gspca_dev
, 0x0028, reg28
, 8);
251 reg_w(gspca_dev
, 0x0010, reg10
, 2);
252 reg_w_val(gspca_dev
, 0x0092, 0x03);
254 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
256 reg_w(gspca_dev
, 0x0071, reg71a
, 4);
259 reg_w(gspca_dev
, 0x0071, reg71b
, 4);
263 reg_w(gspca_dev
, 0x0071, reg71c
, 4);
266 reg_w(gspca_dev
, 0x0071, reg71d
, 4);
269 reg_w(gspca_dev
, 0x007b, reg7b
, 6);
270 reg_w_val(gspca_dev
, 0x00f8, 0x00);
271 reg_w(gspca_dev
, 0x0010, reg10
, 2);
272 reg_w_val(gspca_dev
, 0x0098, 0x41);
273 for (i
= 0; i
< 11; i
++) {
274 if (i
== 3 || i
== 5 || i
== 8)
278 reg_w(gspca_dev
, 0x00e5, ptsensor
, length
);
280 reg_r(gspca_dev
, 0x00e8, 1);
282 reg_r(gspca_dev
, 0x00e8, length
);
285 reg_r(gspca_dev
, 0x00e7, 8);
288 static const __u8 cx_inits_176
[] = {
289 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
290 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
291 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
292 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
293 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
294 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
295 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
297 static const __u8 cx_inits_320
[] = {
298 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
299 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
300 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
301 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
302 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
303 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
304 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
306 static const __u8 cx_inits_352
[] = {
307 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
308 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
309 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
310 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
311 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
312 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
313 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
315 static const __u8 cx_inits_640
[] = {
316 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
317 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
318 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
319 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
320 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
321 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
322 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
325 static void cx11646_initsize(struct gspca_dev
*gspca_dev
)
328 static const __u8 reg12
[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
329 static const __u8 reg17
[] =
330 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
332 switch (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
) {
334 cxinit
= cx_inits_640
;
337 cxinit
= cx_inits_352
;
341 cxinit
= cx_inits_320
;
344 cxinit
= cx_inits_176
;
347 reg_w_val(gspca_dev
, 0x009a, 0x01);
348 reg_w_val(gspca_dev
, 0x0010, 0x10);
349 reg_w(gspca_dev
, 0x0012, reg12
, 5);
350 reg_w(gspca_dev
, 0x0017, reg17
, 8);
351 reg_w_val(gspca_dev
, 0x00c0, 0x00);
352 reg_w_val(gspca_dev
, 0x00c1, 0x04);
353 reg_w_val(gspca_dev
, 0x00c2, 0x04);
355 reg_w(gspca_dev
, 0x0061, cxinit
, 8);
357 reg_w(gspca_dev
, 0x00ca, cxinit
, 8);
359 reg_w(gspca_dev
, 0x00d2, cxinit
, 8);
361 reg_w(gspca_dev
, 0x00da, cxinit
, 6);
363 reg_w(gspca_dev
, 0x0041, cxinit
, 8);
365 reg_w(gspca_dev
, 0x0049, cxinit
, 8);
367 reg_w(gspca_dev
, 0x0051, cxinit
, 2);
369 reg_r(gspca_dev
, 0x0010, 1);
372 static const __u8 cx_jpeg_init
[][8] = {
373 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
374 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
375 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
376 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
377 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
378 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
379 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
380 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
381 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
382 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
383 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
384 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
385 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
386 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
387 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
388 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
389 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
390 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
391 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
392 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
393 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
394 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
395 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
396 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
397 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
398 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
399 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
400 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
401 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
402 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
403 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
404 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
405 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
406 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
407 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
408 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
409 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
410 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
411 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
412 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
413 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
414 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
415 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
416 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
417 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
418 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
419 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
420 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
421 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
422 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
423 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
424 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
425 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
426 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
427 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
428 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
429 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
430 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
431 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
432 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
433 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
434 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
435 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
436 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
437 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
438 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
439 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
440 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
441 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
442 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
443 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
444 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
445 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
446 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
447 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
448 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
449 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
450 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
451 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
455 static const __u8 cxjpeg_640
[][8] = {
456 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
457 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
458 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
459 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
460 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
461 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
462 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
463 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
464 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
465 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
466 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
467 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
468 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
469 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
470 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
471 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
472 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
473 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
474 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
475 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
476 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
477 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
478 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
479 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
480 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
481 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
482 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
484 static const __u8 cxjpeg_352
[][8] = {
485 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
486 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
487 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
488 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
489 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
490 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
491 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
492 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
493 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
494 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
495 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
496 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
497 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
498 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
499 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
500 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
501 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
502 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
503 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
504 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
505 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
506 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
507 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
508 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
509 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
510 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
511 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
513 static const __u8 cxjpeg_320
[][8] = {
514 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
515 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
516 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
517 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
518 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
519 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
520 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
521 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
522 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
523 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
524 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
525 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
526 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
527 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
528 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
529 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
530 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
531 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
532 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
533 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
534 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
535 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
536 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
537 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
538 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
539 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
540 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
542 static const __u8 cxjpeg_176
[][8] = {
543 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
544 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
545 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
546 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
547 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
548 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
549 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
550 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
551 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
552 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
553 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
554 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
555 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
556 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
557 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
558 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
559 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
560 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
561 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
562 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
563 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
564 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
565 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
566 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
567 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
568 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
569 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
571 /* 640 take with the zcx30x part */
572 static const __u8 cxjpeg_qtable
[][8] = {
573 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
574 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
575 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
576 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
577 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
578 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
579 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
580 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
581 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
582 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
583 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 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 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
588 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
589 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
590 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
594 static void cx11646_jpegInit(struct gspca_dev
*gspca_dev
)
599 reg_w_val(gspca_dev
, 0x00c0, 0x01);
600 reg_w_val(gspca_dev
, 0x00c3, 0x00);
601 reg_w_val(gspca_dev
, 0x00c0, 0x00);
602 reg_r(gspca_dev
, 0x0001, 1);
604 for (i
= 0; i
< 79; i
++) {
607 reg_w(gspca_dev
, 0x0008, cx_jpeg_init
[i
], length
);
609 reg_r(gspca_dev
, 0x0002, 1);
610 reg_w_val(gspca_dev
, 0x0055, 0x14);
613 static const __u8 reg12
[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
614 static const __u8 regE5_8
[] =
615 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
616 static const __u8 regE5a
[] = { 0x88, 0x0a, 0x0c, 0x01 };
617 static const __u8 regE5b
[] = { 0x88, 0x0b, 0x12, 0x01 };
618 static const __u8 regE5c
[] = { 0x88, 0x05, 0x01, 0x01 };
619 static const __u8 reg51
[] = { 0x77, 0x03 };
622 static void cx11646_jpeg(struct gspca_dev
*gspca_dev
)
629 reg_w_val(gspca_dev
, 0x00c0, 0x01);
630 reg_w_val(gspca_dev
, 0x00c3, 0x00);
631 reg_w_val(gspca_dev
, 0x00c0, 0x00);
632 reg_r(gspca_dev
, 0x0001, 1);
634 switch (gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
) {
636 for (i
= 0; i
< 27; i
++) {
639 reg_w(gspca_dev
, 0x0008, cxjpeg_640
[i
], length
);
644 for (i
= 0; i
< 27; i
++) {
647 reg_w(gspca_dev
, 0x0008, cxjpeg_352
[i
], length
);
653 for (i
= 0; i
< 27; i
++) {
656 reg_w(gspca_dev
, 0x0008, cxjpeg_320
[i
], length
);
661 for (i
= 0; i
< 27; i
++) {
664 reg_w(gspca_dev
, 0x0008, cxjpeg_176
[i
], length
);
670 reg_r(gspca_dev
, 0x0002, 1);
671 reg_w_val(gspca_dev
, 0x0055, Reg55
);
672 reg_r(gspca_dev
, 0x0002, 1);
673 reg_w(gspca_dev
, 0x0010, reg10
, 2);
674 reg_w_val(gspca_dev
, 0x0054, 0x02);
675 reg_w_val(gspca_dev
, 0x0054, 0x01);
676 reg_w_val(gspca_dev
, 0x0000, 0x94);
677 reg_w_val(gspca_dev
, 0x0053, 0xc0);
678 reg_w_val(gspca_dev
, 0x00fc, 0xe1);
679 reg_w_val(gspca_dev
, 0x0000, 0x00);
680 /* wait for completion */
683 reg_r(gspca_dev
, 0x0002, 1);
684 /* 0x07 until 0x00 */
685 if (gspca_dev
->usb_buf
[0] == 0x00)
687 reg_w_val(gspca_dev
, 0x0053, 0x00);
690 PERR("Damned Errors sending jpeg Table");
691 /* send the qtable now */
692 reg_r(gspca_dev
, 0x0001, 1); /* -> 0x18 */
694 for (i
= 0; i
< 18; i
++) {
697 reg_w(gspca_dev
, 0x0008, cxjpeg_qtable
[i
], length
);
700 reg_r(gspca_dev
, 0x0002, 1); /* 0x00 */
701 reg_r(gspca_dev
, 0x0053, 1); /* 0x00 */
702 reg_w_val(gspca_dev
, 0x0054, 0x02);
703 reg_w_val(gspca_dev
, 0x0054, 0x01);
704 reg_w_val(gspca_dev
, 0x0000, 0x94);
705 reg_w_val(gspca_dev
, 0x0053, 0xc0);
707 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
708 reg_r(gspca_dev
, 0x0038, 1); /* 0x40 */
709 reg_r(gspca_dev
, 0x001f, 1); /* 0x38 */
710 reg_w(gspca_dev
, 0x0012, reg12
, 5);
711 reg_w(gspca_dev
, 0x00e5, regE5_8
, 8);
712 reg_r(gspca_dev
, 0x00e8, 8);
713 reg_w(gspca_dev
, 0x00e5, regE5a
, 4);
714 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
715 reg_w_val(gspca_dev
, 0x009a, 0x01);
716 reg_w(gspca_dev
, 0x00e5, regE5b
, 4);
717 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
718 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
719 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
721 reg_w(gspca_dev
, 0x0051, reg51
, 2);
722 reg_w(gspca_dev
, 0x0010, reg10
, 2);
723 reg_w_val(gspca_dev
, 0x0070, reg70
);
726 static void cx11646_init1(struct gspca_dev
*gspca_dev
)
730 reg_w_val(gspca_dev
, 0x0010, 0x00);
731 reg_w_val(gspca_dev
, 0x0053, 0x00);
732 reg_w_val(gspca_dev
, 0x0052, 0x00);
733 reg_w_val(gspca_dev
, 0x009b, 0x2f);
734 reg_w_val(gspca_dev
, 0x009c, 0x10);
735 reg_r(gspca_dev
, 0x0098, 1);
736 reg_w_val(gspca_dev
, 0x0098, 0x40);
737 reg_r(gspca_dev
, 0x0099, 1);
738 reg_w_val(gspca_dev
, 0x0099, 0x07);
739 reg_w_val(gspca_dev
, 0x0039, 0x40);
740 reg_w_val(gspca_dev
, 0x003c, 0xff);
741 reg_w_val(gspca_dev
, 0x003f, 0x1f);
742 reg_w_val(gspca_dev
, 0x003d, 0x40);
743 /* reg_w_val(gspca_dev, 0x003d, 0x60); */
744 reg_r(gspca_dev
, 0x0099, 1); /* ->0x07 */
746 while (cx_sensor_init
[i
][0]) {
747 reg_w_val(gspca_dev
, 0x00e5, cx_sensor_init
[i
][0]);
748 reg_r(gspca_dev
, 0x00e8, 1); /* -> 0x00 */
750 reg_w_val(gspca_dev
, 0x00ed, 0x01);
751 reg_r(gspca_dev
, 0x00ed, 1); /* -> 0x01 */
755 reg_w_val(gspca_dev
, 0x00c3, 0x00);
758 /* this function is called at probe time */
759 static int sd_config(struct gspca_dev
*gspca_dev
,
760 const struct usb_device_id
*id
)
764 cam
= &gspca_dev
->cam
;
765 cam
->cam_mode
= vga_mode
;
766 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
770 /* this function is called at probe and resume time */
771 static int sd_init(struct gspca_dev
*gspca_dev
)
773 cx11646_init1(gspca_dev
);
774 cx11646_initsize(gspca_dev
);
775 cx11646_fw(gspca_dev
);
776 cx_sensor(gspca_dev
);
777 cx11646_jpegInit(gspca_dev
);
781 static int sd_start(struct gspca_dev
*gspca_dev
)
783 struct sd
*sd
= (struct sd
*) gspca_dev
;
785 /* create the JPEG header */
786 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->pixfmt
.height
,
787 gspca_dev
->pixfmt
.width
,
788 0x22); /* JPEG 411 */
789 jpeg_set_qual(sd
->jpeg_hdr
, QUALITY
);
791 cx11646_initsize(gspca_dev
);
792 cx11646_fw(gspca_dev
);
793 cx_sensor(gspca_dev
);
794 cx11646_jpeg(gspca_dev
);
798 /* called on streamoff with alt 0 and on disconnect */
799 static void sd_stop0(struct gspca_dev
*gspca_dev
)
803 if (!gspca_dev
->present
)
805 reg_w_val(gspca_dev
, 0x0000, 0x00);
806 reg_r(gspca_dev
, 0x0002, 1);
807 reg_w_val(gspca_dev
, 0x0053, 0x00);
810 /* reg_r(gspca_dev, 0x0002, 1);*/
811 reg_r(gspca_dev
, 0x0053, 1);
812 if (gspca_dev
->usb_buf
[0] == 0)
815 reg_w_val(gspca_dev
, 0x0000, 0x00);
816 reg_r(gspca_dev
, 0x0002, 1);
818 reg_w_val(gspca_dev
, 0x0010, 0x00);
819 reg_r(gspca_dev
, 0x0033, 1);
820 reg_w_val(gspca_dev
, 0x00fc, 0xe0);
823 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
824 u8
*data
, /* isoc packet */
825 int len
) /* iso packet length */
827 struct sd
*sd
= (struct sd
*) gspca_dev
;
829 if (data
[0] == 0xff && data
[1] == 0xd8) {
832 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
834 /* put the JPEG header in the new frame */
835 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
836 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
840 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
843 static void setbrightness(struct gspca_dev
*gspca_dev
, s32 val
, s32 sat
)
845 __u8 regE5cbx
[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
849 reg_w(gspca_dev
, 0x00e5, regE5cbx
, 8);
850 reg_r(gspca_dev
, 0x00e8, 8);
851 reg_w(gspca_dev
, 0x00e5, regE5c
, 4);
852 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
856 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
857 reg_w(gspca_dev
, 0x0010, reg10
, 2);
858 reg_w_val(gspca_dev
, 0x0070, reg70
);
861 static void setcontrast(struct gspca_dev
*gspca_dev
, s32 val
, s32 sat
)
863 __u8 regE5acx
[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
864 /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
868 reg_w(gspca_dev
, 0x00e5, regE5acx
, 4);
869 reg_r(gspca_dev
, 0x00e8, 1); /* 0x00 */
872 reg_w(gspca_dev
, 0x0051, reg51c
, 2);
873 reg_w(gspca_dev
, 0x0010, reg10
, 2);
874 reg_w_val(gspca_dev
, 0x0070, reg70
);
877 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
879 struct gspca_dev
*gspca_dev
=
880 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
881 struct sd
*sd
= (struct sd
*)gspca_dev
;
883 gspca_dev
->usb_err
= 0;
885 if (!gspca_dev
->streaming
)
889 case V4L2_CID_BRIGHTNESS
:
890 setbrightness(gspca_dev
, ctrl
->val
, sd
->sat
->cur
.val
);
892 case V4L2_CID_CONTRAST
:
893 setcontrast(gspca_dev
, ctrl
->val
, sd
->sat
->cur
.val
);
895 case V4L2_CID_SATURATION
:
896 setbrightness(gspca_dev
, sd
->brightness
->cur
.val
, ctrl
->val
);
897 setcontrast(gspca_dev
, sd
->contrast
->cur
.val
, ctrl
->val
);
900 return gspca_dev
->usb_err
;
903 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
907 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
909 struct sd
*sd
= (struct sd
*)gspca_dev
;
910 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
912 gspca_dev
->vdev
.ctrl_handler
= hdl
;
913 v4l2_ctrl_handler_init(hdl
, 3);
914 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
915 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 0xd4);
916 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
917 V4L2_CID_CONTRAST
, 0x0a, 0x1f, 1, 0x0c);
918 sd
->sat
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
919 V4L2_CID_SATURATION
, 0, 7, 1, 3);
921 pr_err("Could not initialize controls\n");
927 /* sub-driver description */
928 static const struct sd_desc sd_desc
= {
932 .init_controls
= sd_init_controls
,
935 .pkt_scan
= sd_pkt_scan
,
938 /* -- module initialisation -- */
939 static const struct usb_device_id device_table
[] = {
940 {USB_DEVICE(0x0572, 0x0041)},
943 MODULE_DEVICE_TABLE(usb
, device_table
);
945 /* -- device connect -- */
946 static int sd_probe(struct usb_interface
*intf
,
947 const struct usb_device_id
*id
)
949 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
953 static struct usb_driver sd_driver
= {
955 .id_table
= device_table
,
957 .disconnect
= gspca_disconnect
,
959 .suspend
= gspca_suspend
,
960 .resume
= gspca_resume
,
961 .reset_resume
= gspca_resume
,
965 module_usb_driver(sd_driver
);