aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-16 03:48:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:24:04 -0400
commita17dd1ebd5396e929c10c60237a1fab5adae57cf (patch)
tree109d4fca82a0b1b58a82545e2d7193ce8c6f6098 /drivers/media/video/gspca
parent3e0ed00903e1904112108135c18b1918386457aa (diff)
[media] nw80x: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/nw80x.c203
1 files changed, 87 insertions, 116 deletions
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
index 42e021931e60..74a05bab9f60 100644
--- a/drivers/media/video/gspca/nw80x.c
+++ b/drivers/media/video/gspca/nw80x.c
@@ -32,22 +32,10 @@ MODULE_LICENSE("GPL");
32 32
33static int webcam; 33static int webcam;
34 34
35/* controls */
36enum e_ctrl {
37 GAIN,
38 EXPOSURE,
39 AUTOGAIN,
40 NCTRLS /* number of controls */
41};
42
43#define AUTOGAIN_DEF 1
44
45/* specific webcam descriptor */ 35/* specific webcam descriptor */
46struct sd { 36struct sd {
47 struct gspca_dev gspca_dev; /* !! must be the first item */ 37 struct gspca_dev gspca_dev; /* !! must be the first item */
48 38
49 struct gspca_ctrl ctrls[NCTRLS];
50
51 u32 ae_res; 39 u32 ae_res;
52 s8 ag_cnt; 40 s8 ag_cnt;
53#define AG_CNT_START 13 41#define AG_CNT_START 13
@@ -1667,17 +1655,13 @@ static int swap_bits(int v)
1667 return r; 1655 return r;
1668} 1656}
1669 1657
1670static void setgain(struct gspca_dev *gspca_dev) 1658static void setgain(struct gspca_dev *gspca_dev, u8 val)
1671{ 1659{
1672 struct sd *sd = (struct sd *) gspca_dev; 1660 struct sd *sd = (struct sd *) gspca_dev;
1673 u8 val, v[2]; 1661 u8 v[2];
1674 1662
1675 val = sd->ctrls[GAIN].val;
1676 switch (sd->webcam) { 1663 switch (sd->webcam) {
1677 case P35u: 1664 case P35u:
1678 /* Note the control goes from 0-255 not 0-127, but anything
1679 above 127 just means amplifying noise */
1680 val >>= 1; /* 0 - 255 -> 0 - 127 */
1681 reg_w(gspca_dev, 0x1026, &val, 1); 1665 reg_w(gspca_dev, 0x1026, &val, 1);
1682 break; 1666 break;
1683 case Kr651us: 1667 case Kr651us:
@@ -1690,13 +1674,11 @@ static void setgain(struct gspca_dev *gspca_dev)
1690 } 1674 }
1691} 1675}
1692 1676
1693static void setexposure(struct gspca_dev *gspca_dev) 1677static void setexposure(struct gspca_dev *gspca_dev, s32 val)
1694{ 1678{
1695 struct sd *sd = (struct sd *) gspca_dev; 1679 struct sd *sd = (struct sd *) gspca_dev;
1696 s16 val;
1697 u8 v[2]; 1680 u8 v[2];
1698 1681
1699 val = sd->ctrls[EXPOSURE].val;
1700 switch (sd->webcam) { 1682 switch (sd->webcam) {
1701 case P35u: 1683 case P35u:
1702 v[0] = ((9 - val) << 3) | 0x01; 1684 v[0] = ((9 - val) << 3) | 0x01;
@@ -1713,14 +1695,12 @@ static void setexposure(struct gspca_dev *gspca_dev)
1713 } 1695 }
1714} 1696}
1715 1697
1716static void setautogain(struct gspca_dev *gspca_dev) 1698static void setautogain(struct gspca_dev *gspca_dev, s32 val)
1717{ 1699{
1718 struct sd *sd = (struct sd *) gspca_dev; 1700 struct sd *sd = (struct sd *) gspca_dev;
1719 int w, h; 1701 int w, h;
1720 1702
1721 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) 1703 if (!val) {
1722 return;
1723 if (!sd->ctrls[AUTOGAIN].val) {
1724 sd->ag_cnt = -1; 1704 sd->ag_cnt = -1;
1725 return; 1705 return;
1726 } 1706 }
@@ -1763,7 +1743,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1763 if ((unsigned) webcam >= NWEBCAMS) 1743 if ((unsigned) webcam >= NWEBCAMS)
1764 webcam = 0; 1744 webcam = 0;
1765 sd->webcam = webcam; 1745 sd->webcam = webcam;
1766 gspca_dev->cam.ctrls = sd->ctrls;
1767 gspca_dev->cam.needs_full_bandwidth = 1; 1746 gspca_dev->cam.needs_full_bandwidth = 1;
1768 sd->ag_cnt = -1; 1747 sd->ag_cnt = -1;
1769 1748
@@ -1834,33 +1813,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1834 break; 1813 break;
1835 } 1814 }
1836 } 1815 }
1837 switch (sd->webcam) {
1838 case P35u:
1839/* sd->ctrls[EXPOSURE].max = 9;
1840 * sd->ctrls[EXPOSURE].def = 9; */
1841 /* coarse expo auto gain function gain minimum, to avoid
1842 * a large settings jump the first auto adjustment */
1843 sd->ctrls[GAIN].def = 255 / 5 * 2;
1844 break;
1845 case Cvideopro:
1846 case DvcV6:
1847 case Kritter:
1848 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << AUTOGAIN);
1849 /* fall thru */
1850 case Kr651us:
1851 sd->ctrls[EXPOSURE].max = 315;
1852 sd->ctrls[EXPOSURE].def = 150;
1853 break;
1854 default:
1855 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << EXPOSURE)
1856 | (1 << AUTOGAIN);
1857 break;
1858 }
1859 1816
1860#if AUTOGAIN_DEF
1861 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1862 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1863#endif
1864 return gspca_dev->usb_err; 1817 return gspca_dev->usb_err;
1865} 1818}
1866 1819
@@ -1925,9 +1878,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1925 break; 1878 break;
1926 } 1879 }
1927 1880
1928 setgain(gspca_dev); 1881 v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler);
1929 setexposure(gspca_dev);
1930 setautogain(gspca_dev);
1931 sd->exp_too_high_cnt = 0; 1882 sd->exp_too_high_cnt = 0;
1932 sd->exp_too_low_cnt = 0; 1883 sd->exp_too_low_cnt = 0;
1933 return gspca_dev->usb_err; 1884 return gspca_dev->usb_err;
@@ -1987,24 +1938,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1987 } 1938 }
1988} 1939}
1989 1940
1990static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1991{
1992 struct sd *sd = (struct sd *) gspca_dev;
1993
1994 sd->ctrls[AUTOGAIN].val = val;
1995 if (val)
1996 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1997 else
1998 gspca_dev->ctrl_inac = 0;
1999 if (gspca_dev->streaming)
2000 setautogain(gspca_dev);
2001 return gspca_dev->usb_err;
2002}
2003
2004#define WANT_REGULAR_AUTOGAIN
2005#define WANT_COARSE_EXPO_AUTOGAIN
2006#include "autogain_functions.h"
2007
2008static void do_autogain(struct gspca_dev *gspca_dev) 1941static void do_autogain(struct gspca_dev *gspca_dev)
2009{ 1942{
2010 struct sd *sd = (struct sd *) gspca_dev; 1943 struct sd *sd = (struct sd *) gspca_dev;
@@ -2024,62 +1957,100 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2024 1957
2025 switch (sd->webcam) { 1958 switch (sd->webcam) {
2026 case P35u: 1959 case P35u:
2027 coarse_grained_expo_autogain(gspca_dev, luma, 100, 5); 1960 gspca_coarse_grained_expo_autogain(gspca_dev, luma, 100, 5);
2028 break; 1961 break;
2029 default: 1962 default:
2030 auto_gain_n_exposure(gspca_dev, luma, 100, 5, 230, 0); 1963 gspca_expo_autogain(gspca_dev, luma, 100, 5, 230, 0);
2031 break; 1964 break;
2032 } 1965 }
2033} 1966}
2034 1967
2035/* V4L2 controls supported by the driver */ 1968
2036static const struct ctrl sd_ctrls[NCTRLS] = { 1969static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
2037[GAIN] = { 1970{
2038 { 1971 struct gspca_dev *gspca_dev =
2039 .id = V4L2_CID_GAIN, 1972 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
2040 .type = V4L2_CTRL_TYPE_INTEGER, 1973
2041 .name = "Gain", 1974 gspca_dev->usb_err = 0;
2042 .minimum = 0, 1975
2043 .maximum = 253, 1976 if (!gspca_dev->streaming)
2044 .step = 1, 1977 return 0;
2045 .default_value = 128 1978
2046 }, 1979 switch (ctrl->id) {
2047 .set_control = setgain 1980 /* autogain/gain/exposure control cluster */
2048 }, 1981 case V4L2_CID_AUTOGAIN:
2049[EXPOSURE] = { 1982 if (ctrl->is_new)
2050 { 1983 setautogain(gspca_dev, ctrl->val);
2051 .id = V4L2_CID_EXPOSURE, 1984 if (!ctrl->val) {
2052 .type = V4L2_CTRL_TYPE_INTEGER, 1985 if (gspca_dev->gain->is_new)
2053 .name = "Exposure", 1986 setgain(gspca_dev, gspca_dev->gain->val);
2054 .minimum = 0, 1987 if (gspca_dev->exposure->is_new)
2055 .maximum = 9, 1988 setexposure(gspca_dev,
2056 .step = 1, 1989 gspca_dev->exposure->val);
2057 .default_value = 9 1990 }
2058 }, 1991 break;
2059 .set_control = setexposure 1992 /* Some webcams only have exposure, so handle that separately from the
2060 }, 1993 autogain/gain/exposure cluster in the previous case. */
2061[AUTOGAIN] = { 1994 case V4L2_CID_EXPOSURE:
2062 { 1995 setexposure(gspca_dev, gspca_dev->exposure->val);
2063 .id = V4L2_CID_AUTOGAIN, 1996 break;
2064 .type = V4L2_CTRL_TYPE_BOOLEAN, 1997 }
2065 .name = "Auto Gain", 1998 return gspca_dev->usb_err;
2066 .minimum = 0, 1999}
2067 .maximum = 1, 2000
2068 .step = 1, 2001static const struct v4l2_ctrl_ops sd_ctrl_ops = {
2069 .default_value = AUTOGAIN_DEF, 2002 .s_ctrl = sd_s_ctrl,
2070 .flags = V4L2_CTRL_FLAG_UPDATE
2071 },
2072 .set = sd_setautogain
2073 },
2074}; 2003};
2075 2004
2005static int sd_init_controls(struct gspca_dev *gspca_dev)
2006{
2007 struct sd *sd = (struct sd *)gspca_dev;
2008 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
2009
2010 gspca_dev->vdev.ctrl_handler = hdl;
2011 v4l2_ctrl_handler_init(hdl, 3);
2012 switch (sd->webcam) {
2013 case P35u:
2014 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2015 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
2016 /* For P35u choose coarse expo auto gain function gain minimum,
2017 * to avoid a large settings jump the first auto adjustment */
2018 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2019 V4L2_CID_GAIN, 0, 127, 1, 127 / 5 * 2);
2020 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2021 V4L2_CID_EXPOSURE, 0, 9, 1, 9);
2022 break;
2023 case Kr651us:
2024 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2025 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
2026 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2027 V4L2_CID_GAIN, 0, 253, 1, 128);
2028 /* fall through */
2029 case Cvideopro:
2030 case DvcV6:
2031 case Kritter:
2032 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
2033 V4L2_CID_EXPOSURE, 0, 315, 1, 150);
2034 break;
2035 default:
2036 break;
2037 }
2038
2039 if (hdl->error) {
2040 pr_err("Could not initialize controls\n");
2041 return hdl->error;
2042 }
2043 if (gspca_dev->autogain)
2044 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
2045 return 0;
2046}
2047
2076/* sub-driver description */ 2048/* sub-driver description */
2077static const struct sd_desc sd_desc = { 2049static const struct sd_desc sd_desc = {
2078 .name = MODULE_NAME, 2050 .name = MODULE_NAME,
2079 .ctrls = sd_ctrls,
2080 .nctrls = ARRAY_SIZE(sd_ctrls),
2081 .config = sd_config, 2051 .config = sd_config,
2082 .init = sd_init, 2052 .init = sd_init,
2053 .init_controls = sd_init_controls,
2083 .start = sd_start, 2054 .start = sd_start,
2084 .stopN = sd_stopN, 2055 .stopN = sd_stopN,
2085 .pkt_scan = sd_pkt_scan, 2056 .pkt_scan = sd_pkt_scan,