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
/* specific webcam descriptor */
36
struct gspca_dev gspca_dev; /* !! must be the first item */
38
unsigned char brightness;
39
unsigned char contrast;
42
#define QUALITY_MIN 30
43
#define QUALITY_MAX 60
44
#define QUALITY_DEF 40
46
u8 jpeg_hdr[JPEG_HDR_SZ];
49
/* V4L2 controls supported by the driver */
50
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
51
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
52
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
53
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
54
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
55
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
57
static const struct ctrl sd_ctrls[] = {
60
.id = V4L2_CID_BRIGHTNESS,
61
.type = V4L2_CTRL_TYPE_INTEGER,
66
#define BRIGHTNESS_DEF 0xd4
67
.default_value = BRIGHTNESS_DEF,
69
.set = sd_setbrightness,
70
.get = sd_getbrightness,
74
.id = V4L2_CID_CONTRAST,
75
.type = V4L2_CTRL_TYPE_INTEGER,
80
#define CONTRAST_DEF 0x0c
81
.default_value = CONTRAST_DEF,
83
.set = sd_setcontrast,
84
.get = sd_getcontrast,
88
.id = V4L2_CID_SATURATION,
89
.type = V4L2_CTRL_TYPE_INTEGER,
95
.default_value = COLOR_DEF,
102
static const struct v4l2_pix_format vga_mode[] = {
103
{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
105
.sizeimage = 176 * 144 * 3 / 8 + 590,
106
.colorspace = V4L2_COLORSPACE_JPEG,
108
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
110
.sizeimage = 320 * 240 * 3 / 8 + 590,
111
.colorspace = V4L2_COLORSPACE_JPEG,
113
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
115
.sizeimage = 352 * 288 * 3 / 8 + 590,
116
.colorspace = V4L2_COLORSPACE_JPEG,
118
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
120
.sizeimage = 640 * 480 * 3 / 8 + 590,
121
.colorspace = V4L2_COLORSPACE_JPEG,
125
/* the read bytes are found in gspca_dev->usb_buf */
126
static void reg_r(struct gspca_dev *gspca_dev,
130
struct usb_device *dev = gspca_dev->dev;
133
if (len > USB_BUF_SZ) {
134
pr_err("reg_r: buffer overflow\n");
139
usb_rcvctrlpipe(dev, 0),
141
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
143
index, gspca_dev->usb_buf, len,
145
PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
146
index, gspca_dev->usb_buf[0]);
149
/* the bytes to write are in gspca_dev->usb_buf */
150
static void reg_w_val(struct gspca_dev *gspca_dev,
154
struct usb_device *dev = gspca_dev->dev;
156
gspca_dev->usb_buf[0] = val;
158
usb_sndctrlpipe(dev, 0),
160
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
162
index, gspca_dev->usb_buf, 1, 500);
165
static void reg_w(struct gspca_dev *gspca_dev,
170
struct usb_device *dev = gspca_dev->dev;
173
if (len > USB_BUF_SZ) {
174
pr_err("reg_w: buffer overflow\n");
177
PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
179
memcpy(gspca_dev->usb_buf, buffer, len);
181
usb_sndctrlpipe(dev, 0),
183
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
185
index, gspca_dev->usb_buf, len, 500);
188
static const __u8 cx_sensor_init[][4] = {
189
{0x88, 0x11, 0x01, 0x01},
190
{0x88, 0x12, 0x70, 0x01},
191
{0x88, 0x0f, 0x00, 0x01},
192
{0x88, 0x05, 0x01, 0x01},
196
static const __u8 cx11646_fw1[][3] = {
263
static void cx11646_fw(struct gspca_dev*gspca_dev)
267
reg_w_val(gspca_dev, 0x006a, 0x02);
268
while (cx11646_fw1[i][1]) {
269
reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
272
reg_w_val(gspca_dev, 0x006a, 0x00);
275
static const __u8 cxsensor[] = {
276
0x88, 0x12, 0x70, 0x01,
277
0x88, 0x0d, 0x02, 0x01,
278
0x88, 0x0f, 0x00, 0x01,
279
0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
280
0x88, 0x02, 0x10, 0x01,
281
0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
282
0x88, 0x0B, 0x00, 0x01,
283
0x88, 0x0A, 0x0A, 0x01,
284
0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
285
0x88, 0x05, 0x01, 0x01,
286
0xA1, 0x18, 0x00, 0x01,
290
static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
291
static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
292
static const __u8 reg10[] = { 0xb1, 0xb1 };
293
static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
294
static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
295
/* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
296
static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
297
/* 320{0x04,0x0c,0x05,0x0f}; //320 */
298
static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
299
static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
301
static void cx_sensor(struct gspca_dev*gspca_dev)
305
const __u8 *ptsensor = cxsensor;
307
reg_w(gspca_dev, 0x0020, reg20, 8);
308
reg_w(gspca_dev, 0x0028, reg28, 8);
309
reg_w(gspca_dev, 0x0010, reg10, 8);
310
reg_w_val(gspca_dev, 0x0092, 0x03);
312
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
314
reg_w(gspca_dev, 0x0071, reg71a, 4);
317
reg_w(gspca_dev, 0x0071, reg71b, 4);
321
reg_w(gspca_dev, 0x0071, reg71c, 4);
324
reg_w(gspca_dev, 0x0071, reg71d, 4);
327
reg_w(gspca_dev, 0x007b, reg7b, 6);
328
reg_w_val(gspca_dev, 0x00f8, 0x00);
329
reg_w(gspca_dev, 0x0010, reg10, 8);
330
reg_w_val(gspca_dev, 0x0098, 0x41);
331
for (i = 0; i < 11; i++) {
332
if (i == 3 || i == 5 || i == 8)
336
reg_w(gspca_dev, 0x00e5, ptsensor, length);
338
reg_r(gspca_dev, 0x00e8, 1);
340
reg_r(gspca_dev, 0x00e8, length);
343
reg_r(gspca_dev, 0x00e7, 8);
346
static const __u8 cx_inits_176[] = {
347
0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
348
0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
349
0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
350
0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
351
0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
352
0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
353
0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
355
static const __u8 cx_inits_320[] = {
356
0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
357
0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
358
0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
359
0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
360
0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
361
0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
362
0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
364
static const __u8 cx_inits_352[] = {
365
0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
366
0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
367
0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
368
0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
369
0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
370
0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
371
0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
373
static const __u8 cx_inits_640[] = {
374
0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
375
0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
376
0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
377
0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
378
0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
379
0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
380
0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
383
static void cx11646_initsize(struct gspca_dev *gspca_dev)
386
static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
387
static const __u8 reg17[] =
388
{ 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
390
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
392
cxinit = cx_inits_640;
395
cxinit = cx_inits_352;
399
cxinit = cx_inits_320;
402
cxinit = cx_inits_176;
405
reg_w_val(gspca_dev, 0x009a, 0x01);
406
reg_w_val(gspca_dev, 0x0010, 0x10);
407
reg_w(gspca_dev, 0x0012, reg12, 5);
408
reg_w(gspca_dev, 0x0017, reg17, 8);
409
reg_w_val(gspca_dev, 0x00c0, 0x00);
410
reg_w_val(gspca_dev, 0x00c1, 0x04);
411
reg_w_val(gspca_dev, 0x00c2, 0x04);
413
reg_w(gspca_dev, 0x0061, cxinit, 8);
415
reg_w(gspca_dev, 0x00ca, cxinit, 8);
417
reg_w(gspca_dev, 0x00d2, cxinit, 8);
419
reg_w(gspca_dev, 0x00da, cxinit, 6);
421
reg_w(gspca_dev, 0x0041, cxinit, 8);
423
reg_w(gspca_dev, 0x0049, cxinit, 8);
425
reg_w(gspca_dev, 0x0051, cxinit, 2);
427
reg_r(gspca_dev, 0x0010, 1);
430
static const __u8 cx_jpeg_init[][8] = {
431
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
432
{0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
433
{0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
434
{0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
435
{0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
436
{0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
437
{0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
438
{0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
439
{0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
440
{0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
441
{0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
442
{0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
443
{0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
444
{0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
445
{0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
446
{0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
447
{0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
448
{0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
449
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
450
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
451
{0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
452
{0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
453
{0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
454
{0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
455
{0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
456
{0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
457
{0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
458
{0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
459
{0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
460
{0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
461
{0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
462
{0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
463
{0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
464
{0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
465
{0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
466
{0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
467
{0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
468
{0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
469
{0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
470
{0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
471
{0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
472
{0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
473
{0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
474
{0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
475
{0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
476
{0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
477
{0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
478
{0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
479
{0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
480
{0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
481
{0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
482
{0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
483
{0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
484
{0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
485
{0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
486
{0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
487
{0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
488
{0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
489
{0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
490
{0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
491
{0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
492
{0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
493
{0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
494
{0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
495
{0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
496
{0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
497
{0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
498
{0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
499
{0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
500
{0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
501
{0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
502
{0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
503
{0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
504
{0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
505
{0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
506
{0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
507
{0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
508
{0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
509
{0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
513
static const __u8 cxjpeg_640[][8] = {
514
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
515
{0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
516
{0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
517
{0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
518
{0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
519
{0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
520
{0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
521
{0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
522
{0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
523
{0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
524
{0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
525
{0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
526
{0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
527
{0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
528
{0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
529
{0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
530
{0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
531
{0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 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, 0x28, 0xFF},
536
{0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
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_352[][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, 0x01, 0x83, 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, 0x16, 0xFF},
565
{0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
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
static const __u8 cxjpeg_320[][8] = {
572
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
573
{0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
574
{0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
575
{0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
576
{0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
577
{0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
578
{0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
579
{0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
580
{0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
581
{0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
582
{0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
583
{0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
584
{0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
585
{0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
586
{0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
587
{0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
588
{0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
589
{0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
590
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
591
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
592
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
593
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
594
{0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
595
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
596
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
597
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
598
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
600
static const __u8 cxjpeg_176[][8] = {
601
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
602
{0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
603
{0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
604
{0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
605
{0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
606
{0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
607
{0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
608
{0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
609
{0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
610
{0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
611
{0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
612
{0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
613
{0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
614
{0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
615
{0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
616
{0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
617
{0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
618
{0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
619
{0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
620
{0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
621
{0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
622
{0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
623
{0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
624
{0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
625
{0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
626
{0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
627
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
629
/* 640 take with the zcx30x part */
630
static const __u8 cxjpeg_qtable[][8] = {
631
{0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
632
{0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
633
{0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
634
{0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
635
{0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
636
{0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
637
{0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
638
{0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
639
{0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
640
{0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
641
{0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 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
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
647
{0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
648
{0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
652
static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
657
reg_w_val(gspca_dev, 0x00c0, 0x01);
658
reg_w_val(gspca_dev, 0x00c3, 0x00);
659
reg_w_val(gspca_dev, 0x00c0, 0x00);
660
reg_r(gspca_dev, 0x0001, 1);
662
for (i = 0; i < 79; i++) {
665
reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
667
reg_r(gspca_dev, 0x0002, 1);
668
reg_w_val(gspca_dev, 0x0055, 0x14);
671
static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
672
static const __u8 regE5_8[] =
673
{ 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
674
static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
675
static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
676
static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
677
static const __u8 reg51[] = { 0x77, 0x03 };
680
static void cx11646_jpeg(struct gspca_dev*gspca_dev)
687
reg_w_val(gspca_dev, 0x00c0, 0x01);
688
reg_w_val(gspca_dev, 0x00c3, 0x00);
689
reg_w_val(gspca_dev, 0x00c0, 0x00);
690
reg_r(gspca_dev, 0x0001, 1);
692
switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
694
for (i = 0; i < 27; i++) {
697
reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
702
for (i = 0; i < 27; i++) {
705
reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
711
for (i = 0; i < 27; i++) {
714
reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
719
for (i = 0; i < 27; i++) {
722
reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
728
reg_r(gspca_dev, 0x0002, 1);
729
reg_w_val(gspca_dev, 0x0055, Reg55);
730
reg_r(gspca_dev, 0x0002, 1);
731
reg_w(gspca_dev, 0x0010, reg10, 2);
732
reg_w_val(gspca_dev, 0x0054, 0x02);
733
reg_w_val(gspca_dev, 0x0054, 0x01);
734
reg_w_val(gspca_dev, 0x0000, 0x94);
735
reg_w_val(gspca_dev, 0x0053, 0xc0);
736
reg_w_val(gspca_dev, 0x00fc, 0xe1);
737
reg_w_val(gspca_dev, 0x0000, 0x00);
738
/* wait for completion */
741
reg_r(gspca_dev, 0x0002, 1);
742
/* 0x07 until 0x00 */
743
if (gspca_dev->usb_buf[0] == 0x00)
745
reg_w_val(gspca_dev, 0x0053, 0x00);
748
PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
749
/* send the qtable now */
750
reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
752
for (i = 0; i < 18; i++) {
755
reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
758
reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
759
reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
760
reg_w_val(gspca_dev, 0x0054, 0x02);
761
reg_w_val(gspca_dev, 0x0054, 0x01);
762
reg_w_val(gspca_dev, 0x0000, 0x94);
763
reg_w_val(gspca_dev, 0x0053, 0xc0);
765
reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
766
reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
767
reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
768
reg_w(gspca_dev, 0x0012, reg12, 5);
769
reg_w(gspca_dev, 0x00e5, regE5_8, 8);
770
reg_r(gspca_dev, 0x00e8, 8);
771
reg_w(gspca_dev, 0x00e5, regE5a, 4);
772
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
773
reg_w_val(gspca_dev, 0x009a, 0x01);
774
reg_w(gspca_dev, 0x00e5, regE5b, 4);
775
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
776
reg_w(gspca_dev, 0x00e5, regE5c, 4);
777
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
779
reg_w(gspca_dev, 0x0051, reg51, 2);
780
reg_w(gspca_dev, 0x0010, reg10, 2);
781
reg_w_val(gspca_dev, 0x0070, reg70);
784
static void cx11646_init1(struct gspca_dev *gspca_dev)
788
reg_w_val(gspca_dev, 0x0010, 0x00);
789
reg_w_val(gspca_dev, 0x0053, 0x00);
790
reg_w_val(gspca_dev, 0x0052, 0x00);
791
reg_w_val(gspca_dev, 0x009b, 0x2f);
792
reg_w_val(gspca_dev, 0x009c, 0x10);
793
reg_r(gspca_dev, 0x0098, 1);
794
reg_w_val(gspca_dev, 0x0098, 0x40);
795
reg_r(gspca_dev, 0x0099, 1);
796
reg_w_val(gspca_dev, 0x0099, 0x07);
797
reg_w_val(gspca_dev, 0x0039, 0x40);
798
reg_w_val(gspca_dev, 0x003c, 0xff);
799
reg_w_val(gspca_dev, 0x003f, 0x1f);
800
reg_w_val(gspca_dev, 0x003d, 0x40);
801
/* reg_w_val(gspca_dev, 0x003d, 0x60); */
802
reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
804
while (cx_sensor_init[i][0]) {
805
reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
806
reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
808
reg_w_val(gspca_dev, 0x00ed, 0x01);
809
reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
813
reg_w_val(gspca_dev, 0x00c3, 0x00);
816
/* this function is called at probe time */
817
static int sd_config(struct gspca_dev *gspca_dev,
818
const struct usb_device_id *id)
820
struct sd *sd = (struct sd *) gspca_dev;
823
cam = &gspca_dev->cam;
824
cam->cam_mode = vga_mode;
825
cam->nmodes = ARRAY_SIZE(vga_mode);
827
sd->brightness = BRIGHTNESS_DEF;
828
sd->contrast = CONTRAST_DEF;
829
sd->colors = COLOR_DEF;
830
sd->quality = QUALITY_DEF;
834
/* this function is called at probe and resume time */
835
static int sd_init(struct gspca_dev *gspca_dev)
837
cx11646_init1(gspca_dev);
838
cx11646_initsize(gspca_dev);
839
cx11646_fw(gspca_dev);
840
cx_sensor(gspca_dev);
841
cx11646_jpegInit(gspca_dev);
845
static int sd_start(struct gspca_dev *gspca_dev)
847
struct sd *sd = (struct sd *) gspca_dev;
849
/* create the JPEG header */
850
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
851
0x22); /* JPEG 411 */
852
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
854
cx11646_initsize(gspca_dev);
855
cx11646_fw(gspca_dev);
856
cx_sensor(gspca_dev);
857
cx11646_jpeg(gspca_dev);
861
/* called on streamoff with alt 0 and on disconnect */
862
static void sd_stop0(struct gspca_dev *gspca_dev)
866
if (!gspca_dev->present)
868
reg_w_val(gspca_dev, 0x0000, 0x00);
869
reg_r(gspca_dev, 0x0002, 1);
870
reg_w_val(gspca_dev, 0x0053, 0x00);
873
/* reg_r(gspca_dev, 0x0002, 1);*/
874
reg_r(gspca_dev, 0x0053, 1);
875
if (gspca_dev->usb_buf[0] == 0)
878
reg_w_val(gspca_dev, 0x0000, 0x00);
879
reg_r(gspca_dev, 0x0002, 1);
881
reg_w_val(gspca_dev, 0x0010, 0x00);
882
reg_r(gspca_dev, 0x0033, 1);
883
reg_w_val(gspca_dev, 0x00fc, 0xe0);
886
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
887
u8 *data, /* isoc packet */
888
int len) /* iso packet length */
890
struct sd *sd = (struct sd *) gspca_dev;
892
if (data[0] == 0xff && data[1] == 0xd8) {
895
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
897
/* put the JPEG header in the new frame */
898
gspca_frame_add(gspca_dev, FIRST_PACKET,
899
sd->jpeg_hdr, JPEG_HDR_SZ);
903
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
906
static void setbrightness(struct gspca_dev *gspca_dev)
908
struct sd *sd = (struct sd *) gspca_dev;
909
__u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
914
bright = sd->brightness;
915
regE5cbx[2] = bright;
916
reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
917
reg_r(gspca_dev, 0x00e8, 8);
918
reg_w(gspca_dev, 0x00e5, regE5c, 4);
919
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
924
reg_w(gspca_dev, 0x0051, reg51c, 2);
925
reg_w(gspca_dev, 0x0010, reg10, 2);
926
reg_w_val(gspca_dev, 0x0070, reg70);
929
static void setcontrast(struct gspca_dev *gspca_dev)
931
struct sd *sd = (struct sd *) gspca_dev;
932
__u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
933
/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
936
regE5acx[2] = sd->contrast;
937
reg_w(gspca_dev, 0x00e5, regE5acx, 4);
938
reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
940
reg51c[1] = sd->colors;
941
reg_w(gspca_dev, 0x0051, reg51c, 2);
942
reg_w(gspca_dev, 0x0010, reg10, 2);
943
reg_w_val(gspca_dev, 0x0070, reg70);
946
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
948
struct sd *sd = (struct sd *) gspca_dev;
950
sd->brightness = val;
951
if (gspca_dev->streaming)
952
setbrightness(gspca_dev);
956
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
958
struct sd *sd = (struct sd *) gspca_dev;
960
*val = sd->brightness;
964
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
966
struct sd *sd = (struct sd *) gspca_dev;
969
if (gspca_dev->streaming)
970
setcontrast(gspca_dev);
974
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
976
struct sd *sd = (struct sd *) gspca_dev;
982
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
984
struct sd *sd = (struct sd *) gspca_dev;
987
if (gspca_dev->streaming) {
988
setbrightness(gspca_dev);
989
setcontrast(gspca_dev);
994
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
996
struct sd *sd = (struct sd *) gspca_dev;
1002
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1003
struct v4l2_jpegcompression *jcomp)
1005
struct sd *sd = (struct sd *) gspca_dev;
1007
if (jcomp->quality < QUALITY_MIN)
1008
sd->quality = QUALITY_MIN;
1009
else if (jcomp->quality > QUALITY_MAX)
1010
sd->quality = QUALITY_MAX;
1012
sd->quality = jcomp->quality;
1013
if (gspca_dev->streaming)
1014
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1018
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1019
struct v4l2_jpegcompression *jcomp)
1021
struct sd *sd = (struct sd *) gspca_dev;
1023
memset(jcomp, 0, sizeof *jcomp);
1024
jcomp->quality = sd->quality;
1025
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1026
| V4L2_JPEG_MARKER_DQT;
1030
/* sub-driver description */
1031
static const struct sd_desc sd_desc = {
1032
.name = MODULE_NAME,
1034
.nctrls = ARRAY_SIZE(sd_ctrls),
1035
.config = sd_config,
1039
.pkt_scan = sd_pkt_scan,
1040
.get_jcomp = sd_get_jcomp,
1041
.set_jcomp = sd_set_jcomp,
1044
/* -- module initialisation -- */
1045
static const struct usb_device_id device_table[] = {
1046
{USB_DEVICE(0x0572, 0x0041)},
1049
MODULE_DEVICE_TABLE(usb, device_table);
1051
/* -- device connect -- */
1052
static int sd_probe(struct usb_interface *intf,
1053
const struct usb_device_id *id)
1055
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1059
static struct usb_driver sd_driver = {
1060
.name = MODULE_NAME,
1061
.id_table = device_table,
1063
.disconnect = gspca_disconnect,
1065
.suspend = gspca_suspend,
1066
.resume = gspca_resume,
1070
/* -- module insert / remove -- */
1071
static int __init sd_mod_init(void)
1073
return usb_register(&sd_driver);
1075
static void __exit sd_mod_exit(void)
1077
usb_deregister(&sd_driver);
1080
module_init(sd_mod_init);
1081
module_exit(sd_mod_exit);