aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/pac7302.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/pac7302.c')
-rw-r--r--drivers/media/video/gspca/pac7302.c411
1 files changed, 188 insertions, 223 deletions
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index de0b66c4b56e..2a68220d1ada 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -4,7 +4,9 @@
4 * 4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 * 6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu> 7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
8 * 10 *
9 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -22,33 +24,26 @@
22 */ 24 */
23 25
24/* Some documentation about various registers as determined by trial and error. 26/* Some documentation about various registers as determined by trial and error.
25 When the register addresses differ between the 7202 and the 7311 the 2
26 different addresses are written as 7302addr/7311addr, when one of the 2
27 addresses is a - sign that register description is not valid for the
28 matching IC.
29 27
30 Register page 1: 28 Register page 1:
31 29
32 Address Description 30 Address Description
33 -/0x08 Unknown compressor related, must always be 8 except when not
34 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
35 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
36 bits 345 seem to toggle per color gains on/off (inverted)
37 0x78 Global control, bit 6 controls the LED (inverted) 31 0x78 Global control, bit 6 controls the LED (inverted)
38 -/0x80 JPEG compression ratio ? Best not touched
39 32
40 Register page 3/4: 33 Register page 3:
41 34
42 Address Description 35 Address Description
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on 36 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 37 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain 38 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
46 0x10/- Master gain 0-31 39 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) 40 63 -> ~27 fps, the 2 msb's must always be 1 !!
41 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42 1 -> ~30 fps, 2 -> ~20 fps
43 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
44 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
45 0x10 Master gain 0-31
48 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
49 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
50 completely disable the analog amplification block. Set to 0x68
51 for max gain, 0x14 for minimal gain.
52 47
53 The registers are accessed in the following functions: 48 The registers are accessed in the following functions:
54 49
@@ -68,6 +63,7 @@
68 63
69#define MODULE_NAME "pac7302" 64#define MODULE_NAME "pac7302"
70 65
66#include <linux/input.h>
71#include <media/v4l2-chip-ident.h> 67#include <media/v4l2-chip-ident.h>
72#include "gspca.h" 68#include "gspca.h"
73 69
@@ -86,8 +82,8 @@ struct sd {
86 unsigned char red_balance; 82 unsigned char red_balance;
87 unsigned char blue_balance; 83 unsigned char blue_balance;
88 unsigned char gain; 84 unsigned char gain;
89 unsigned char exposure;
90 unsigned char autogain; 85 unsigned char autogain;
86 unsigned short exposure;
91 __u8 hflip; 87 __u8 hflip;
92 __u8 vflip; 88 __u8 vflip;
93 u8 flags; 89 u8 flags;
@@ -124,8 +120,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
124static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 120static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
125static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 121static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
126 122
127static struct ctrl sd_ctrls[] = { 123static const struct ctrl sd_ctrls[] = {
128/* This control is pac7302 only */
129 { 124 {
130 { 125 {
131 .id = V4L2_CID_BRIGHTNESS, 126 .id = V4L2_CID_BRIGHTNESS,
@@ -141,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_setbrightness, 136 .set = sd_setbrightness,
142 .get = sd_getbrightness, 137 .get = sd_getbrightness,
143 }, 138 },
144/* This control is for both the 7302 and the 7311 */
145 { 139 {
146 { 140 {
147 .id = V4L2_CID_CONTRAST, 141 .id = V4L2_CID_CONTRAST,
@@ -157,7 +151,6 @@ static struct ctrl sd_ctrls[] = {
157 .set = sd_setcontrast, 151 .set = sd_setcontrast,
158 .get = sd_getcontrast, 152 .get = sd_getcontrast,
159 }, 153 },
160/* This control is pac7302 only */
161 { 154 {
162 { 155 {
163 .id = V4L2_CID_SATURATION, 156 .id = V4L2_CID_SATURATION,
@@ -215,7 +208,6 @@ static struct ctrl sd_ctrls[] = {
215 .set = sd_setbluebalance, 208 .set = sd_setbluebalance,
216 .get = sd_getbluebalance, 209 .get = sd_getbluebalance,
217 }, 210 },
218/* All controls below are for both the 7302 and the 7311 */
219 { 211 {
220 { 212 {
221 .id = V4L2_CID_GAIN, 213 .id = V4L2_CID_GAIN,
@@ -238,11 +230,10 @@ static struct ctrl sd_ctrls[] = {
238 .type = V4L2_CTRL_TYPE_INTEGER, 230 .type = V4L2_CTRL_TYPE_INTEGER,
239 .name = "Exposure", 231 .name = "Exposure",
240 .minimum = 0, 232 .minimum = 0,
241#define EXPOSURE_MAX 255 233 .maximum = 1023,
242 .maximum = EXPOSURE_MAX,
243 .step = 1, 234 .step = 1,
244#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 235#define EXPOSURE_DEF 66 /* 33 ms / 30 fps */
245#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 236#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
246 .default_value = EXPOSURE_DEF, 237 .default_value = EXPOSURE_DEF,
247 }, 238 },
248 .set = sd_setexposure, 239 .set = sd_setexposure,
@@ -301,7 +292,6 @@ static const struct v4l2_pix_format vga_mode[] = {
301}; 292};
302 293
303#define LOAD_PAGE3 255 294#define LOAD_PAGE3 255
304#define LOAD_PAGE4 254
305#define END_OF_SEQUENCE 0 295#define END_OF_SEQUENCE 0
306 296
307/* pac 7302 */ 297/* pac 7302 */
@@ -379,7 +369,7 @@ static const __u8 start_7302[] = {
379#define SKIP 0xaa 369#define SKIP 0xaa
380/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 370/* page 3 - the value SKIP says skip the index - see reg_w_page() */
381static const __u8 page3_7302[] = { 371static const __u8 page3_7302[] = {
382 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, 372 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
383 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 373 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
384 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, 375 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
@@ -388,7 +378,7 @@ static const __u8 page3_7302[] = {
388 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, 378 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
389 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, 380 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, 381 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
392 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 382 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, 383 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -401,12 +391,14 @@ static const __u8 page3_7302[] = {
401 0x00 391 0x00
402}; 392};
403 393
404static int reg_w_buf(struct gspca_dev *gspca_dev, 394static void reg_w_buf(struct gspca_dev *gspca_dev,
405 __u8 index, 395 __u8 index,
406 const char *buffer, int len) 396 const char *buffer, int len)
407{ 397{
408 int ret; 398 int ret;
409 399
400 if (gspca_dev->usb_err < 0)
401 return;
410 memcpy(gspca_dev->usb_buf, buffer, len); 402 memcpy(gspca_dev->usb_buf, buffer, len);
411 ret = usb_control_msg(gspca_dev->dev, 403 ret = usb_control_msg(gspca_dev->dev,
412 usb_sndctrlpipe(gspca_dev->dev, 0), 404 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -415,20 +407,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
415 0, /* value */ 407 0, /* value */
416 index, gspca_dev->usb_buf, len, 408 index, gspca_dev->usb_buf, len,
417 500); 409 500);
418 if (ret < 0) 410 if (ret < 0) {
419 PDEBUG(D_ERR, "reg_w_buf(): " 411 PDEBUG(D_ERR, "reg_w_buf(): "
420 "Failed to write registers to index 0x%x, error %i", 412 "Failed to write registers to index 0x%x, error %i",
421 index, ret); 413 index, ret);
422 return ret; 414 gspca_dev->usb_err = ret;
415 }
423} 416}
424 417
425 418
426static int reg_w(struct gspca_dev *gspca_dev, 419static void reg_w(struct gspca_dev *gspca_dev,
427 __u8 index, 420 __u8 index,
428 __u8 value) 421 __u8 value)
429{ 422{
430 int ret; 423 int ret;
431 424
425 if (gspca_dev->usb_err < 0)
426 return;
432 gspca_dev->usb_buf[0] = value; 427 gspca_dev->usb_buf[0] = value;
433 ret = usb_control_msg(gspca_dev->dev, 428 ret = usb_control_msg(gspca_dev->dev,
434 usb_sndctrlpipe(gspca_dev->dev, 0), 429 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -436,32 +431,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
436 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 431 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
437 0, index, gspca_dev->usb_buf, 1, 432 0, index, gspca_dev->usb_buf, 1,
438 500); 433 500);
439 if (ret < 0) 434 if (ret < 0) {
440 PDEBUG(D_ERR, "reg_w(): " 435 PDEBUG(D_ERR, "reg_w(): "
441 "Failed to write register to index 0x%x, value 0x%x, error %i", 436 "Failed to write register to index 0x%x, value 0x%x, error %i",
442 index, value, ret); 437 index, value, ret);
443 return ret; 438 gspca_dev->usb_err = ret;
439 }
444} 440}
445 441
446static int reg_w_seq(struct gspca_dev *gspca_dev, 442static void reg_w_seq(struct gspca_dev *gspca_dev,
447 const __u8 *seq, int len) 443 const __u8 *seq, int len)
448{ 444{
449 int ret = 0;
450 while (--len >= 0) { 445 while (--len >= 0) {
451 if (0 <= ret) 446 reg_w(gspca_dev, seq[0], seq[1]);
452 ret = reg_w(gspca_dev, seq[0], seq[1]);
453 seq += 2; 447 seq += 2;
454 } 448 }
455 return ret;
456} 449}
457 450
458/* load the beginning of a page */ 451/* load the beginning of a page */
459static int reg_w_page(struct gspca_dev *gspca_dev, 452static void reg_w_page(struct gspca_dev *gspca_dev,
460 const __u8 *page, int len) 453 const __u8 *page, int len)
461{ 454{
462 int index; 455 int index;
463 int ret = 0; 456 int ret = 0;
464 457
458 if (gspca_dev->usb_err < 0)
459 return;
465 for (index = 0; index < len; index++) { 460 for (index = 0; index < len; index++) {
466 if (page[index] == SKIP) /* skip this index */ 461 if (page[index] == SKIP) /* skip this index */
467 continue; 462 continue;
@@ -477,56 +472,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
477 "Failed to write register to index 0x%x, " 472 "Failed to write register to index 0x%x, "
478 "value 0x%x, error %i", 473 "value 0x%x, error %i",
479 index, page[index], ret); 474 index, page[index], ret);
475 gspca_dev->usb_err = ret;
480 break; 476 break;
481 } 477 }
482 } 478 }
483 return ret;
484} 479}
485 480
486/* output a variable sequence */ 481/* output a variable sequence */
487static int reg_w_var(struct gspca_dev *gspca_dev, 482static void reg_w_var(struct gspca_dev *gspca_dev,
488 const __u8 *seq, 483 const __u8 *seq,
489 const __u8 *page3, unsigned int page3_len, 484 const __u8 *page3, unsigned int page3_len)
490 const __u8 *page4, unsigned int page4_len)
491{ 485{
492 int index, len; 486 int index, len;
493 int ret = 0;
494 487
495 for (;;) { 488 for (;;) {
496 index = *seq++; 489 index = *seq++;
497 len = *seq++; 490 len = *seq++;
498 switch (len) { 491 switch (len) {
499 case END_OF_SEQUENCE: 492 case END_OF_SEQUENCE:
500 return ret; 493 return;
501 case LOAD_PAGE4:
502 ret = reg_w_page(gspca_dev, page4, page4_len);
503 break;
504 case LOAD_PAGE3: 494 case LOAD_PAGE3:
505 ret = reg_w_page(gspca_dev, page3, page3_len); 495 reg_w_page(gspca_dev, page3, page3_len);
506 break; 496 break;
507 default: 497 default:
508 if (len > USB_BUF_SZ) { 498 if (len > USB_BUF_SZ) {
509 PDEBUG(D_ERR|D_STREAM, 499 PDEBUG(D_ERR|D_STREAM,
510 "Incorrect variable sequence"); 500 "Incorrect variable sequence");
511 return -EINVAL; 501 return;
512 } 502 }
513 while (len > 0) { 503 while (len > 0) {
514 if (len < 8) { 504 if (len < 8) {
515 ret = reg_w_buf(gspca_dev, 505 reg_w_buf(gspca_dev,
516 index, seq, len); 506 index, seq, len);
517 if (ret < 0)
518 return ret;
519 seq += len; 507 seq += len;
520 break; 508 break;
521 } 509 }
522 ret = reg_w_buf(gspca_dev, index, seq, 8); 510 reg_w_buf(gspca_dev, index, seq, 8);
523 seq += 8; 511 seq += 8;
524 index += 8; 512 index += 8;
525 len -= 8; 513 len -= 8;
526 } 514 }
527 } 515 }
528 if (ret < 0)
529 return ret;
530 } 516 }
531 /* not reached */ 517 /* not reached */
532} 518}
@@ -560,11 +546,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
560} 546}
561 547
562/* This function is used by pac7302 only */ 548/* This function is used by pac7302 only */
563static int setbrightcont(struct gspca_dev *gspca_dev) 549static void setbrightcont(struct gspca_dev *gspca_dev)
564{ 550{
565 struct sd *sd = (struct sd *) gspca_dev; 551 struct sd *sd = (struct sd *) gspca_dev;
566 int i, v; 552 int i, v;
567 int ret;
568 static const __u8 max[10] = 553 static const __u8 max[10] =
569 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 554 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
570 0xd4, 0xec}; 555 0xd4, 0xec};
@@ -572,7 +557,7 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
572 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 557 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
573 0x11, 0x0b}; 558 0x11, 0x0b};
574 559
575 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 560 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
576 for (i = 0; i < 10; i++) { 561 for (i = 0; i < 10; i++) {
577 v = max[i]; 562 v = max[i];
578 v += (sd->brightness - BRIGHTNESS_MAX) 563 v += (sd->brightness - BRIGHTNESS_MAX)
@@ -582,136 +567,121 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
582 v = 0; 567 v = 0;
583 else if (v > 0xff) 568 else if (v > 0xff)
584 v = 0xff; 569 v = 0xff;
585 if (0 <= ret) 570 reg_w(gspca_dev, 0xa2 + i, v);
586 ret = reg_w(gspca_dev, 0xa2 + i, v);
587 } 571 }
588 if (0 <= ret) 572 reg_w(gspca_dev, 0xdc, 0x01);
589 ret = reg_w(gspca_dev, 0xdc, 0x01);
590 return ret;
591} 573}
592 574
593/* This function is used by pac7302 only */ 575/* This function is used by pac7302 only */
594static int setcolors(struct gspca_dev *gspca_dev) 576static void setcolors(struct gspca_dev *gspca_dev)
595{ 577{
596 struct sd *sd = (struct sd *) gspca_dev; 578 struct sd *sd = (struct sd *) gspca_dev;
597 int i, v; 579 int i, v;
598 int ret;
599 static const int a[9] = 580 static const int a[9] =
600 {217, -212, 0, -101, 170, -67, -38, -315, 355}; 581 {217, -212, 0, -101, 170, -67, -38, -315, 355};
601 static const int b[9] = 582 static const int b[9] =
602 {19, 106, 0, 19, 106, 1, 19, 106, 1}; 583 {19, 106, 0, 19, 106, 1, 19, 106, 1};
603 584
604 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 585 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
605 if (0 <= ret) 586 reg_w(gspca_dev, 0x11, 0x01);
606 ret = reg_w(gspca_dev, 0x11, 0x01); 587 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
607 if (0 <= ret)
608 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
609 for (i = 0; i < 9; i++) { 588 for (i = 0; i < 9; i++) {
610 v = a[i] * sd->colors / COLOR_MAX + b[i]; 589 v = a[i] * sd->colors / COLOR_MAX + b[i];
611 if (0 <= ret) 590 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
612 ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 591 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
613 if (0 <= ret)
614 ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
615 } 592 }
616 if (0 <= ret) 593 reg_w(gspca_dev, 0xdc, 0x01);
617 ret = reg_w(gspca_dev, 0xdc, 0x01);
618 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 594 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
619 return ret;
620} 595}
621 596
622static int setwhitebalance(struct gspca_dev *gspca_dev) 597static void setwhitebalance(struct gspca_dev *gspca_dev)
623{ 598{
624 struct sd *sd = (struct sd *) gspca_dev; 599 struct sd *sd = (struct sd *) gspca_dev;
625 int ret;
626 600
627 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 601 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
628 if (0 <= ret) 602 reg_w(gspca_dev, 0xc6, sd->white_balance);
629 ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
630 603
631 if (0 <= ret) 604 reg_w(gspca_dev, 0xdc, 0x01);
632 ret = reg_w(gspca_dev, 0xdc, 0x01);
633 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); 605 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
634 return ret;
635} 606}
636 607
637static int setredbalance(struct gspca_dev *gspca_dev) 608static void setredbalance(struct gspca_dev *gspca_dev)
638{ 609{
639 struct sd *sd = (struct sd *) gspca_dev; 610 struct sd *sd = (struct sd *) gspca_dev;
640 int ret;
641 611
642 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 612 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
643 if (0 <= ret) 613 reg_w(gspca_dev, 0xc5, sd->red_balance);
644 ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
645 614
646 if (0 <= ret) 615 reg_w(gspca_dev, 0xdc, 0x01);
647 ret = reg_w(gspca_dev, 0xdc, 0x01);
648 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); 616 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
649 return ret;
650} 617}
651 618
652static int setbluebalance(struct gspca_dev *gspca_dev) 619static void setbluebalance(struct gspca_dev *gspca_dev)
653{ 620{
654 struct sd *sd = (struct sd *) gspca_dev; 621 struct sd *sd = (struct sd *) gspca_dev;
655 int ret;
656 622
657 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 623 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
658 if (0 <= ret) 624 reg_w(gspca_dev, 0xc7, sd->blue_balance);
659 ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
660 625
661 if (0 <= ret) 626 reg_w(gspca_dev, 0xdc, 0x01);
662 ret = reg_w(gspca_dev, 0xdc, 0x01);
663 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); 627 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
664 return ret;
665} 628}
666 629
667static int setgain(struct gspca_dev *gspca_dev) 630static void setgain(struct gspca_dev *gspca_dev)
668{ 631{
669 struct sd *sd = (struct sd *) gspca_dev; 632 struct sd *sd = (struct sd *) gspca_dev;
670 int ret;
671 633
672 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 634 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
673 if (0 <= ret) 635 reg_w(gspca_dev, 0x10, sd->gain >> 3);
674 ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
675 636
676 /* load registers to sensor (Bit 0, auto clear) */ 637 /* load registers to sensor (Bit 0, auto clear) */
677 if (0 <= ret) 638 reg_w(gspca_dev, 0x11, 0x01);
678 ret = reg_w(gspca_dev, 0x11, 0x01);
679 return ret;
680} 639}
681 640
682static int setexposure(struct gspca_dev *gspca_dev) 641static void setexposure(struct gspca_dev *gspca_dev)
683{ 642{
684 struct sd *sd = (struct sd *) gspca_dev; 643 struct sd *sd = (struct sd *) gspca_dev;
685 int ret; 644 __u8 clockdiv;
686 __u8 reg; 645 __u16 exposure;
687 646
688 /* register 2 of frame 3/4 contains the clock divider configuring the 647 /* register 2 of frame 3 contains the clock divider configuring the
689 no fps according to the formula: 60 / reg. sd->exposure is the 648 no fps according to the formula: 90 / reg. sd->exposure is the
690 desired exposure time in ms. */ 649 desired exposure time in 0.5 ms. */
691 reg = 120 * sd->exposure / 1000; 650 clockdiv = (90 * sd->exposure + 1999) / 2000;
692 if (reg < 2) 651
693 reg = 2; 652 /* Note clockdiv = 3 also works, but when running at 30 fps, depending
694 else if (reg > 63) 653 on the scene being recorded, the camera switches to another
695 reg = 63; 654 quantization table for certain JPEG blocks, and we don't know how
696 655 to decompress these blocks. So we cap the framerate at 15 fps */
697 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 656 if (clockdiv < 6)
698 the nearest multiple of 3, except when between 6 and 12? */ 657 clockdiv = 6;
699 if (reg < 6 || reg > 12) 658 else if (clockdiv > 63)
700 reg = ((reg + 1) / 3) * 3; 659 clockdiv = 63;
701 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 660
702 if (0 <= ret) 661 /* reg2 MUST be a multiple of 3, except when between 6 and 12?
703 ret = reg_w(gspca_dev, 0x02, reg); 662 Always round up, otherwise we cannot get the desired frametime
663 using the partial frame time exposure control */
664 if (clockdiv < 6 || clockdiv > 12)
665 clockdiv = ((clockdiv + 2) / 3) * 3;
666
667 /* frame exposure time in ms = 1000 * clockdiv / 90 ->
668 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
669 exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
670 /* 0 = use full frametime, 448 = no exposure, reverse it */
671 exposure = 448 - exposure;
672
673 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
674 reg_w(gspca_dev, 0x02, clockdiv);
675 reg_w(gspca_dev, 0x0e, exposure & 0xff);
676 reg_w(gspca_dev, 0x0f, exposure >> 8);
704 677
705 /* load registers to sensor (Bit 0, auto clear) */ 678 /* load registers to sensor (Bit 0, auto clear) */
706 if (0 <= ret) 679 reg_w(gspca_dev, 0x11, 0x01);
707 ret = reg_w(gspca_dev, 0x11, 0x01);
708 return ret;
709} 680}
710 681
711static int sethvflip(struct gspca_dev *gspca_dev) 682static void sethvflip(struct gspca_dev *gspca_dev)
712{ 683{
713 struct sd *sd = (struct sd *) gspca_dev; 684 struct sd *sd = (struct sd *) gspca_dev;
714 int ret;
715 u8 data, hflip, vflip; 685 u8 data, hflip, vflip;
716 686
717 hflip = sd->hflip; 687 hflip = sd->hflip;
@@ -721,48 +691,37 @@ static int sethvflip(struct gspca_dev *gspca_dev)
721 if (sd->flags & FL_VFLIP) 691 if (sd->flags & FL_VFLIP)
722 vflip = !vflip; 692 vflip = !vflip;
723 693
724 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 694 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
725 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); 695 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
726 if (0 <= ret) 696 reg_w(gspca_dev, 0x21, data);
727 ret = reg_w(gspca_dev, 0x21, data); 697
728 /* load registers to sensor (Bit 0, auto clear) */ 698 /* load registers to sensor (Bit 0, auto clear) */
729 if (0 <= ret) 699 reg_w(gspca_dev, 0x11, 0x01);
730 ret = reg_w(gspca_dev, 0x11, 0x01);
731 return ret;
732} 700}
733 701
734/* this function is called at probe and resume time for pac7302 */ 702/* this function is called at probe and resume time for pac7302 */
735static int sd_init(struct gspca_dev *gspca_dev) 703static int sd_init(struct gspca_dev *gspca_dev)
736{ 704{
737 return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); 705 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
706 return gspca_dev->usb_err;
738} 707}
739 708
740static int sd_start(struct gspca_dev *gspca_dev) 709static int sd_start(struct gspca_dev *gspca_dev)
741{ 710{
742 struct sd *sd = (struct sd *) gspca_dev; 711 struct sd *sd = (struct sd *) gspca_dev;
743 int ret = 0;
744 712
745 sd->sof_read = 0; 713 sd->sof_read = 0;
746 714
747 ret = reg_w_var(gspca_dev, start_7302, 715 reg_w_var(gspca_dev, start_7302,
748 page3_7302, sizeof(page3_7302), 716 page3_7302, sizeof(page3_7302));
749 NULL, 0); 717 setbrightcont(gspca_dev);
750 if (0 <= ret) 718 setcolors(gspca_dev);
751 ret = setbrightcont(gspca_dev); 719 setwhitebalance(gspca_dev);
752 if (0 <= ret) 720 setredbalance(gspca_dev);
753 ret = setcolors(gspca_dev); 721 setbluebalance(gspca_dev);
754 if (0 <= ret) 722 setgain(gspca_dev);
755 ret = setwhitebalance(gspca_dev); 723 setexposure(gspca_dev);
756 if (0 <= ret) 724 sethvflip(gspca_dev);
757 ret = setredbalance(gspca_dev);
758 if (0 <= ret)
759 ret = setbluebalance(gspca_dev);
760 if (0 <= ret)
761 ret = setgain(gspca_dev);
762 if (0 <= ret)
763 ret = setexposure(gspca_dev);
764 if (0 <= ret)
765 ret = sethvflip(gspca_dev);
766 725
767 /* only resolution 640x480 is supported for pac7302 */ 726 /* only resolution 640x480 is supported for pac7302 */
768 727
@@ -771,34 +730,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
771 atomic_set(&sd->avg_lum, -1); 730 atomic_set(&sd->avg_lum, -1);
772 731
773 /* start stream */ 732 /* start stream */
774 if (0 <= ret) 733 reg_w(gspca_dev, 0xff, 0x01);
775 ret = reg_w(gspca_dev, 0xff, 0x01); 734 reg_w(gspca_dev, 0x78, 0x01);
776 if (0 <= ret)
777 ret = reg_w(gspca_dev, 0x78, 0x01);
778 735
779 return ret; 736 return gspca_dev->usb_err;
780} 737}
781 738
782static void sd_stopN(struct gspca_dev *gspca_dev) 739static void sd_stopN(struct gspca_dev *gspca_dev)
783{ 740{
784 int ret;
785 741
786 /* stop stream */ 742 /* stop stream */
787 ret = reg_w(gspca_dev, 0xff, 0x01); 743 reg_w(gspca_dev, 0xff, 0x01);
788 if (0 <= ret) 744 reg_w(gspca_dev, 0x78, 0x00);
789 ret = reg_w(gspca_dev, 0x78, 0x00);
790} 745}
791 746
792/* called on streamoff with alt 0 and on disconnect for pac7302 */ 747/* called on streamoff with alt 0 and on disconnect for pac7302 */
793static void sd_stop0(struct gspca_dev *gspca_dev) 748static void sd_stop0(struct gspca_dev *gspca_dev)
794{ 749{
795 int ret;
796
797 if (!gspca_dev->present) 750 if (!gspca_dev->present)
798 return; 751 return;
799 ret = reg_w(gspca_dev, 0xff, 0x01); 752 reg_w(gspca_dev, 0xff, 0x01);
800 if (0 <= ret) 753 reg_w(gspca_dev, 0x78, 0x40);
801 ret = reg_w(gspca_dev, 0x78, 0x40);
802} 754}
803 755
804/* Include pac common sof detection functions */ 756/* Include pac common sof detection functions */
@@ -808,22 +760,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
808{ 760{
809 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
810 int avg_lum = atomic_read(&sd->avg_lum); 762 int avg_lum = atomic_read(&sd->avg_lum);
811 int desired_lum, deadzone; 763 int desired_lum;
764 const int deadzone = 30;
812 765
813 if (avg_lum == -1) 766 if (avg_lum == -1)
814 return; 767 return;
815 768
816 desired_lum = 270 + sd->brightness * 4; 769 desired_lum = 270 + sd->brightness;
817 /* Hack hack, with the 7202 the first exposure step is
818 pretty large, so if we're about to make the first
819 exposure increase make the deadzone large to avoid
820 oscilating */
821 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
822 sd->exposure > EXPOSURE_DEF &&
823 sd->exposure < 42)
824 deadzone = 90;
825 else
826 deadzone = 30;
827 770
828 if (sd->autogain_ignore_frames > 0) 771 if (sd->autogain_ignore_frames > 0)
829 sd->autogain_ignore_frames--; 772 sd->autogain_ignore_frames--;
@@ -947,7 +890,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
947 sd->brightness = val; 890 sd->brightness = val;
948 if (gspca_dev->streaming) 891 if (gspca_dev->streaming)
949 setbrightcont(gspca_dev); 892 setbrightcont(gspca_dev);
950 return 0; 893 return gspca_dev->usb_err;
951} 894}
952 895
953static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 896static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -966,7 +909,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
966 if (gspca_dev->streaming) { 909 if (gspca_dev->streaming) {
967 setbrightcont(gspca_dev); 910 setbrightcont(gspca_dev);
968 } 911 }
969 return 0; 912 return gspca_dev->usb_err;
970} 913}
971 914
972static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 915static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -984,7 +927,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
984 sd->colors = val; 927 sd->colors = val;
985 if (gspca_dev->streaming) 928 if (gspca_dev->streaming)
986 setcolors(gspca_dev); 929 setcolors(gspca_dev);
987 return 0; 930 return gspca_dev->usb_err;
988} 931}
989 932
990static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -998,14 +941,11 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
998static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) 941static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
999{ 942{
1000 struct sd *sd = (struct sd *) gspca_dev; 943 struct sd *sd = (struct sd *) gspca_dev;
1001 int ret = 0;
1002 944
1003 sd->white_balance = val; 945 sd->white_balance = val;
1004 if (gspca_dev->streaming) 946 if (gspca_dev->streaming)
1005 ret = setwhitebalance(gspca_dev); 947 setwhitebalance(gspca_dev);
1006 if (0 <= ret) 948 return gspca_dev->usb_err;
1007 ret = 0;
1008 return ret;
1009} 949}
1010 950
1011static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) 951static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1019,14 +959,11 @@ static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1019static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) 959static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
1020{ 960{
1021 struct sd *sd = (struct sd *) gspca_dev; 961 struct sd *sd = (struct sd *) gspca_dev;
1022 int ret = 0;
1023 962
1024 sd->red_balance = val; 963 sd->red_balance = val;
1025 if (gspca_dev->streaming) 964 if (gspca_dev->streaming)
1026 ret = setredbalance(gspca_dev); 965 setredbalance(gspca_dev);
1027 if (0 <= ret) 966 return gspca_dev->usb_err;
1028 ret = 0;
1029 return ret;
1030} 967}
1031 968
1032static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) 969static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1040,14 +977,11 @@ static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
1040static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) 977static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
1041{ 978{
1042 struct sd *sd = (struct sd *) gspca_dev; 979 struct sd *sd = (struct sd *) gspca_dev;
1043 int ret = 0;
1044 980
1045 sd->blue_balance = val; 981 sd->blue_balance = val;
1046 if (gspca_dev->streaming) 982 if (gspca_dev->streaming)
1047 ret = setbluebalance(gspca_dev); 983 setbluebalance(gspca_dev);
1048 if (0 <= ret) 984 return gspca_dev->usb_err;
1049 ret = 0;
1050 return ret;
1051} 985}
1052 986
1053static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) 987static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1065,7 +999,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1065 sd->gain = val; 999 sd->gain = val;
1066 if (gspca_dev->streaming) 1000 if (gspca_dev->streaming)
1067 setgain(gspca_dev); 1001 setgain(gspca_dev);
1068 return 0; 1002 return gspca_dev->usb_err;
1069} 1003}
1070 1004
1071static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1005static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1083,7 +1017,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1083 sd->exposure = val; 1017 sd->exposure = val;
1084 if (gspca_dev->streaming) 1018 if (gspca_dev->streaming)
1085 setexposure(gspca_dev); 1019 setexposure(gspca_dev);
1086 return 0; 1020 return gspca_dev->usb_err;
1087} 1021}
1088 1022
1089static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 1023static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1114,7 +1048,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1114 } 1048 }
1115 } 1049 }
1116 1050
1117 return 0; 1051 return gspca_dev->usb_err;
1118} 1052}
1119 1053
1120static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1054static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1132,7 +1066,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1132 sd->hflip = val; 1066 sd->hflip = val;
1133 if (gspca_dev->streaming) 1067 if (gspca_dev->streaming)
1134 sethvflip(gspca_dev); 1068 sethvflip(gspca_dev);
1135 return 0; 1069 return gspca_dev->usb_err;
1136} 1070}
1137 1071
1138static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 1072static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1150,7 +1084,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1150 sd->vflip = val; 1084 sd->vflip = val;
1151 if (gspca_dev->streaming) 1085 if (gspca_dev->streaming)
1152 sethvflip(gspca_dev); 1086 sethvflip(gspca_dev);
1153 return 0; 1087 return gspca_dev->usb_err;
1154} 1088}
1155 1089
1156static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 1090static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1165,7 +1099,6 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1165static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1099static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1166 struct v4l2_dbg_register *reg) 1100 struct v4l2_dbg_register *reg)
1167{ 1101{
1168 int ret = -EINVAL;
1169 __u8 index; 1102 __u8 index;
1170 __u8 value; 1103 __u8 value;
1171 1104
@@ -1185,14 +1118,12 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1185 /* Note that there shall be no access to other page 1118 /* Note that there shall be no access to other page
1186 by any other function between the page swith and 1119 by any other function between the page swith and
1187 the actual register write */ 1120 the actual register write */
1188 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 1121 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1189 if (0 <= ret) 1122 reg_w(gspca_dev, index, value);
1190 ret = reg_w(gspca_dev, index, value);
1191 1123
1192 if (0 <= ret) 1124 reg_w(gspca_dev, 0xdc, 0x01);
1193 ret = reg_w(gspca_dev, 0xdc, 0x01);
1194 } 1125 }
1195 return ret; 1126 return gspca_dev->usb_err;
1196} 1127}
1197 1128
1198static int sd_chip_ident(struct gspca_dev *gspca_dev, 1129static int sd_chip_ident(struct gspca_dev *gspca_dev,
@@ -1210,8 +1141,39 @@ static int sd_chip_ident(struct gspca_dev *gspca_dev,
1210} 1141}
1211#endif 1142#endif
1212 1143
1144#ifdef CONFIG_INPUT
1145static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1146 u8 *data, /* interrupt packet data */
1147 int len) /* interrput packet length */
1148{
1149 int ret = -EINVAL;
1150 u8 data0, data1;
1151
1152 if (len == 2) {
1153 data0 = data[0];
1154 data1 = data[1];
1155 if ((data0 == 0x00 && data1 == 0x11) ||
1156 (data0 == 0x22 && data1 == 0x33) ||
1157 (data0 == 0x44 && data1 == 0x55) ||
1158 (data0 == 0x66 && data1 == 0x77) ||
1159 (data0 == 0x88 && data1 == 0x99) ||
1160 (data0 == 0xaa && data1 == 0xbb) ||
1161 (data0 == 0xcc && data1 == 0xdd) ||
1162 (data0 == 0xee && data1 == 0xff)) {
1163 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1164 input_sync(gspca_dev->input_dev);
1165 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1166 input_sync(gspca_dev->input_dev);
1167 ret = 0;
1168 }
1169 }
1170
1171 return ret;
1172}
1173#endif
1174
1213/* sub-driver description for pac7302 */ 1175/* sub-driver description for pac7302 */
1214static struct sd_desc sd_desc = { 1176static const struct sd_desc sd_desc = {
1215 .name = MODULE_NAME, 1177 .name = MODULE_NAME,
1216 .ctrls = sd_ctrls, 1178 .ctrls = sd_ctrls,
1217 .nctrls = ARRAY_SIZE(sd_ctrls), 1179 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -1226,6 +1188,9 @@ static struct sd_desc sd_desc = {
1226 .set_register = sd_dbg_s_register, 1188 .set_register = sd_dbg_s_register,
1227 .get_chip_ident = sd_chip_ident, 1189 .get_chip_ident = sd_chip_ident,
1228#endif 1190#endif
1191#ifdef CONFIG_INPUT
1192 .int_pkt_scan = sd_int_pkt_scan,
1193#endif
1229}; 1194};
1230 1195
1231/* -- module initialisation -- */ 1196/* -- module initialisation -- */