aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <j.w.r.degoede@hhs.nl>2008-09-03 16:12:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 17:37:40 -0400
commit038ec7c772cb093411b163c22f389787722cfd8e (patch)
tree31bc2b6adb62e0520f11bcb9647d8958b7f6be20 /drivers/media
parent086272555d1b7936512de1e6d9efacdf87169cb0 (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')
-rw-r--r--drivers/media/video/gspca/pac7311.c48
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,