diff options
| -rw-r--r-- | drivers/media/video/gspca/spca561.c | 55 |
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) | |||
| 680 | static void sd_start_12a(struct gspca_dev *gspca_dev) | 702 | static 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 | } |
| 718 | static void sd_start_72a(struct gspca_dev *gspca_dev) | 729 | static 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 | } |
