diff options
author | Jean-François Moine <moinejf@free.fr> | 2011-03-22 04:53:21 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 15:38:20 -0400 |
commit | f12b44ff2d5ba8eb41210438589a64490ddfedec (patch) | |
tree | dd090ff6b040102bab0e9a401058f457064a8d22 /drivers | |
parent | bad03ff53ae3d336b5ecc5356b4739d9a693fc3d (diff) |
[media] gspca - nw80x: Fix the gain, exposure and autogain
The autogain now uses common functions.
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/nw80x.c | 135 |
1 files changed, 46 insertions, 89 deletions
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c index f4c6f407f56e..d2d356e87539 100644 --- a/drivers/media/video/gspca/nw80x.c +++ b/drivers/media/video/gspca/nw80x.c | |||
@@ -38,6 +38,8 @@ enum e_ctrl { | |||
38 | NCTRLS /* number of controls */ | 38 | NCTRLS /* number of controls */ |
39 | }; | 39 | }; |
40 | 40 | ||
41 | #define AUTOGAIN_DEF 1 | ||
42 | |||
41 | /* specific webcam descriptor */ | 43 | /* specific webcam descriptor */ |
42 | struct sd { | 44 | struct sd { |
43 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 45 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
@@ -47,6 +49,8 @@ struct sd { | |||
47 | u32 ae_res; | 49 | u32 ae_res; |
48 | s8 ag_cnt; | 50 | s8 ag_cnt; |
49 | #define AG_CNT_START 13 | 51 | #define AG_CNT_START 13 |
52 | u8 exp_too_low_cnt; | ||
53 | u8 exp_too_high_cnt; | ||
50 | 54 | ||
51 | u8 bridge; | 55 | u8 bridge; |
52 | u8 webcam; | 56 | u8 webcam; |
@@ -1638,12 +1642,12 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
1638 | } | 1642 | } |
1639 | } | 1643 | } |
1640 | 1644 | ||
1641 | static int swap_6bits(int v) | 1645 | static int swap_bits(int v) |
1642 | { | 1646 | { |
1643 | int r, i; | 1647 | int r, i; |
1644 | 1648 | ||
1645 | r = 0; | 1649 | r = 0; |
1646 | for (i = 0; i < 6; i++) { | 1650 | for (i = 0; i < 8; i++) { |
1647 | r <<= 1; | 1651 | r <<= 1; |
1648 | if (v & 1) | 1652 | if (v & 1) |
1649 | r++; | 1653 | r++; |
@@ -1657,20 +1661,17 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
1657 | struct sd *sd = (struct sd *) gspca_dev; | 1661 | struct sd *sd = (struct sd *) gspca_dev; |
1658 | u8 val, v[2]; | 1662 | u8 val, v[2]; |
1659 | 1663 | ||
1660 | val = sd->ctrls[GAIN].val >> 1; /* 0 - 63 -> 0 - 31 */ | 1664 | val = sd->ctrls[GAIN].val; |
1661 | reg_w(gspca_dev, 0x100e, &val, 1); /* AE Y gain */ | ||
1662 | |||
1663 | switch (sd->webcam) { | 1665 | switch (sd->webcam) { |
1664 | case P35u: | 1666 | case P35u: |
1665 | /* Note the control goes from 0-255 not 0-127, but anything | 1667 | /* Note the control goes from 0-255 not 0-127, but anything |
1666 | above 127 just means amplifying noise */ | 1668 | above 127 just means amplifying noise */ |
1667 | val = sd->ctrls[GAIN].val << 1; /* 0 - 63 -> 0 - 127 */ | 1669 | val >>= 1; /* 0 - 255 -> 0 - 127 */ |
1668 | reg_w(gspca_dev, 0x1026, &val, 1); | 1670 | reg_w(gspca_dev, 0x1026, &val, 1); |
1669 | break; | 1671 | break; |
1670 | case Kr651us: | 1672 | case Kr651us: |
1671 | /* 0 - 63 -> 0 - 0x37 */ | 1673 | /* 0 - 253 */ |
1672 | val = (sd->ctrls[GAIN].val * 0x37) / 63; | 1674 | val = swap_bits(val); |
1673 | val = swap_6bits(val); | ||
1674 | v[0] = val << 3; | 1675 | v[0] = val << 3; |
1675 | v[1] = val >> 5; | 1676 | v[1] = val >> 5; |
1676 | reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */ | 1677 | reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */ |
@@ -1681,16 +1682,18 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
1681 | static void setexposure(struct gspca_dev *gspca_dev) | 1682 | static void setexposure(struct gspca_dev *gspca_dev) |
1682 | { | 1683 | { |
1683 | struct sd *sd = (struct sd *) gspca_dev; | 1684 | struct sd *sd = (struct sd *) gspca_dev; |
1685 | s16 val; | ||
1684 | u8 v[2]; | 1686 | u8 v[2]; |
1685 | 1687 | ||
1688 | val = sd->ctrls[EXPOSURE].val; | ||
1686 | switch (sd->webcam) { | 1689 | switch (sd->webcam) { |
1687 | case P35u: | 1690 | case P35u: |
1688 | v[0] = (sd->ctrls[EXPOSURE].val << 3) | 0x01; | 1691 | v[0] = ((9 - val) << 3) | 0x01; |
1689 | reg_w(gspca_dev, 0x1019, v, 1); | 1692 | reg_w(gspca_dev, 0x1019, v, 1); |
1690 | break; | 1693 | break; |
1691 | case Kr651us: | 1694 | case Kr651us: |
1692 | v[0] = sd->ctrls[EXPOSURE].val; | 1695 | v[0] = val; |
1693 | v[1] = sd->ctrls[EXPOSURE].val >> 8; | 1696 | v[1] = val >> 8; |
1694 | reg_w(gspca_dev, 0x101b, v, 2); | 1697 | reg_w(gspca_dev, 0x101b, v, 2); |
1695 | break; | 1698 | break; |
1696 | } | 1699 | } |
@@ -1788,16 +1791,30 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1788 | switch (sd->webcam) { | 1791 | switch (sd->webcam) { |
1789 | case P35u: | 1792 | case P35u: |
1790 | /* sd->ctrls[EXPOSURE].max = 9; | 1793 | /* sd->ctrls[EXPOSURE].max = 9; |
1791 | * sd->ctrls[EXPOSURE].def = 1; */ | 1794 | * sd->ctrls[EXPOSURE].def = 9; */ |
1795 | /* coarse expo auto gain function gain minimum, to avoid | ||
1796 | * a large settings jump the first auto adjustment */ | ||
1797 | sd->ctrls[GAIN].def = 255 / 5 * 2; | ||
1792 | break; | 1798 | break; |
1799 | case Cvideopro: | ||
1800 | case DvcV6: | ||
1801 | case Kritter: | ||
1802 | gspca_dev->ctrl_dis = (1 << GAIN) | (1 << AUTOGAIN); | ||
1803 | /* fall thru */ | ||
1793 | case Kr651us: | 1804 | case Kr651us: |
1794 | sd->ctrls[EXPOSURE].max = 315; | 1805 | sd->ctrls[EXPOSURE].max = 315; |
1795 | sd->ctrls[EXPOSURE].def = 150; | 1806 | sd->ctrls[EXPOSURE].def = 150; |
1796 | break; | 1807 | break; |
1797 | default: | 1808 | default: |
1798 | gspca_dev->ctrl_dis = ~(1 << GAIN); | 1809 | gspca_dev->ctrl_dis = (1 << GAIN) | (1 << EXPOSURE) |
1810 | | (1 << AUTOGAIN); | ||
1799 | break; | 1811 | break; |
1800 | } | 1812 | } |
1813 | |||
1814 | #if AUTOGAIN_DEF | ||
1815 | if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN))) | ||
1816 | gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE); | ||
1817 | #endif | ||
1801 | return gspca_dev->usb_err; | 1818 | return gspca_dev->usb_err; |
1802 | } | 1819 | } |
1803 | 1820 | ||
@@ -1865,6 +1882,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1865 | setgain(gspca_dev); | 1882 | setgain(gspca_dev); |
1866 | setexposure(gspca_dev); | 1883 | setexposure(gspca_dev); |
1867 | setautogain(gspca_dev); | 1884 | setautogain(gspca_dev); |
1885 | sd->exp_too_high_cnt = 0; | ||
1886 | sd->exp_too_low_cnt = 0; | ||
1868 | return gspca_dev->usb_err; | 1887 | return gspca_dev->usb_err; |
1869 | } | 1888 | } |
1870 | 1889 | ||
@@ -1936,11 +1955,12 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1936 | return gspca_dev->usb_err; | 1955 | return gspca_dev->usb_err; |
1937 | } | 1956 | } |
1938 | 1957 | ||
1958 | #include "autogain_functions.h" | ||
1959 | |||
1939 | static void do_autogain(struct gspca_dev *gspca_dev) | 1960 | static void do_autogain(struct gspca_dev *gspca_dev) |
1940 | { | 1961 | { |
1941 | struct sd *sd = (struct sd *) gspca_dev; | 1962 | struct sd *sd = (struct sd *) gspca_dev; |
1942 | int luma; | 1963 | int luma; |
1943 | int gain, shutter; | ||
1944 | 1964 | ||
1945 | if (sd->ag_cnt < 0) | 1965 | if (sd->ag_cnt < 0) |
1946 | return; | 1966 | return; |
@@ -1954,76 +1974,13 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1954 | + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | 1974 | + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; |
1955 | luma /= sd->ae_res; | 1975 | luma /= sd->ae_res; |
1956 | 1976 | ||
1957 | if (sd->webcam == P35u) { | 1977 | switch (sd->webcam) { |
1958 | u8 clock; | 1978 | case P35u: |
1959 | 1979 | coarse_grained_expo_autogain(gspca_dev, luma, 100, 5); | |
1960 | if (luma > 92 && luma < 108) | 1980 | break; |
1961 | return; /* fine */ | 1981 | default: |
1962 | clock = sd->ctrls[EXPOSURE].val; | 1982 | auto_gain_n_exposure(gspca_dev, luma, 100, 5, 230, 0); |
1963 | gain = sd->ctrls[GAIN].val; | 1983 | break; |
1964 | if (luma < 100) { | ||
1965 | if (luma < 70 && clock > 0) | ||
1966 | clock--; | ||
1967 | if (gain > 98 && clock > 0) | ||
1968 | clock--; | ||
1969 | if (gain <= 50) | ||
1970 | gain += 3; | ||
1971 | } else { | ||
1972 | if (luma > 150 && clock < 9) | ||
1973 | clock++; | ||
1974 | if (gain < 12 && clock < 9) | ||
1975 | clock++; | ||
1976 | if (gain >= 5) | ||
1977 | gain -= 3; | ||
1978 | } | ||
1979 | if (gain != sd->ctrls[GAIN].val) { | ||
1980 | sd->ctrls[GAIN].val = gain; | ||
1981 | setgain(gspca_dev); | ||
1982 | } | ||
1983 | if (clock != sd->ctrls[EXPOSURE].val) { | ||
1984 | sd->ctrls[EXPOSURE].val = clock; | ||
1985 | setexposure(gspca_dev); | ||
1986 | } | ||
1987 | return; | ||
1988 | } | ||
1989 | |||
1990 | /* kr651us */ | ||
1991 | if (luma > 95 && luma < 105) | ||
1992 | return; /* fine */ | ||
1993 | gain = sd->ctrls[GAIN].val; | ||
1994 | shutter = sd->ctrls[EXPOSURE].val; | ||
1995 | if (luma < 100) { | ||
1996 | if (shutter > 0) { | ||
1997 | if (luma < 85 && shutter > 50) | ||
1998 | shutter -= 50; | ||
1999 | else | ||
2000 | shutter--; | ||
2001 | } else if (gain < 63) { | ||
2002 | if (luma < 85 && gain < 53) | ||
2003 | gain += 10; | ||
2004 | else | ||
2005 | gain++; | ||
2006 | } | ||
2007 | } else { | ||
2008 | if (gain > 0) { | ||
2009 | if (luma > 115 && gain > 10) | ||
2010 | gain -= 10; | ||
2011 | else | ||
2012 | gain--; | ||
2013 | } else if (shutter < 316) { /* max 0x13b */ | ||
2014 | if (luma > 115 && shutter < 266) | ||
2015 | shutter += 50; | ||
2016 | else | ||
2017 | shutter++; | ||
2018 | } | ||
2019 | } | ||
2020 | if (gain != sd->ctrls[GAIN].val) { | ||
2021 | sd->ctrls[GAIN].val = gain; | ||
2022 | setgain(gspca_dev); | ||
2023 | } | ||
2024 | if (shutter != sd->ctrls[EXPOSURE].val) { | ||
2025 | sd->ctrls[EXPOSURE].val = shutter; | ||
2026 | setexposure(gspca_dev); | ||
2027 | } | 1984 | } |
2028 | } | 1985 | } |
2029 | 1986 | ||
@@ -2035,9 +1992,9 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
2035 | .type = V4L2_CTRL_TYPE_INTEGER, | 1992 | .type = V4L2_CTRL_TYPE_INTEGER, |
2036 | .name = "Gain", | 1993 | .name = "Gain", |
2037 | .minimum = 0, | 1994 | .minimum = 0, |
2038 | .maximum = 63, | 1995 | .maximum = 253, |
2039 | .step = 1, | 1996 | .step = 1, |
2040 | .default_value = 16 | 1997 | .default_value = 128 |
2041 | }, | 1998 | }, |
2042 | .set_control = setgain | 1999 | .set_control = setgain |
2043 | }, | 2000 | }, |
@@ -2049,7 +2006,7 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
2049 | .minimum = 0, | 2006 | .minimum = 0, |
2050 | .maximum = 9, | 2007 | .maximum = 9, |
2051 | .step = 1, | 2008 | .step = 1, |
2052 | .default_value = 1 | 2009 | .default_value = 9 |
2053 | }, | 2010 | }, |
2054 | .set_control = setexposure | 2011 | .set_control = setexposure |
2055 | }, | 2012 | }, |
@@ -2061,7 +2018,7 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
2061 | .minimum = 0, | 2018 | .minimum = 0, |
2062 | .maximum = 1, | 2019 | .maximum = 1, |
2063 | .step = 1, | 2020 | .step = 1, |
2064 | .default_value = 1, | 2021 | .default_value = AUTOGAIN_DEF, |
2065 | .flags = V4L2_CTRL_FLAG_UPDATE | 2022 | .flags = V4L2_CTRL_FLAG_UPDATE |
2066 | }, | 2023 | }, |
2067 | .set = sd_setautogain | 2024 | .set = sd_setautogain |