diff options
Diffstat (limited to 'drivers/media/video/gspca/spca561.c')
-rw-r--r-- | drivers/media/video/gspca/spca561.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index a26174508cb9..1073ac3d2ec6 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
644 | } | 644 | } |
645 | } | 645 | } |
646 | 646 | ||
647 | static void setautogain(struct gspca_dev *gspca_dev) | ||
648 | { | ||
649 | struct sd *sd = (struct sd *) gspca_dev; | ||
650 | |||
651 | if (sd->chip_revision == Rev072A) { | ||
652 | if (sd->autogain) | ||
653 | sd->ag_cnt = AG_CNT_START; | ||
654 | else | ||
655 | sd->ag_cnt = -1; | ||
656 | } | ||
657 | } | ||
658 | |||
647 | static void sd_start(struct gspca_dev *gspca_dev) | 659 | static void sd_start(struct gspca_dev *gspca_dev) |
648 | { | 660 | { |
649 | struct sd *sd = (struct sd *) gspca_dev; | 661 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
671 | reg_w_val(dev, 0x8500, mode); /* mode */ | 683 | reg_w_val(dev, 0x8500, mode); /* mode */ |
672 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | 684 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ |
673 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 685 | reg_w_val(dev, 0x8112, 0x10 | 0x20); |
686 | setautogain(gspca_dev); | ||
674 | break; | 687 | break; |
675 | default: | 688 | default: |
676 | /* case Rev012A: */ | 689 | /* case Rev012A: */ |
@@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
720 | reg_w_val(gspca_dev->dev, 0x8114, 0); | 733 | reg_w_val(gspca_dev->dev, 0x8114, 0); |
721 | } | 734 | } |
722 | 735 | ||
723 | static void setautogain(struct gspca_dev *gspca_dev) | 736 | static void do_autogain(struct gspca_dev *gspca_dev) |
724 | { | 737 | { |
725 | struct sd *sd = (struct sd *) gspca_dev; | 738 | struct sd *sd = (struct sd *) gspca_dev; |
726 | int expotimes = 0; | 739 | int expotimes; |
727 | int pixelclk = 0; | 740 | int pixelclk; |
728 | int gainG = 0; | 741 | int gainG; |
729 | __u8 R, Gr, Gb, B; | 742 | __u8 R, Gr, Gb, B; |
730 | int y; | 743 | int y; |
731 | __u8 luma_mean = 110; | 744 | __u8 luma_mean = 110; |
732 | __u8 luma_delta = 20; | 745 | __u8 luma_delta = 20; |
733 | __u8 spring = 4; | 746 | __u8 spring = 4; |
734 | 747 | ||
748 | if (sd->ag_cnt < 0) | ||
749 | return; | ||
750 | if (--sd->ag_cnt >= 0) | ||
751 | return; | ||
752 | sd->ag_cnt = AG_CNT_START; | ||
753 | |||
735 | switch (sd->chip_revision) { | 754 | switch (sd->chip_revision) { |
736 | case Rev072A: | 755 | case Rev072A: |
737 | reg_r(gspca_dev, 0x8621, 1); | 756 | reg_r(gspca_dev, 0x8621, 1); |
@@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
795 | __u8 *data, /* isoc packet */ | 814 | __u8 *data, /* isoc packet */ |
796 | int len) /* iso packet length */ | 815 | int len) /* iso packet length */ |
797 | { | 816 | { |
798 | struct sd *sd = (struct sd *) gspca_dev; | ||
799 | |||
800 | switch (data[0]) { | 817 | switch (data[0]) { |
801 | case 0: /* start of frame */ | 818 | case 0: /* start of frame */ |
802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 819 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
803 | data, 0); | 820 | data, 0); |
804 | if (sd->ag_cnt >= 0) { | ||
805 | if (--sd->ag_cnt < 0) { | ||
806 | sd->ag_cnt = AG_CNT_START; | ||
807 | setautogain(gspca_dev); | ||
808 | } | ||
809 | } | ||
810 | data += SPCA561_OFFSET_DATA; | 821 | data += SPCA561_OFFSET_DATA; |
811 | len -= SPCA561_OFFSET_DATA; | 822 | len -= SPCA561_OFFSET_DATA; |
812 | if (data[1] & 0x10) { | 823 | if (data[1] & 0x10) { |
@@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
944 | struct sd *sd = (struct sd *) gspca_dev; | 955 | struct sd *sd = (struct sd *) gspca_dev; |
945 | 956 | ||
946 | sd->autogain = val; | 957 | sd->autogain = val; |
947 | if (val) | 958 | if (gspca_dev->streaming) |
948 | sd->ag_cnt = AG_CNT_START; | 959 | setautogain(gspca_dev); |
949 | else | ||
950 | sd->ag_cnt = -1; | ||
951 | return 0; | 960 | return 0; |
952 | } | 961 | } |
953 | 962 | ||
@@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = { | |||
971 | .stop0 = sd_stop0, | 980 | .stop0 = sd_stop0, |
972 | .close = sd_close, | 981 | .close = sd_close, |
973 | .pkt_scan = sd_pkt_scan, | 982 | .pkt_scan = sd_pkt_scan, |
983 | .dq_callback = do_autogain, | ||
974 | }; | 984 | }; |
975 | 985 | ||
976 | /* -- module initialisation -- */ | 986 | /* -- module initialisation -- */ |