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");
34 #define QUALITY_MIN 30
35 #define QUALITY_MAX 60
36 #define QUALITY_DEF 40
38 /* specific webcam descriptor */
40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 struct v4l2_ctrl *brightness;
42 struct v4l2_ctrl *contrast;
43 struct v4l2_ctrl *sat;
44 struct v4l2_ctrl *jpegqual;
46 u8 jpeg_hdr[JPEG_HDR_SZ];
49 static const struct v4l2_pix_format vga_mode[] = {
50 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
52 .sizeimage = 176 * 144 * 3 / 8 + 590,
53 .colorspace = V4L2_COLORSPACE_JPEG,
55 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
57 .sizeimage = 320 * 240 * 3 / 8 + 590,
58 .colorspace = V4L2_COLORSPACE_JPEG,
60 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
62 .sizeimage = 352 * 288 * 3 / 8 + 590,
63 .colorspace = V4L2_COLORSPACE_JPEG,
65 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
67 .sizeimage = 640 * 480 * 3 / 8 + 590,
68 .colorspace = V4L2_COLORSPACE_JPEG,
72 /* the read bytes are found in gspca_dev->usb_buf */
73 static void reg_r(struct gspca_dev *gspca_dev,
77 struct usb_device *dev = gspca_dev->dev;
80 if (len > USB_BUF_SZ) {
81 pr_err("reg_r: buffer overflow\n");
86 usb_rcvctrlpipe(dev, 0),
88 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
90 index, gspca_dev->usb_buf, len,
92 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
93 index, gspca_dev->usb_buf[0]);
96 /* the bytes to write are in gspca_dev->usb_buf */
97 static void reg_w_val(struct gspca_dev *gspca_dev,
101 struct usb_device *dev = gspca_dev->dev;
103 gspca_dev->usb_buf[0] = val;
105 usb_sndctrlpipe(dev, 0),
107 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
109 index, gspca_dev->usb_buf, 1, 500);
112 static void reg_w(struct gspca_dev *gspca_dev,
117 struct usb_device *dev = gspca_dev->dev;
120 if (len > USB_BUF_SZ) {
121 pr_err("reg_w: buffer overflow\n");
124 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
126 memcpy(gspca_dev->usb_buf, buffer, len);
128 usb_sndctrlpipe(dev, 0),
130 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
132 index, gspca_dev->usb_buf, len, 500);
135 static const __u8 cx_sensor_init[][4] = {
136 {0x88, 0x11, 0x01, 0x01},
137 {0x88, 0x12, 0x70, 0x01},
138 {0x88, 0x0f, 0x00, 0x01},
139 {0x88, 0x05, 0x01, 0x01},
143 static const __u8 cx11646_fw1[][3] = {
210 static void cx11646_fw(struct gspca_dev*gspca_dev)
214 reg_w_val(gspca_dev, 0x006a, 0x02);
215 while (cx11646_fw1[i][1]) {
216 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
219 reg_w_val(gspca_dev, 0x006a, 0x00);
222 static const __u8 cxsensor[] = {
223 0x88, 0x12, 0x70, 0x01,
224 0x88, 0x0d, 0x02, 0x01,
225 0x88, 0x0f, 0x00, 0x01,
226 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
227 0x88, 0x02, 0x10, 0x01,
228 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
229 0x88, 0x0B, 0x00, 0x01,
230 0x88, 0x0A, 0x0A, 0x01,
231 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
232 0x88, 0x05, 0x01, 0x01,
233 0xA1, 0x18, 0x00, 0x01,
237 static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
238 static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
239 static const __u8 reg10[] = { 0xb1, 0xb1 };
240 static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
241 static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
242 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
243 static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
244 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
245 static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
246 static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
248 static void cx_sensor(struct gspca_dev*gspca_dev)
252 const __u8 *ptsensor = cxsensor;
254 reg_w(gspca_dev, 0x0020, reg20, 8);
255 reg_w(gspca_dev, 0x0028, reg28, 8);
256 reg_w(gspca_dev, 0x0010, reg10, 2);
257 reg_w_val(gspca_dev, 0x0092, 0x03);
259 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
261 reg_w(gspca_dev, 0x0071, reg71a, 4);
264 reg_w(gspca_dev, 0x0071, reg71b, 4);
268 reg_w(gspca_dev, 0x0071, reg71c, 4);
271 reg_w(gspca_dev, 0x0071, reg71d, 4);
274 reg_w(gspca_dev, 0x007b, reg7b, 6);
275 reg_w_val(gspca_dev, 0x00f8, 0x00);
276 reg_w(gspca_dev, 0x0010, reg10, 2);
277 reg_w_val(gspca_dev, 0x0098, 0x41);
278 for (i = 0; i < 11; i++) {
279 if (i == 3 || i == 5 || i == 8)
283 reg_w(gspca_dev, 0x00e5, ptsensor, length);
285 reg_r(gspca_dev, 0x00e8, 1);
287 reg_r(gspca_dev, 0x00e8, length);
290 reg_r(gspca_dev, 0x00e7, 8);
293 static const __u8 cx_inits_176[] = {
294 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
295 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
296 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
297 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
298 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
299 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
300 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
302 static const __u8 cx_inits_320[] = {
303 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
304 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
305 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
306 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
307 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
308 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
309 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
311 static const __u8 cx_inits_352[] = {
312 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
313 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
314 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
315 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
316 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
317 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
318 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
320 static const __u8 cx_inits_640[] = {
321 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
322 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
323 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
324 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
325 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
326 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
327 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
330 static void cx11646_initsize(struct gspca_dev *gspca_dev)
333 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
334 static const __u8 reg17[] =
335 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
337 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
339 cxinit = cx_inits_640;
342 cxinit = cx_inits_352;
346 cxinit = cx_inits_320;
349 cxinit = cx_inits_176;
352 reg_w_val(gspca_dev, 0x009a, 0x01);
353 reg_w_val(gspca_dev, 0x0010, 0x10);
354 reg_w(gspca_dev, 0x0012, reg12, 5);
355 reg_w(gspca_dev, 0x0017, reg17, 8);
356 reg_w_val(gspca_dev, 0x00c0, 0x00);
357 reg_w_val(gspca_dev, 0x00c1, 0x04);
358 reg_w_val(gspca_dev, 0x00c2, 0x04);
360 reg_w(gspca_dev, 0x0061, cxinit, 8);
362 reg_w(gspca_dev, 0x00ca, cxinit, 8);
364 reg_w(gspca_dev, 0x00d2, cxinit, 8);
366 reg_w(gspca_dev, 0x00da, cxinit, 6);
368 reg_w(gspca_dev, 0x0041, cxinit, 8);
370 reg_w(gspca_dev, 0x0049, cxinit, 8);
372 reg_w(gspca_dev, 0x0051, cxinit, 2);
374 reg_r(gspca_dev, 0x0010, 1);
377 static const __u8 cx_jpeg_init[][8] = {
378 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
379 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
380 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
381 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
382 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
383 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
384 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
385 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
386 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
387 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
388 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
389 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
390 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
391 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
392 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
393 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
394 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
395 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
396 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
397 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
398 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
399 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
400 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
401 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
402 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
403 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
404 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
405 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
406 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
407 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
408 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
409 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
410 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
411 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
412 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
413 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
414 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
415 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
416 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
417 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
418 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
419 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
420 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
421 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
422 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
423 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
424 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
425 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
426 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
427 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
428 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
429 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
430 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
431 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
432 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
433 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
434 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
435 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
436 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
437 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
438 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
439 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
440 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
441 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
442 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
443 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
444 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
445 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
446 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
447 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
448 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
449 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
450 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
451 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
452 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
453 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
454 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
455 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
456 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
460 static const __u8 cxjpeg_640[][8] = {
461 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
462 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
463 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
464 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
465 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
466 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
467 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
468 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
469 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
470 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
471 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
472 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
473 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
474 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
475 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
476 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
477 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
478 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
479 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
480 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
481 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
482 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
483 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
484 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
485 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
486 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
487 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
489 static const __u8 cxjpeg_352[][8] = {
490 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
491 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
492 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
493 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
494 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
495 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
496 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
497 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
498 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
499 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
500 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
501 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
502 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
503 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
504 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
505 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
506 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
507 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
508 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
509 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
510 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
511 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
512 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
513 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
514 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
515 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
516 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
518 static const __u8 cxjpeg_320[][8] = {
519 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
520 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
521 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
522 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
523 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
524 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
525 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
526 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
527 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
528 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
529 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
530 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
531 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
532 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
533 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
534 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
535 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
536 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
537 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
538 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
539 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
540 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
541 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
542 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
543 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
544 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
545 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
547 static const __u8 cxjpeg_176[][8] = {
548 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
549 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
550 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
551 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
552 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
553 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
554 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
555 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
556 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
557 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
558 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
559 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
560 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
561 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
562 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
563 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
564 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
565 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
566 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
567 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
568 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
569 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
570 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
571 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
572 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
573 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
574 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
576 /* 640 take with the zcx30x part */
577 static const __u8 cxjpeg_qtable[][8] = {
578 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
579 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
580 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
581 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
582 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
583 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
584 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
585 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
586 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
587 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
588 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
589 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
590 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
591 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
592 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
593 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
594 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
595 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
599 static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
604 reg_w_val(gspca_dev, 0x00c0, 0x01);
605 reg_w_val(gspca_dev, 0x00c3, 0x00);
606 reg_w_val(gspca_dev, 0x00c0, 0x00);
607 reg_r(gspca_dev, 0x0001, 1);
609 for (i = 0; i < 79; i++) {
612 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
614 reg_r(gspca_dev, 0x0002, 1);
615 reg_w_val(gspca_dev, 0x0055, 0x14);
618 static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
619 static const __u8 regE5_8[] =
620 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
621 static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
622 static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
623 static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
624 static const __u8 reg51[] = { 0x77, 0x03 };
627 static void cx11646_jpeg(struct gspca_dev*gspca_dev)
634 reg_w_val(gspca_dev, 0x00c0, 0x01);
635 reg_w_val(gspca_dev, 0x00c3, 0x00);
636 reg_w_val(gspca_dev, 0x00c0, 0x00);
637 reg_r(gspca_dev, 0x0001, 1);
639 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
641 for (i = 0; i < 27; i++) {
644 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
649 for (i = 0; i < 27; i++) {
652 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
658 for (i = 0; i < 27; i++) {
661 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
666 for (i = 0; i < 27; i++) {
669 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
675 reg_r(gspca_dev, 0x0002, 1);
676 reg_w_val(gspca_dev, 0x0055, Reg55);
677 reg_r(gspca_dev, 0x0002, 1);
678 reg_w(gspca_dev, 0x0010, reg10, 2);
679 reg_w_val(gspca_dev, 0x0054, 0x02);
680 reg_w_val(gspca_dev, 0x0054, 0x01);
681 reg_w_val(gspca_dev, 0x0000, 0x94);
682 reg_w_val(gspca_dev, 0x0053, 0xc0);
683 reg_w_val(gspca_dev, 0x00fc, 0xe1);
684 reg_w_val(gspca_dev, 0x0000, 0x00);
685 /* wait for completion */
688 reg_r(gspca_dev, 0x0002, 1);
689 /* 0x07 until 0x00 */
690 if (gspca_dev->usb_buf[0] == 0x00)
692 reg_w_val(gspca_dev, 0x0053, 0x00);
695 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
696 /* send the qtable now */
697 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
699 for (i = 0; i < 18; i++) {
702 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
705 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
706 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
707 reg_w_val(gspca_dev, 0x0054, 0x02);
708 reg_w_val(gspca_dev, 0x0054, 0x01);
709 reg_w_val(gspca_dev, 0x0000, 0x94);
710 reg_w_val(gspca_dev, 0x0053, 0xc0);
712 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
713 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
714 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
715 reg_w(gspca_dev, 0x0012, reg12, 5);
716 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
717 reg_r(gspca_dev, 0x00e8, 8);
718 reg_w(gspca_dev, 0x00e5, regE5a, 4);
719 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
720 reg_w_val(gspca_dev, 0x009a, 0x01);
721 reg_w(gspca_dev, 0x00e5, regE5b, 4);
722 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
723 reg_w(gspca_dev, 0x00e5, regE5c, 4);
724 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
726 reg_w(gspca_dev, 0x0051, reg51, 2);
727 reg_w(gspca_dev, 0x0010, reg10, 2);
728 reg_w_val(gspca_dev, 0x0070, reg70);
731 static void cx11646_init1(struct gspca_dev *gspca_dev)
735 reg_w_val(gspca_dev, 0x0010, 0x00);
736 reg_w_val(gspca_dev, 0x0053, 0x00);
737 reg_w_val(gspca_dev, 0x0052, 0x00);
738 reg_w_val(gspca_dev, 0x009b, 0x2f);
739 reg_w_val(gspca_dev, 0x009c, 0x10);
740 reg_r(gspca_dev, 0x0098, 1);
741 reg_w_val(gspca_dev, 0x0098, 0x40);
742 reg_r(gspca_dev, 0x0099, 1);
743 reg_w_val(gspca_dev, 0x0099, 0x07);
744 reg_w_val(gspca_dev, 0x0039, 0x40);
745 reg_w_val(gspca_dev, 0x003c, 0xff);
746 reg_w_val(gspca_dev, 0x003f, 0x1f);
747 reg_w_val(gspca_dev, 0x003d, 0x40);
748 /* reg_w_val(gspca_dev, 0x003d, 0x60); */
749 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
751 while (cx_sensor_init[i][0]) {
752 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
753 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
755 reg_w_val(gspca_dev, 0x00ed, 0x01);
756 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
760 reg_w_val(gspca_dev, 0x00c3, 0x00);
763 /* this function is called at probe time */
764 static int sd_config(struct gspca_dev *gspca_dev,
765 const struct usb_device_id *id)
769 cam = &gspca_dev->cam;
770 cam->cam_mode = vga_mode;
771 cam->nmodes = ARRAY_SIZE(vga_mode);
775 /* this function is called at probe and resume time */
776 static int sd_init(struct gspca_dev *gspca_dev)
778 cx11646_init1(gspca_dev);
779 cx11646_initsize(gspca_dev);
780 cx11646_fw(gspca_dev);
781 cx_sensor(gspca_dev);
782 cx11646_jpegInit(gspca_dev);
786 static int sd_start(struct gspca_dev *gspca_dev)
788 struct sd *sd = (struct sd *) gspca_dev;
790 /* create the JPEG header */
791 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
792 0x22); /* JPEG 411 */
794 cx11646_initsize(gspca_dev);
795 cx11646_fw(gspca_dev);
796 cx_sensor(gspca_dev);
797 cx11646_jpeg(gspca_dev);
801 /* called on streamoff with alt 0 and on disconnect */
802 static void sd_stop0(struct gspca_dev *gspca_dev)
806 if (!gspca_dev->present)
808 reg_w_val(gspca_dev, 0x0000, 0x00);
809 reg_r(gspca_dev, 0x0002, 1);
810 reg_w_val(gspca_dev, 0x0053, 0x00);
813 /* reg_r(gspca_dev, 0x0002, 1);*/
814 reg_r(gspca_dev, 0x0053, 1);
815 if (gspca_dev->usb_buf[0] == 0)
818 reg_w_val(gspca_dev, 0x0000, 0x00);
819 reg_r(gspca_dev, 0x0002, 1);
821 reg_w_val(gspca_dev, 0x0010, 0x00);
822 reg_r(gspca_dev, 0x0033, 1);
823 reg_w_val(gspca_dev, 0x00fc, 0xe0);
826 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
827 u8 *data, /* isoc packet */
828 int len) /* iso packet length */
830 struct sd *sd = (struct sd *) gspca_dev;
832 if (data[0] == 0xff && data[1] == 0xd8) {
835 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
837 /* put the JPEG header in the new frame */
838 gspca_frame_add(gspca_dev, FIRST_PACKET,
839 sd->jpeg_hdr, JPEG_HDR_SZ);
843 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
846 static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
848 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
852 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
853 reg_r(gspca_dev, 0x00e8, 8);
854 reg_w(gspca_dev, 0x00e5, regE5c, 4);
855 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
859 reg_w(gspca_dev, 0x0051, reg51c, 2);
860 reg_w(gspca_dev, 0x0010, reg10, 2);
861 reg_w_val(gspca_dev, 0x0070, reg70);
864 static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
866 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
867 /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
871 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
872 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
875 reg_w(gspca_dev, 0x0051, reg51c, 2);
876 reg_w(gspca_dev, 0x0010, reg10, 2);
877 reg_w_val(gspca_dev, 0x0070, reg70);
880 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
882 struct gspca_dev *gspca_dev =
883 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
884 struct sd *sd = (struct sd *)gspca_dev;
886 gspca_dev->usb_err = 0;
888 if (!gspca_dev->streaming)
892 case V4L2_CID_BRIGHTNESS:
893 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
895 case V4L2_CID_CONTRAST:
896 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
898 case V4L2_CID_SATURATION:
899 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
900 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
902 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
903 jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
906 return gspca_dev->usb_err;
909 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
913 static int sd_init_controls(struct gspca_dev *gspca_dev)
915 struct sd *sd = (struct sd *)gspca_dev;
916 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
918 gspca_dev->vdev.ctrl_handler = hdl;
919 v4l2_ctrl_handler_init(hdl, 4);
920 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
921 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
922 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
923 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
924 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
925 V4L2_CID_SATURATION, 0, 7, 1, 3);
926 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
927 V4L2_CID_JPEG_COMPRESSION_QUALITY,
928 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
930 pr_err("Could not initialize controls\n");
936 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
937 struct v4l2_jpegcompression *jcomp)
939 struct sd *sd = (struct sd *) gspca_dev;
941 v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
945 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
946 struct v4l2_jpegcompression *jcomp)
948 struct sd *sd = (struct sd *) gspca_dev;
950 memset(jcomp, 0, sizeof *jcomp);
951 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
952 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
953 | V4L2_JPEG_MARKER_DQT;
957 /* sub-driver description */
958 static const struct sd_desc sd_desc = {
962 .init_controls = sd_init_controls,
965 .pkt_scan = sd_pkt_scan,
966 .get_jcomp = sd_get_jcomp,
967 .set_jcomp = sd_set_jcomp,
970 /* -- module initialisation -- */
971 static const struct usb_device_id device_table[] = {
972 {USB_DEVICE(0x0572, 0x0041)},
975 MODULE_DEVICE_TABLE(usb, device_table);
977 /* -- device connect -- */
978 static int sd_probe(struct usb_interface *intf,
979 const struct usb_device_id *id)
981 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
985 static struct usb_driver sd_driver = {
987 .id_table = device_table,
989 .disconnect = gspca_disconnect,
991 .suspend = gspca_suspend,
992 .resume = gspca_resume,
996 module_usb_driver(sd_driver);