aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2011-03-22 04:53:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 15:38:20 -0400
commitf12b44ff2d5ba8eb41210438589a64490ddfedec (patch)
treedd090ff6b040102bab0e9a401058f457064a8d22 /drivers/media/video
parentbad03ff53ae3d336b5ecc5356b4739d9a693fc3d (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/media/video')
-rw-r--r--drivers/media/video/gspca/nw80x.c135
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 */
42struct sd { 44struct 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
1641static int swap_6bits(int v) 1645static 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)
1681static void setexposure(struct gspca_dev *gspca_dev) 1682static 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
1939static void do_autogain(struct gspca_dev *gspca_dev) 1960static 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