aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/pac7311.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/pac7311.c')
-rw-r--r--drivers/media/video/gspca/pac7311.c716
1 files changed, 257 insertions, 459 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 052714484e83..e5697a6345e8 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -57,23 +57,17 @@ MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
57MODULE_DESCRIPTION("Pixart PAC7311"); 57MODULE_DESCRIPTION("Pixart PAC7311");
58MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
59 59
60/* specific webcam descriptor */ 60/* specific webcam descriptor for pac7311 */
61struct sd { 61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */ 62 struct gspca_dev gspca_dev; /* !! must be the first item */
63 63
64 unsigned char brightness;
65 unsigned char contrast; 64 unsigned char contrast;
66 unsigned char colors;
67 unsigned char gain; 65 unsigned char gain;
68 unsigned char exposure; 66 unsigned char exposure;
69 unsigned char autogain; 67 unsigned char autogain;
70 __u8 hflip; 68 __u8 hflip;
71 __u8 vflip; 69 __u8 vflip;
72 70
73 __u8 sensor;
74#define SENSOR_PAC7302 0
75#define SENSOR_PAC7311 1
76
77 u8 sof_read; 71 u8 sof_read;
78 u8 autogain_ignore_frames; 72 u8 autogain_ignore_frames;
79 73
@@ -81,12 +75,8 @@ struct sd {
81}; 75};
82 76
83/* V4L2 controls supported by the driver */ 77/* V4L2 controls supported by the driver */
84static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 82static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -99,23 +89,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
100 90
101static struct ctrl sd_ctrls[] = { 91static struct ctrl sd_ctrls[] = {
102/* This control is pac7302 only */
103#define BRIGHTNESS_IDX 0
104 {
105 {
106 .id = V4L2_CID_BRIGHTNESS,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Brightness",
109 .minimum = 0,
110#define BRIGHTNESS_MAX 0x20
111 .maximum = BRIGHTNESS_MAX,
112 .step = 1,
113#define BRIGHTNESS_DEF 0x10
114 .default_value = BRIGHTNESS_DEF,
115 },
116 .set = sd_setbrightness,
117 .get = sd_getbrightness,
118 },
119/* This control is for both the 7302 and the 7311 */ 92/* This control is for both the 7302 and the 7311 */
120 { 93 {
121 { 94 {
@@ -132,23 +105,6 @@ static struct ctrl sd_ctrls[] = {
132 .set = sd_setcontrast, 105 .set = sd_setcontrast,
133 .get = sd_getcontrast, 106 .get = sd_getcontrast,
134 }, 107 },
135/* This control is pac7302 only */
136#define SATURATION_IDX 2
137 {
138 {
139 .id = V4L2_CID_SATURATION,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Saturation",
142 .minimum = 0,
143#define COLOR_MAX 255
144 .maximum = COLOR_MAX,
145 .step = 1,
146#define COLOR_DEF 127
147 .default_value = COLOR_DEF,
148 },
149 .set = sd_setcolors,
150 .get = sd_getcolors,
151 },
152/* All controls below are for both the 7302 and the 7311 */ 108/* All controls below are for both the 7302 and the 7311 */
153 { 109 {
154 { 110 {
@@ -244,101 +200,9 @@ static const struct v4l2_pix_format vga_mode[] = {
244 .priv = 0}, 200 .priv = 0},
245}; 201};
246 202
247/* pac 7302 */ 203#define LOAD_PAGE3 255
248static const __u8 init_7302[] = { 204#define LOAD_PAGE4 254
249/* index,value */ 205#define END_OF_SEQUENCE 0
250 0xff, 0x01, /* page 1 */
251 0x78, 0x00, /* deactivate */
252 0xff, 0x01,
253 0x78, 0x40, /* led off */
254};
255static const __u8 start_7302[] = {
256/* index, len, [value]* */
257 0xff, 1, 0x00, /* page 0 */
258 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
259 0x00, 0x00, 0x00, 0x00,
260 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
261 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
262 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
263 0x26, 2, 0xaa, 0xaa,
264 0x2e, 1, 0x31,
265 0x38, 1, 0x01,
266 0x3a, 3, 0x14, 0xff, 0x5a,
267 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
268 0x00, 0x54, 0x11,
269 0x55, 1, 0x00,
270 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
271 0x6b, 1, 0x00,
272 0x6e, 3, 0x08, 0x06, 0x00,
273 0x72, 3, 0x00, 0xff, 0x00,
274 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
275 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
276 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
277 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
278 0xd2, 0xeb,
279 0xaf, 1, 0x02,
280 0xb5, 2, 0x08, 0x08,
281 0xb8, 2, 0x08, 0x88,
282 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
283 0xcc, 1, 0x00,
284 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
285 0xc1, 0xd7, 0xec,
286 0xdc, 1, 0x01,
287 0xff, 1, 0x01, /* page 1 */
288 0x12, 3, 0x02, 0x00, 0x01,
289 0x3e, 2, 0x00, 0x00,
290 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
291 0x7c, 1, 0x00,
292 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
293 0x02, 0x00,
294 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
295 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
296 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
297 0xd8, 1, 0x01,
298 0xdb, 2, 0x00, 0x01,
299 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
300 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
301 0xeb, 1, 0x00,
302 0xff, 1, 0x02, /* page 2 */
303 0x22, 1, 0x00,
304 0xff, 1, 0x03, /* page 3 */
305 0x00, 255, /* load the page 3 */
306 0x11, 1, 0x01,
307 0xff, 1, 0x02, /* page 2 */
308 0x13, 1, 0x00,
309 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
310 0x27, 2, 0x14, 0x0c,
311 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
312 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
313 0x6e, 1, 0x08,
314 0xff, 1, 0x01, /* page 1 */
315 0x78, 1, 0x00,
316 0, 0 /* end of sequence */
317};
318
319/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320static const __u8 page3_7302[] = {
321 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340 0x00
341};
342 206
343/* pac 7311 */ 207/* pac 7311 */
344static const __u8 init_7311[] = { 208static const __u8 init_7311[] = {
@@ -378,119 +242,154 @@ static const __u8 start_7311[] = {
378 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, 242 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379 0x3f, 0x00, 0x0a, 0x01, 0x00, 243 0x3f, 0x00, 0x0a, 0x01, 0x00,
380 0xff, 1, 0x04, /* page 4 */ 244 0xff, 1, 0x04, /* page 4 */
381 0x00, 254, /* load the page 4 */ 245 0, LOAD_PAGE4, /* load the page 4 */
382 0x11, 1, 0x01, 246 0x11, 1, 0x01,
383 0, 0 /* end of sequence */ 247 0, END_OF_SEQUENCE /* end of sequence */
384}; 248};
385 249
386/* page 4 - the value 0xaa says skip the index - see reg_w_page() */ 250#define SKIP 0xaa
251/* page 4 - the value SKIP says skip the index - see reg_w_page() */
387static const __u8 page4_7311[] = { 252static const __u8 page4_7311[] = {
388 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, 253 SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, 254 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
390 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 255 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, 256 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
392 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68, 257 SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
393 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 258 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
395}; 260};
396 261
397static void reg_w_buf(struct gspca_dev *gspca_dev, 262static int reg_w_buf(struct gspca_dev *gspca_dev,
398 __u8 index, 263 __u8 index,
399 const char *buffer, int len) 264 const char *buffer, int len)
400{ 265{
266 int ret;
267
401 memcpy(gspca_dev->usb_buf, buffer, len); 268 memcpy(gspca_dev->usb_buf, buffer, len);
402 usb_control_msg(gspca_dev->dev, 269 ret = usb_control_msg(gspca_dev->dev,
403 usb_sndctrlpipe(gspca_dev->dev, 0), 270 usb_sndctrlpipe(gspca_dev->dev, 0),
404 1, /* request */ 271 1, /* request */
405 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 272 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
406 0, /* value */ 273 0, /* value */
407 index, gspca_dev->usb_buf, len, 274 index, gspca_dev->usb_buf, len,
408 500); 275 500);
276 if (ret < 0)
277 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i",
279 index, ret);
280 return ret;
409} 281}
410 282
411 283
412static void reg_w(struct gspca_dev *gspca_dev, 284static int reg_w(struct gspca_dev *gspca_dev,
413 __u8 index, 285 __u8 index,
414 __u8 value) 286 __u8 value)
415{ 287{
288 int ret;
289
416 gspca_dev->usb_buf[0] = value; 290 gspca_dev->usb_buf[0] = value;
417 usb_control_msg(gspca_dev->dev, 291 ret = usb_control_msg(gspca_dev->dev,
418 usb_sndctrlpipe(gspca_dev->dev, 0), 292 usb_sndctrlpipe(gspca_dev->dev, 0),
419 0, /* request */ 293 0, /* request */
420 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421 0, index, gspca_dev->usb_buf, 1, 295 0, index, gspca_dev->usb_buf, 1,
422 500); 296 500);
297 if (ret < 0)
298 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret);
301 return ret;
423} 302}
424 303
425static void reg_w_seq(struct gspca_dev *gspca_dev, 304static int reg_w_seq(struct gspca_dev *gspca_dev,
426 const __u8 *seq, int len) 305 const __u8 *seq, int len)
427{ 306{
307 int ret = 0;
428 while (--len >= 0) { 308 while (--len >= 0) {
429 reg_w(gspca_dev, seq[0], seq[1]); 309 if (0 <= ret)
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
430 seq += 2; 311 seq += 2;
431 } 312 }
313 return ret;
432} 314}
433 315
434/* load the beginning of a page */ 316/* load the beginning of a page */
435static void reg_w_page(struct gspca_dev *gspca_dev, 317static int reg_w_page(struct gspca_dev *gspca_dev,
436 const __u8 *page, int len) 318 const __u8 *page, int len)
437{ 319{
438 int index; 320 int index;
321 int ret = 0;
439 322
440 for (index = 0; index < len; index++) { 323 for (index = 0; index < len; index++) {
441 if (page[index] == 0xaa) /* skip this index */ 324 if (page[index] == SKIP) /* skip this index */
442 continue; 325 continue;
443 gspca_dev->usb_buf[0] = page[index]; 326 gspca_dev->usb_buf[0] = page[index];
444 usb_control_msg(gspca_dev->dev, 327 ret = usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0), 328 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */ 329 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 330 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, index, gspca_dev->usb_buf, 1, 331 0, index, gspca_dev->usb_buf, 1,
449 500); 332 500);
333 if (ret < 0) {
334 PDEBUG(D_ERR, "reg_w_page(): "
335 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i",
337 index, page[index], ret);
338 break;
339 }
450 } 340 }
341 return ret;
451} 342}
452 343
453/* output a variable sequence */ 344/* output a variable sequence */
454static void reg_w_var(struct gspca_dev *gspca_dev, 345static int reg_w_var(struct gspca_dev *gspca_dev,
455 const __u8 *seq) 346 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len)
456{ 349{
457 int index, len; 350 int index, len;
351 int ret = 0;
458 352
459 for (;;) { 353 for (;;) {
460 index = *seq++; 354 index = *seq++;
461 len = *seq++; 355 len = *seq++;
462 switch (len) { 356 switch (len) {
463 case 0: 357 case END_OF_SEQUENCE:
464 return; 358 return ret;
465 case 254: 359 case LOAD_PAGE4:
466 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); 360 ret = reg_w_page(gspca_dev, page4, page4_len);
467 break; 361 break;
468 case 255: 362 case LOAD_PAGE3:
469 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); 363 ret = reg_w_page(gspca_dev, page3, page3_len);
470 break; 364 break;
471 default: 365 default:
472 if (len > 64) { 366 if (len > USB_BUF_SZ) {
473 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
474 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
475 return; 369 return -EINVAL;
476 } 370 }
477 while (len > 0) { 371 while (len > 0) {
478 if (len < 8) { 372 if (len < 8) {
479 reg_w_buf(gspca_dev, index, seq, len); 373 ret = reg_w_buf(gspca_dev,
374 index, seq, len);
375 if (ret < 0)
376 return ret;
480 seq += len; 377 seq += len;
481 break; 378 break;
482 } 379 }
483 reg_w_buf(gspca_dev, index, seq, 8); 380 ret = reg_w_buf(gspca_dev, index, seq, 8);
484 seq += 8; 381 seq += 8;
485 index += 8; 382 index += 8;
486 len -= 8; 383 len -= 8;
487 } 384 }
488 } 385 }
386 if (ret < 0)
387 return ret;
489 } 388 }
490 /* not reached */ 389 /* not reached */
491} 390}
492 391
493/* this function is called at probe time */ 392/* this function is called at probe time for pac7311 */
494static int sd_config(struct gspca_dev *gspca_dev, 393static int sd_config(struct gspca_dev *gspca_dev,
495 const struct usb_device_id *id) 394 const struct usb_device_id *id)
496{ 395{
@@ -499,22 +398,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
499 398
500 cam = &gspca_dev->cam; 399 cam = &gspca_dev->cam;
501 400
502 sd->sensor = id->driver_info; 401 PDEBUG(D_CONF, "Find Sensor PAC7311");
503 if (sd->sensor == SENSOR_PAC7302) { 402 cam->cam_mode = vga_mode;
504 PDEBUG(D_CONF, "Find Sensor PAC7302"); 403 cam->nmodes = ARRAY_SIZE(vga_mode);
505 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
506 cam->nmodes = 1;
507 } else {
508 PDEBUG(D_CONF, "Find Sensor PAC7311");
509 cam->cam_mode = vga_mode;
510 cam->nmodes = ARRAY_SIZE(vga_mode);
511 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
512 | (1 << SATURATION_IDX);
513 }
514 404
515 sd->brightness = BRIGHTNESS_DEF;
516 sd->contrast = CONTRAST_DEF; 405 sd->contrast = CONTRAST_DEF;
517 sd->colors = COLOR_DEF;
518 sd->gain = GAIN_DEF; 406 sd->gain = GAIN_DEF;
519 sd->exposure = EXPOSURE_DEF; 407 sd->exposure = EXPOSURE_DEF;
520 sd->autogain = AUTOGAIN_DEF; 408 sd->autogain = AUTOGAIN_DEF;
@@ -523,91 +411,47 @@ static int sd_config(struct gspca_dev *gspca_dev,
523 return 0; 411 return 0;
524} 412}
525 413
526/* This function is used by pac7302 only */
527static void setbrightcont(struct gspca_dev *gspca_dev)
528{
529 struct sd *sd = (struct sd *) gspca_dev;
530 int i, v;
531 static const __u8 max[10] =
532 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
533 0xd4, 0xec};
534 static const __u8 delta[10] =
535 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
536 0x11, 0x0b};
537
538 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
539 for (i = 0; i < 10; i++) {
540 v = max[i];
541 v += (sd->brightness - BRIGHTNESS_MAX)
542 * 150 / BRIGHTNESS_MAX; /* 200 ? */
543 v -= delta[i] * sd->contrast / CONTRAST_MAX;
544 if (v < 0)
545 v = 0;
546 else if (v > 0xff)
547 v = 0xff;
548 reg_w(gspca_dev, 0xa2 + i, v);
549 }
550 reg_w(gspca_dev, 0xdc, 0x01);
551}
552
553/* This function is used by pac7311 only */ 414/* This function is used by pac7311 only */
554static void setcontrast(struct gspca_dev *gspca_dev) 415static int setcontrast(struct gspca_dev *gspca_dev)
555{ 416{
556 struct sd *sd = (struct sd *) gspca_dev; 417 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
557 419
558 reg_w(gspca_dev, 0xff, 0x04); 420 ret = reg_w(gspca_dev, 0xff, 0x04);
559 reg_w(gspca_dev, 0x10, sd->contrast >> 4); 421 if (0 <= ret)
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
560 /* load registers to sensor (Bit 0, auto clear) */ 423 /* load registers to sensor (Bit 0, auto clear) */
561 reg_w(gspca_dev, 0x11, 0x01); 424 if (0 <= ret)
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
562} 427}
563 428
564/* This function is used by pac7302 only */ 429static int setgain(struct gspca_dev *gspca_dev)
565static void setcolors(struct gspca_dev *gspca_dev)
566{ 430{
567 struct sd *sd = (struct sd *) gspca_dev; 431 struct sd *sd = (struct sd *) gspca_dev;
568 int i, v; 432 int gain = GAIN_MAX - sd->gain;
569 static const int a[9] = 433 int ret;
570 {217, -212, 0, -101, 170, -67, -38, -315, 355};
571 static const int b[9] =
572 {19, 106, 0, 19, 106, 1, 19, 106, 1};
573
574 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
575 reg_w(gspca_dev, 0x11, 0x01);
576 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
577 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
578 for (i = 0; i < 9; i++) {
579 v = a[i] * sd->colors / COLOR_MAX + b[i];
580 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
581 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
582 }
583 reg_w(gspca_dev, 0xdc, 0x01);
584 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
585}
586 434
587static void setgain(struct gspca_dev *gspca_dev) 435 if (gain < 1)
588{ 436 gain = 1;
589 struct sd *sd = (struct sd *) gspca_dev; 437 else if (gain > 245)
438 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret)
441 ret = reg_w(gspca_dev, 0x0e, 0x00);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
590 444
591 if (sd->sensor == SENSOR_PAC7302) {
592 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
593 reg_w(gspca_dev, 0x10, sd->gain >> 3);
594 } else {
595 int gain = GAIN_MAX - sd->gain;
596 if (gain < 1)
597 gain = 1;
598 else if (gain > 245)
599 gain = 245;
600 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
601 reg_w(gspca_dev, 0x0e, 0x00);
602 reg_w(gspca_dev, 0x0f, gain);
603 }
604 /* load registers to sensor (Bit 0, auto clear) */ 445 /* load registers to sensor (Bit 0, auto clear) */
605 reg_w(gspca_dev, 0x11, 0x01); 446 if (0 <= ret)
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
606} 449}
607 450
608static void setexposure(struct gspca_dev *gspca_dev) 451static int setexposure(struct gspca_dev *gspca_dev)
609{ 452{
610 struct sd *sd = (struct sd *) gspca_dev; 453 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
611 __u8 reg; 455 __u8 reg;
612 456
613 /* register 2 of frame 3/4 contains the clock divider configuring the 457 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -619,97 +463,94 @@ static void setexposure(struct gspca_dev *gspca_dev)
619 else if (reg > 63) 463 else if (reg > 63)
620 reg = 63; 464 reg = 63;
621 465
622 if (sd->sensor == SENSOR_PAC7302) { 466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
623 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 467 if (0 <= ret)
624 the nearest multiple of 3, except when between 6 and 12? */ 468 ret = reg_w(gspca_dev, 0x02, reg);
625 if (reg < 6 || reg > 12) 469 /* Page 1 register 8 must always be 0x08 except when not in
626 reg = ((reg + 1) / 3) * 3; 470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
627 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 471 if (0 <= ret)
628 reg_w(gspca_dev, 0x02, reg); 472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) {
475 if (0 <= ret)
476 ret = reg_w(gspca_dev, 0x08, 0x09);
629 } else { 477 } else {
630 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 478 if (0 <= ret)
631 reg_w(gspca_dev, 0x02, reg); 479 ret = reg_w(gspca_dev, 0x08, 0x08);
632 /* Page 1 register 8 must always be 0x08 except when not in
633 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
634 reg_w(gspca_dev, 0xff, 0x01);
635 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
636 reg <= 3)
637 reg_w(gspca_dev, 0x08, 0x09);
638 else
639 reg_w(gspca_dev, 0x08, 0x08);
640 } 480 }
481
641 /* load registers to sensor (Bit 0, auto clear) */ 482 /* load registers to sensor (Bit 0, auto clear) */
642 reg_w(gspca_dev, 0x11, 0x01); 483 if (0 <= ret)
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
643} 486}
644 487
645static void sethvflip(struct gspca_dev *gspca_dev) 488static int sethvflip(struct gspca_dev *gspca_dev)
646{ 489{
647 struct sd *sd = (struct sd *) gspca_dev; 490 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
648 __u8 data; 492 __u8 data;
649 493
650 if (sd->sensor == SENSOR_PAC7302) { 494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
651 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
652 data = (sd->hflip ? 0x08 : 0x00) 496 if (0 <= ret)
653 | (sd->vflip ? 0x04 : 0x00); 497 ret = reg_w(gspca_dev, 0x21, data);
654 } else {
655 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
656 data = (sd->hflip ? 0x04 : 0x00)
657 | (sd->vflip ? 0x08 : 0x00);
658 }
659 reg_w(gspca_dev, 0x21, data);
660 /* load registers to sensor (Bit 0, auto clear) */ 498 /* load registers to sensor (Bit 0, auto clear) */
661 reg_w(gspca_dev, 0x11, 0x01); 499 if (0 <= ret)
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
662} 502}
663 503
664/* this function is called at probe and resume time */ 504/* this function is called at probe and resume time for pac7311 */
665static int sd_init(struct gspca_dev *gspca_dev) 505static int sd_init(struct gspca_dev *gspca_dev)
666{ 506{
667 struct sd *sd = (struct sd *) gspca_dev; 507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
668
669 if (sd->sensor == SENSOR_PAC7302)
670 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
671 else
672 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
673
674 return 0;
675} 508}
676 509
677static int sd_start(struct gspca_dev *gspca_dev) 510static int sd_start(struct gspca_dev *gspca_dev)
678{ 511{
679 struct sd *sd = (struct sd *) gspca_dev; 512 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
680 514
681 sd->sof_read = 0; 515 sd->sof_read = 0;
682 516
683 if (sd->sensor == SENSOR_PAC7302) { 517 ret = reg_w_var(gspca_dev, start_7311,
684 reg_w_var(gspca_dev, start_7302); 518 NULL, 0,
685 setbrightcont(gspca_dev); 519 page4_7311, sizeof(page4_7311));
686 setcolors(gspca_dev); 520 if (0 <= ret)
687 } else { 521 ret = setcontrast(gspca_dev);
688 reg_w_var(gspca_dev, start_7311); 522 if (0 <= ret)
689 setcontrast(gspca_dev); 523 ret = setgain(gspca_dev);
690 } 524 if (0 <= ret)
691 setgain(gspca_dev); 525 ret = setexposure(gspca_dev);
692 setexposure(gspca_dev); 526 if (0 <= ret)
693 sethvflip(gspca_dev); 527 ret = sethvflip(gspca_dev);
694 528
695 /* set correct resolution */ 529 /* set correct resolution */
696 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
697 case 2: /* 160x120 pac7311 */ 531 case 2: /* 160x120 pac7311 */
698 reg_w(gspca_dev, 0xff, 0x01); 532 if (0 <= ret)
699 reg_w(gspca_dev, 0x17, 0x20); 533 ret = reg_w(gspca_dev, 0xff, 0x01);
700 reg_w(gspca_dev, 0x87, 0x10); 534 if (0 <= ret)
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
701 break; 538 break;
702 case 1: /* 320x240 pac7311 */ 539 case 1: /* 320x240 pac7311 */
703 reg_w(gspca_dev, 0xff, 0x01); 540 if (0 <= ret)
704 reg_w(gspca_dev, 0x17, 0x30); 541 ret = reg_w(gspca_dev, 0xff, 0x01);
705 reg_w(gspca_dev, 0x87, 0x11); 542 if (0 <= ret)
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
706 break; 546 break;
707 case 0: /* 640x480 */ 547 case 0: /* 640x480 */
708 if (sd->sensor == SENSOR_PAC7302) 548 if (0 <= ret)
709 break; 549 ret = reg_w(gspca_dev, 0xff, 0x01);
710 reg_w(gspca_dev, 0xff, 0x01); 550 if (0 <= ret)
711 reg_w(gspca_dev, 0x17, 0x00); 551 ret = reg_w(gspca_dev, 0x17, 0x00);
712 reg_w(gspca_dev, 0x87, 0x12); 552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
713 break; 554 break;
714 } 555 }
715 556
@@ -718,47 +559,42 @@ static int sd_start(struct gspca_dev *gspca_dev)
718 atomic_set(&sd->avg_lum, -1); 559 atomic_set(&sd->avg_lum, -1);
719 560
720 /* start stream */ 561 /* start stream */
721 reg_w(gspca_dev, 0xff, 0x01); 562 if (0 <= ret)
722 if (sd->sensor == SENSOR_PAC7302) 563 ret = reg_w(gspca_dev, 0xff, 0x01);
723 reg_w(gspca_dev, 0x78, 0x01); 564 if (0 <= ret)
724 else 565 ret = reg_w(gspca_dev, 0x78, 0x05);
725 reg_w(gspca_dev, 0x78, 0x05); 566
726 return 0; 567 return ret;
727} 568}
728 569
729static void sd_stopN(struct gspca_dev *gspca_dev) 570static void sd_stopN(struct gspca_dev *gspca_dev)
730{ 571{
731 struct sd *sd = (struct sd *) gspca_dev; 572 int ret;
732
733 if (sd->sensor == SENSOR_PAC7302) {
734 reg_w(gspca_dev, 0xff, 0x01);
735 reg_w(gspca_dev, 0x78, 0x00);
736 reg_w(gspca_dev, 0x78, 0x00);
737 return;
738 }
739 reg_w(gspca_dev, 0xff, 0x04);
740 reg_w(gspca_dev, 0x27, 0x80);
741 reg_w(gspca_dev, 0x28, 0xca);
742 reg_w(gspca_dev, 0x29, 0x53);
743 reg_w(gspca_dev, 0x2a, 0x0e);
744 reg_w(gspca_dev, 0xff, 0x01);
745 reg_w(gspca_dev, 0x3e, 0x20);
746 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
747 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
748 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
749}
750 573
751/* called on streamoff with alt 0 and on disconnect */ 574 ret = reg_w(gspca_dev, 0xff, 0x04);
575 if (0 <= ret)
576 ret = reg_w(gspca_dev, 0x27, 0x80);
577 if (0 <= ret)
578 ret = reg_w(gspca_dev, 0x28, 0xca);
579 if (0 <= ret)
580 ret = reg_w(gspca_dev, 0x29, 0x53);
581 if (0 <= ret)
582 ret = reg_w(gspca_dev, 0x2a, 0x0e);
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0xff, 0x01);
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x3e, 0x20);
587 if (0 <= ret)
588 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
589 if (0 <= ret)
590 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
591 if (0 <= ret)
592 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
593}
594
595/* called on streamoff with alt 0 and on disconnect for 7311 */
752static void sd_stop0(struct gspca_dev *gspca_dev) 596static void sd_stop0(struct gspca_dev *gspca_dev)
753{ 597{
754 struct sd *sd = (struct sd *) gspca_dev;
755
756 if (!gspca_dev->present)
757 return;
758 if (sd->sensor == SENSOR_PAC7302) {
759 reg_w(gspca_dev, 0xff, 0x01);
760 reg_w(gspca_dev, 0x78, 0x40);
761 }
762} 598}
763 599
764/* Include pac common sof detection functions */ 600/* Include pac common sof detection functions */
@@ -773,22 +609,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
773 if (avg_lum == -1) 609 if (avg_lum == -1)
774 return; 610 return;
775 611
776 if (sd->sensor == SENSOR_PAC7302) { 612 desired_lum = 200;
777 desired_lum = 270 + sd->brightness * 4; 613 deadzone = 20;
778 /* Hack hack, with the 7202 the first exposure step is
779 pretty large, so if we're about to make the first
780 exposure increase make the deadzone large to avoid
781 oscilating */
782 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
783 sd->exposure > EXPOSURE_DEF &&
784 sd->exposure < 42)
785 deadzone = 90;
786 else
787 deadzone = 30;
788 } else {
789 desired_lum = 200;
790 deadzone = 20;
791 }
792 614
793 if (sd->autogain_ignore_frames > 0) 615 if (sd->autogain_ignore_frames > 0)
794 sd->autogain_ignore_frames--; 616 sd->autogain_ignore_frames--;
@@ -797,53 +619,92 @@ static void do_autogain(struct gspca_dev *gspca_dev)
797 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 619 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
798} 620}
799 621
800static const unsigned char pac7311_jpeg_header1[] = { 622/* JPEG header, part 1 */
801 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08 623static const unsigned char pac_jpeg_header1[] = {
624 0xff, 0xd8, /* SOI: Start of Image */
625
626 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
627 0x00, 0x11, /* length = 17 bytes (including this length field) */
628 0x08 /* Precision: 8 */
629 /* 2 bytes is placed here: number of image lines */
630 /* 2 bytes is placed here: samples per line */
802}; 631};
803 632
804static const unsigned char pac7311_jpeg_header2[] = { 633/* JPEG header, continued */
805 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 634static const unsigned char pac_jpeg_header2[] = {
806 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 635 0x03, /* Number of image components: 3 */
636 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
637 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
638 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
639
640 0xff, 0xda, /* SOS: Start Of Scan */
641 0x00, 0x0c, /* length = 12 bytes (including this length field) */
642 0x03, /* number of components: 3 */
643 0x01, 0x00, /* selector 1, table 0x00 */
644 0x02, 0x11, /* selector 2, table 0x11 */
645 0x03, 0x11, /* selector 3, table 0x11 */
646 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
647 0x00 /* Successive approximation: 0 */
807}; 648};
808 649
650static void pac_start_frame(struct gspca_dev *gspca_dev,
651 struct gspca_frame *frame,
652 __u16 lines, __u16 samples_per_line)
653{
654 unsigned char tmpbuf[4];
655
656 gspca_frame_add(gspca_dev, FIRST_PACKET,
657 pac_jpeg_header1, sizeof(pac_jpeg_header1));
658
659 tmpbuf[0] = lines >> 8;
660 tmpbuf[1] = lines & 0xff;
661 tmpbuf[2] = samples_per_line >> 8;
662 tmpbuf[3] = samples_per_line & 0xff;
663
664 gspca_frame_add(gspca_dev, INTER_PACKET,
665 tmpbuf, sizeof(tmpbuf));
666 gspca_frame_add(gspca_dev, INTER_PACKET,
667 pac_jpeg_header2, sizeof(pac_jpeg_header2));
668}
669
809/* this function is run at interrupt level */ 670/* this function is run at interrupt level */
810static void sd_pkt_scan(struct gspca_dev *gspca_dev, 671static void sd_pkt_scan(struct gspca_dev *gspca_dev,
811 struct gspca_frame *frame, /* target */ 672 u8 *data, /* isoc packet */
812 __u8 *data, /* isoc packet */
813 int len) /* iso packet length */ 673 int len) /* iso packet length */
814{ 674{
815 struct sd *sd = (struct sd *) gspca_dev; 675 struct sd *sd = (struct sd *) gspca_dev;
816 unsigned char *sof; 676 unsigned char *sof;
677 struct gspca_frame *frame;
817 678
818 sof = pac_find_sof(gspca_dev, data, len); 679 sof = pac_find_sof(&sd->sof_read, data, len);
819 if (sof) { 680 if (sof) {
820 unsigned char tmpbuf[4];
821 int n, lum_offset, footer_length; 681 int n, lum_offset, footer_length;
822 682
823 if (sd->sensor == SENSOR_PAC7302) { 683 frame = gspca_get_i_frame(gspca_dev);
824 /* 6 bytes after the FF D9 EOF marker a number of lumination 684 if (frame == NULL) {
825 bytes are send corresponding to different parts of the 685 gspca_dev->last_packet_type = DISCARD_PACKET;
826 image, the 14th and 15th byte after the EOF seem to 686 return;
827 correspond to the center of the image */
828 lum_offset = 61 + sizeof pac_sof_marker;
829 footer_length = 74;
830 } else {
831 lum_offset = 24 + sizeof pac_sof_marker;
832 footer_length = 26;
833 } 687 }
834 688
689 /* 6 bytes after the FF D9 EOF marker a number of lumination
690 bytes are send corresponding to different parts of the
691 image, the 14th and 15th byte after the EOF seem to
692 correspond to the center of the image */
693 lum_offset = 24 + sizeof pac_sof_marker;
694 footer_length = 26;
695
835 /* Finish decoding current frame */ 696 /* Finish decoding current frame */
836 n = (sof - data) - (footer_length + sizeof pac_sof_marker); 697 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
837 if (n < 0) { 698 if (n < 0) {
838 frame->data_end += n; 699 frame->data_end += n;
839 n = 0; 700 n = 0;
840 } 701 }
841 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame, 702 gspca_frame_add(gspca_dev, INTER_PACKET,
842 data, n); 703 data, n);
843 if (gspca_dev->last_packet_type != DISCARD_PACKET && 704 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
844 frame->data_end[-2] == 0xff && 705 frame->data_end[-2] == 0xff &&
845 frame->data_end[-1] == 0xd9) 706 frame->data_end[-1] == 0xd9)
846 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 707 gspca_frame_add(gspca_dev, LAST_PACKET,
847 NULL, 0); 708 NULL, 0);
848 709
849 n = sof - data; 710 n = sof - data;
@@ -859,43 +720,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
859 atomic_set(&sd->avg_lum, -1); 720 atomic_set(&sd->avg_lum, -1);
860 721
861 /* Start the new frame with the jpeg header */ 722 /* Start the new frame with the jpeg header */
862 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 723 pac_start_frame(gspca_dev, frame,
863 pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1)); 724 gspca_dev->height, gspca_dev->width);
864 if (sd->sensor == SENSOR_PAC7302) {
865 /* The PAC7302 has the image rotated 90 degrees */
866 tmpbuf[0] = gspca_dev->width >> 8;
867 tmpbuf[1] = gspca_dev->width & 0xff;
868 tmpbuf[2] = gspca_dev->height >> 8;
869 tmpbuf[3] = gspca_dev->height & 0xff;
870 } else {
871 tmpbuf[0] = gspca_dev->height >> 8;
872 tmpbuf[1] = gspca_dev->height & 0xff;
873 tmpbuf[2] = gspca_dev->width >> 8;
874 tmpbuf[3] = gspca_dev->width & 0xff;
875 }
876 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
877 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
878 pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
879 } 725 }
880 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 726 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
881}
882
883static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
884{
885 struct sd *sd = (struct sd *) gspca_dev;
886
887 sd->brightness = val;
888 if (gspca_dev->streaming)
889 setbrightcont(gspca_dev);
890 return 0;
891}
892
893static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
894{
895 struct sd *sd = (struct sd *) gspca_dev;
896
897 *val = sd->brightness;
898 return 0;
899} 727}
900 728
901static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 729static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
@@ -904,10 +732,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
904 732
905 sd->contrast = val; 733 sd->contrast = val;
906 if (gspca_dev->streaming) { 734 if (gspca_dev->streaming) {
907 if (sd->sensor == SENSOR_PAC7302) 735 setcontrast(gspca_dev);
908 setbrightcont(gspca_dev);
909 else
910 setcontrast(gspca_dev);
911 } 736 }
912 return 0; 737 return 0;
913} 738}
@@ -920,24 +745,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
920 return 0; 745 return 0;
921} 746}
922 747
923static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
924{
925 struct sd *sd = (struct sd *) gspca_dev;
926
927 sd->colors = val;
928 if (gspca_dev->streaming)
929 setcolors(gspca_dev);
930 return 0;
931}
932
933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936
937 *val = sd->colors;
938 return 0;
939}
940
941static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 748static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
942{ 749{
943 struct sd *sd = (struct sd *) gspca_dev; 750 struct sd *sd = (struct sd *) gspca_dev;
@@ -1041,7 +848,7 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1041 return 0; 848 return 0;
1042} 849}
1043 850
1044/* sub-driver description */ 851/* sub-driver description for pac7311 */
1045static struct sd_desc sd_desc = { 852static struct sd_desc sd_desc = {
1046 .name = MODULE_NAME, 853 .name = MODULE_NAME,
1047 .ctrls = sd_ctrls, 854 .ctrls = sd_ctrls,
@@ -1057,21 +864,12 @@ static struct sd_desc sd_desc = {
1057 864
1058/* -- module initialisation -- */ 865/* -- module initialisation -- */
1059static __devinitdata struct usb_device_id device_table[] = { 866static __devinitdata struct usb_device_id device_table[] = {
1060 {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302}, 867 {USB_DEVICE(0x093a, 0x2600)},
1061 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, 868 {USB_DEVICE(0x093a, 0x2601)},
1062 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, 869 {USB_DEVICE(0x093a, 0x2603)},
1063 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, 870 {USB_DEVICE(0x093a, 0x2608)},
1064 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, 871 {USB_DEVICE(0x093a, 0x260e)},
1065 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, 872 {USB_DEVICE(0x093a, 0x260f)},
1066 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
1067 {USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
1068 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1072 {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
1073 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1074 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1075 {} 873 {}
1076}; 874};
1077MODULE_DEVICE_TABLE(usb, device_table); 875MODULE_DEVICE_TABLE(usb, device_table);