diff options
author | Hans de Goede <j.w.r.degoede@hhs.nl> | 2008-09-03 16:12:18 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-09-03 17:37:40 -0400 |
commit | 038ec7c772cb093411b163c22f389787722cfd8e (patch) | |
tree | 31bc2b6adb62e0520f11bcb9647d8958b7f6be20 /drivers/media/video | |
parent | 086272555d1b7936512de1e6d9efacdf87169cb0 (diff) |
V4L/DVB (8827): gspca: Stop pac7302 autogain oscillation.
Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/pac7311.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 35244cf98511..723219d4964e 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | Address Description | 40 | Address Description |
41 | 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on | 41 | 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on |
42 | the 7302, so one of 3, 6, 9, ... | 42 | the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? |
43 | -/0x0f Master gain 1-245, low value = high gain | 43 | -/0x0f Master gain 1-245, low value = high gain |
44 | 0x10/- Master gain 0-31 | 44 | 0x10/- Master gain 0-31 |
45 | -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) | 45 | -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) |
@@ -626,8 +626,9 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
626 | 626 | ||
627 | if (sd->sensor == SENSOR_PAC7302) { | 627 | if (sd->sensor == SENSOR_PAC7302) { |
628 | /* On the pac7302 reg2 MUST be a multiple of 3, so round it to | 628 | /* On the pac7302 reg2 MUST be a multiple of 3, so round it to |
629 | the nearest multiple of 3 */ | 629 | the nearest multiple of 3, except when between 6 and 12? */ |
630 | reg = ((reg + 1) / 3) * 3; | 630 | if (reg < 6 || reg > 12) |
631 | reg = ((reg + 1) / 3) * 3; | ||
631 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ | 632 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ |
632 | reg_w(gspca_dev, 0x02, reg); | 633 | reg_w(gspca_dev, 0x02, reg); |
633 | } else { | 634 | } else { |
@@ -761,20 +762,32 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
761 | { | 762 | { |
762 | struct sd *sd = (struct sd *) gspca_dev; | 763 | struct sd *sd = (struct sd *) gspca_dev; |
763 | int avg_lum = atomic_read(&sd->avg_lum); | 764 | int avg_lum = atomic_read(&sd->avg_lum); |
764 | int desired_lum; | 765 | int desired_lum, deadzone; |
765 | 766 | ||
766 | if (avg_lum == -1) | 767 | if (avg_lum == -1) |
767 | return; | 768 | return; |
768 | 769 | ||
769 | if (sd->sensor == SENSOR_PAC7302) | 770 | if (sd->sensor == SENSOR_PAC7302) { |
770 | desired_lum = 70 + sd->brightness * 2; | 771 | desired_lum = 270 + sd->brightness * 4; |
771 | else | 772 | /* Hack hack, with the 7202 the first exposure step is |
773 | pretty large, so if we're about to make the first | ||
774 | exposure increase make the deadzone large to avoid | ||
775 | oscilating */ | ||
776 | if (desired_lum > avg_lum && sd->gain == GAIN_DEF && | ||
777 | sd->exposure > EXPOSURE_DEF && | ||
778 | sd->exposure < 42) | ||
779 | deadzone = 90; | ||
780 | else | ||
781 | deadzone = 30; | ||
782 | } else { | ||
772 | desired_lum = 200; | 783 | desired_lum = 200; |
784 | deadzone = 20; | ||
785 | } | ||
773 | 786 | ||
774 | if (sd->autogain_ignore_frames > 0) | 787 | if (sd->autogain_ignore_frames > 0) |
775 | sd->autogain_ignore_frames--; | 788 | sd->autogain_ignore_frames--; |
776 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, | 789 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, |
777 | 10, GAIN_KNEE, EXPOSURE_KNEE)) | 790 | deadzone, GAIN_KNEE, EXPOSURE_KNEE)) |
778 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; | 791 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; |
779 | } | 792 | } |
780 | 793 | ||
@@ -802,7 +815,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
802 | int n, lum_offset, footer_length; | 815 | int n, lum_offset, footer_length; |
803 | 816 | ||
804 | if (sd->sensor == SENSOR_PAC7302) { | 817 | if (sd->sensor == SENSOR_PAC7302) { |
805 | lum_offset = 34 + sizeof pac_sof_marker; | 818 | /* 6 bytes after the FF D9 EOF marker a number of lumination |
819 | bytes are send corresponding to different parts of the | ||
820 | image, the 14th and 15th byte after the EOF seem to | ||
821 | correspond to the center of the image */ | ||
822 | lum_offset = 61 + sizeof pac_sof_marker; | ||
806 | footer_length = 74; | 823 | footer_length = 74; |
807 | } else { | 824 | } else { |
808 | lum_offset = 24 + sizeof pac_sof_marker; | 825 | lum_offset = 24 + sizeof pac_sof_marker; |
@@ -829,18 +846,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
829 | 846 | ||
830 | /* Get average lumination */ | 847 | /* Get average lumination */ |
831 | if (gspca_dev->last_packet_type == LAST_PACKET && | 848 | if (gspca_dev->last_packet_type == LAST_PACKET && |
832 | n >= lum_offset) { | 849 | n >= lum_offset) |
833 | if (sd->sensor == SENSOR_PAC7302) | 850 | atomic_set(&sd->avg_lum, data[-lum_offset] + |
834 | atomic_set(&sd->avg_lum, | ||
835 | (data[-lum_offset] << 8) | | ||
836 | data[-lum_offset + 1]); | ||
837 | else | ||
838 | atomic_set(&sd->avg_lum, | ||
839 | data[-lum_offset] + | ||
840 | data[-lum_offset + 1]); | 851 | data[-lum_offset + 1]); |
841 | } else { | 852 | else |
842 | atomic_set(&sd->avg_lum, -1); | 853 | atomic_set(&sd->avg_lum, -1); |
843 | } | ||
844 | 854 | ||
845 | /* Start the new frame with the jpeg header */ | 855 | /* Start the new frame with the jpeg header */ |
846 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 856 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |