aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/spca561.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/spca561.c')
-rw-r--r--drivers/media/video/gspca/spca561.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index d2f689e366af..1c29c279a982 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -38,9 +38,9 @@ struct sd {
38#define CONTRAST_MAX 0x3fff 38#define CONTRAST_MAX 0x3fff
39 39
40 __u16 exposure; /* rev12a only */ 40 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 0 41#define EXPOSURE_MIN 1
42#define EXPOSURE_DEF 200 42#define EXPOSURE_DEF 200
43#define EXPOSURE_MAX 762 43#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
44 44
45 __u8 brightness; /* rev72a only */ 45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0 46#define BRIGHTNESS_MIN 0
@@ -648,9 +648,31 @@ static void setexposure(struct gspca_dev *gspca_dev)
648{ 648{
649 struct sd *sd = (struct sd *) gspca_dev; 649 struct sd *sd = (struct sd *) gspca_dev;
650 int expo; 650 int expo;
651 int clock_divider;
651 __u8 data[2]; 652 __u8 data[2];
652 653
653 expo = sd->exposure + 0x20a8; /* from test */ 654 /* Register 0x8309 controls exposure for the spca561,
655 the basic exposure setting goes from 1-2047, where 1 is completely
656 dark and 2047 is very bright. It not only influences exposure but
657 also the framerate (to allow for longer exposure) from 1 - 300 it
658 only raises the exposure time then from 300 - 600 it halves the
659 framerate to be able to further raise the exposure time and for every
660 300 more it halves the framerate again. This allows for a maximum
661 exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
662 Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
663 configure a divider for the base framerate which us used at the
664 exposure setting of 1-300. These bits configure the base framerate
665 according to the following formula: fps = 60 / (value + 2) */
666 if (sd->exposure < 2048) {
667 expo = sd->exposure;
668 clock_divider = 0;
669 } else {
670 /* Add 900 to make the 0 setting of the second part of the
671 exposure equal to the 2047 setting of the first part. */
672 expo = (sd->exposure - 2048) + 900;
673 clock_divider = 3;
674 }
675 expo |= clock_divider << 11;
654 data[0] = expo; 676 data[0] = expo;
655 data[1] = expo >> 8; 677 data[1] = expo >> 8;
656 reg_w_buf(gspca_dev, 0x8309, data, 2); 678 reg_w_buf(gspca_dev, 0x8309, data, 2);
@@ -680,23 +702,11 @@ static void setautogain(struct gspca_dev *gspca_dev)
680static void sd_start_12a(struct gspca_dev *gspca_dev) 702static void sd_start_12a(struct gspca_dev *gspca_dev)
681{ 703{
682 struct usb_device *dev = gspca_dev->dev; 704 struct usb_device *dev = gspca_dev->dev;
683 int Clck; 705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
684 __u8 Reg8307[] = { 0xaa, 0x00 }; 706 __u8 Reg8307[] = { 0xaa, 0x00 };
685 int mode; 707 int mode;
686 708
687 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 709 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
688 switch (mode) {
689 case 0:
690 case 1:
691 Clck = 0x8a;
692 break;
693 case 2:
694 Clck = 0x85;
695 break;
696 default:
697 Clck = 0x83;
698 break;
699 }
700 if (mode <= 1) { 710 if (mode <= 1) {
701 /* Use compression on 320x240 and above */ 711 /* Use compression on 320x240 and above */
702 reg_w_val(dev, 0x8500, 0x10 | mode); 712 reg_w_val(dev, 0x8500, 0x10 | mode);
@@ -714,6 +724,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
714 setcontrast(gspca_dev); 724 setcontrast(gspca_dev);
715 setwhite(gspca_dev); 725 setwhite(gspca_dev);
716 setautogain(gspca_dev); 726 setautogain(gspca_dev);
727 setexposure(gspca_dev);
717} 728}
718static void sd_start_72a(struct gspca_dev *gspca_dev) 729static void sd_start_72a(struct gspca_dev *gspca_dev)
719{ 730{
@@ -849,6 +860,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
849 __u8 *data, /* isoc packet */ 860 __u8 *data, /* isoc packet */
850 int len) /* iso packet length */ 861 int len) /* iso packet length */
851{ 862{
863 struct sd *sd = (struct sd *) gspca_dev;
864
852 switch (data[0]) { 865 switch (data[0]) {
853 case 0: /* start of frame */ 866 case 0: /* start of frame */
854 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 867 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -861,9 +874,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
861 frame, data, len); 874 frame, data, len);
862 } else { 875 } else {
863 /* raw bayer (with a header, which we skip) */ 876 /* raw bayer (with a header, which we skip) */
864/*fixme: is this specific to the rev012a? */ 877 if (sd->chip_revision == Rev012A) {
865 data += 16; 878 data += 20;
866 len -= 16; 879 len -= 20;
880 } else {
881 data += 16;
882 len -= 16;
883 }
867 gspca_frame_add(gspca_dev, FIRST_PACKET, 884 gspca_frame_add(gspca_dev, FIRST_PACKET,
868 frame, data, len); 885 frame, data, len);
869 } 886 }