diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-02-02 04:03:36 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-02-05 15:04:07 -0500 |
commit | c9114031d88bb71659d7f0cc74ecf8ddea47e1b7 (patch) | |
tree | da79bec74a254c1984c2028d985cd17750704ff4 /drivers/media/i2c/tvaudio.c | |
parent | 71df09bc67f08844a8af4f48966d3bb550a0fb59 (diff) |
[media] tvaudio: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/tvaudio.c')
-rw-r--r-- | drivers/media/i2c/tvaudio.c | 206 |
1 files changed, 77 insertions, 129 deletions
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index df6aaa5fbdec..e3b33b78dd21 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <media/tvaudio.h> | 39 | #include <media/tvaudio.h> |
40 | #include <media/v4l2-device.h> | 40 | #include <media/v4l2-device.h> |
41 | #include <media/v4l2-chip-ident.h> | 41 | #include <media/v4l2-chip-ident.h> |
42 | #include <media/v4l2-ctrls.h> | ||
42 | 43 | ||
43 | #include <media/i2c-addr.h> | 44 | #include <media/i2c-addr.h> |
44 | 45 | ||
@@ -91,13 +92,13 @@ struct CHIPDESC { | |||
91 | audiocmd init; | 92 | audiocmd init; |
92 | 93 | ||
93 | /* which register has which value */ | 94 | /* which register has which value */ |
94 | int leftreg,rightreg,treblereg,bassreg; | 95 | int leftreg, rightreg, treblereg, bassreg; |
95 | 96 | ||
96 | /* initialize with (defaults to 65535/32768/32768 */ | 97 | /* initialize with (defaults to 65535/32768/32768 */ |
97 | int volinit, trebleinit, bassinit; | 98 | int volinit, trebleinit, bassinit; |
98 | 99 | ||
99 | /* functions to convert the values (v4l -> chip) */ | 100 | /* functions to convert the values (v4l -> chip) */ |
100 | getvalue volfunc,treblefunc,bassfunc; | 101 | getvalue volfunc, treblefunc, bassfunc; |
101 | 102 | ||
102 | /* get/set mode */ | 103 | /* get/set mode */ |
103 | getrxsubchans getrxsubchans; | 104 | getrxsubchans getrxsubchans; |
@@ -113,6 +114,12 @@ struct CHIPDESC { | |||
113 | /* current state of the chip */ | 114 | /* current state of the chip */ |
114 | struct CHIPSTATE { | 115 | struct CHIPSTATE { |
115 | struct v4l2_subdev sd; | 116 | struct v4l2_subdev sd; |
117 | struct v4l2_ctrl_handler hdl; | ||
118 | struct { | ||
119 | /* volume/balance cluster */ | ||
120 | struct v4l2_ctrl *volume; | ||
121 | struct v4l2_ctrl *balance; | ||
122 | }; | ||
116 | 123 | ||
117 | /* chip-specific description - should point to | 124 | /* chip-specific description - should point to |
118 | an entry at CHIPDESC table */ | 125 | an entry at CHIPDESC table */ |
@@ -122,7 +129,7 @@ struct CHIPSTATE { | |||
122 | audiocmd shadow; | 129 | audiocmd shadow; |
123 | 130 | ||
124 | /* current settings */ | 131 | /* current settings */ |
125 | u16 volume, balance, treble, bass, muted; | 132 | u16 muted; |
126 | int prevmode; | 133 | int prevmode; |
127 | int radio; | 134 | int radio; |
128 | int input; | 135 | int input; |
@@ -138,6 +145,11 @@ static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd) | |||
138 | return container_of(sd, struct CHIPSTATE, sd); | 145 | return container_of(sd, struct CHIPSTATE, sd); |
139 | } | 146 | } |
140 | 147 | ||
148 | static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) | ||
149 | { | ||
150 | return &container_of(ctrl->handler, struct CHIPSTATE, hdl)->sd; | ||
151 | } | ||
152 | |||
141 | 153 | ||
142 | /* ---------------------------------------------------------------------- */ | 154 | /* ---------------------------------------------------------------------- */ |
143 | /* i2c I/O functions */ | 155 | /* i2c I/O functions */ |
@@ -1679,91 +1691,27 @@ static struct CHIPDESC chiplist[] = { | |||
1679 | 1691 | ||
1680 | /* ---------------------------------------------------------------------- */ | 1692 | /* ---------------------------------------------------------------------- */ |
1681 | 1693 | ||
1682 | static int tvaudio_g_ctrl(struct v4l2_subdev *sd, | 1694 | static int tvaudio_s_ctrl(struct v4l2_ctrl *ctrl) |
1683 | struct v4l2_control *ctrl) | ||
1684 | { | ||
1685 | struct CHIPSTATE *chip = to_state(sd); | ||
1686 | struct CHIPDESC *desc = chip->desc; | ||
1687 | |||
1688 | switch (ctrl->id) { | ||
1689 | case V4L2_CID_AUDIO_MUTE: | ||
1690 | if (!(desc->flags & CHIP_HAS_INPUTSEL)) | ||
1691 | break; | ||
1692 | ctrl->value=chip->muted; | ||
1693 | return 0; | ||
1694 | case V4L2_CID_AUDIO_VOLUME: | ||
1695 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1696 | break; | ||
1697 | ctrl->value = chip->volume; | ||
1698 | return 0; | ||
1699 | case V4L2_CID_AUDIO_BALANCE: | ||
1700 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1701 | break; | ||
1702 | ctrl->value = chip->balance; | ||
1703 | return 0; | ||
1704 | case V4L2_CID_AUDIO_BASS: | ||
1705 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | ||
1706 | break; | ||
1707 | ctrl->value = chip->bass; | ||
1708 | return 0; | ||
1709 | case V4L2_CID_AUDIO_TREBLE: | ||
1710 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | ||
1711 | break; | ||
1712 | ctrl->value = chip->treble; | ||
1713 | return 0; | ||
1714 | } | ||
1715 | return -EINVAL; | ||
1716 | } | ||
1717 | |||
1718 | static int tvaudio_s_ctrl(struct v4l2_subdev *sd, | ||
1719 | struct v4l2_control *ctrl) | ||
1720 | { | 1695 | { |
1696 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
1721 | struct CHIPSTATE *chip = to_state(sd); | 1697 | struct CHIPSTATE *chip = to_state(sd); |
1722 | struct CHIPDESC *desc = chip->desc; | 1698 | struct CHIPDESC *desc = chip->desc; |
1723 | 1699 | ||
1724 | switch (ctrl->id) { | 1700 | switch (ctrl->id) { |
1725 | case V4L2_CID_AUDIO_MUTE: | 1701 | case V4L2_CID_AUDIO_MUTE: |
1726 | if (!(desc->flags & CHIP_HAS_INPUTSEL)) | 1702 | chip->muted = ctrl->val; |
1727 | break; | ||
1728 | |||
1729 | if (ctrl->value < 0 || ctrl->value >= 2) | ||
1730 | return -ERANGE; | ||
1731 | chip->muted = ctrl->value; | ||
1732 | if (chip->muted) | 1703 | if (chip->muted) |
1733 | chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); | 1704 | chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); |
1734 | else | 1705 | else |
1735 | chip_write_masked(chip,desc->inputreg, | 1706 | chip_write_masked(chip,desc->inputreg, |
1736 | desc->inputmap[chip->input],desc->inputmask); | 1707 | desc->inputmap[chip->input],desc->inputmask); |
1737 | return 0; | 1708 | return 0; |
1738 | case V4L2_CID_AUDIO_VOLUME: | 1709 | case V4L2_CID_AUDIO_VOLUME: { |
1739 | { | ||
1740 | u32 volume, balance; | ||
1741 | u32 left, right; | ||
1742 | |||
1743 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1744 | break; | ||
1745 | |||
1746 | volume = ctrl->value; | ||
1747 | chip->volume = volume; | ||
1748 | balance = chip->balance; | ||
1749 | left = (min(65536U - balance, 32768U) * volume) / 32768U; | ||
1750 | right = (min(balance, 32768U) * volume) / 32768U; | ||
1751 | |||
1752 | chip_write(chip, desc->leftreg, desc->volfunc(left)); | ||
1753 | chip_write(chip, desc->rightreg, desc->volfunc(right)); | ||
1754 | return 0; | ||
1755 | } | ||
1756 | case V4L2_CID_AUDIO_BALANCE: | ||
1757 | { | ||
1758 | u32 volume, balance; | 1710 | u32 volume, balance; |
1759 | u32 left, right; | 1711 | u32 left, right; |
1760 | 1712 | ||
1761 | if (!(desc->flags & CHIP_HAS_VOLUME)) | 1713 | volume = chip->volume->val; |
1762 | break; | 1714 | balance = chip->balance->val; |
1763 | |||
1764 | balance = ctrl->value; | ||
1765 | chip->balance = balance; | ||
1766 | volume = chip->volume; | ||
1767 | left = (min(65536U - balance, 32768U) * volume) / 32768U; | 1715 | left = (min(65536U - balance, 32768U) * volume) / 32768U; |
1768 | right = (min(balance, 32768U) * volume) / 32768U; | 1716 | right = (min(balance, 32768U) * volume) / 32768U; |
1769 | 1717 | ||
@@ -1772,18 +1720,10 @@ static int tvaudio_s_ctrl(struct v4l2_subdev *sd, | |||
1772 | return 0; | 1720 | return 0; |
1773 | } | 1721 | } |
1774 | case V4L2_CID_AUDIO_BASS: | 1722 | case V4L2_CID_AUDIO_BASS: |
1775 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | 1723 | chip_write(chip, desc->bassreg, desc->bassfunc(ctrl->val)); |
1776 | break; | ||
1777 | chip->bass = ctrl->value; | ||
1778 | chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); | ||
1779 | |||
1780 | return 0; | 1724 | return 0; |
1781 | case V4L2_CID_AUDIO_TREBLE: | 1725 | case V4L2_CID_AUDIO_TREBLE: |
1782 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | 1726 | chip_write(chip, desc->treblereg, desc->treblefunc(ctrl->val)); |
1783 | break; | ||
1784 | chip->treble = ctrl->value; | ||
1785 | chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); | ||
1786 | |||
1787 | return 0; | 1727 | return 0; |
1788 | } | 1728 | } |
1789 | return -EINVAL; | 1729 | return -EINVAL; |
@@ -1802,35 +1742,6 @@ static int tvaudio_s_radio(struct v4l2_subdev *sd) | |||
1802 | return 0; | 1742 | return 0; |
1803 | } | 1743 | } |
1804 | 1744 | ||
1805 | static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
1806 | { | ||
1807 | struct CHIPSTATE *chip = to_state(sd); | ||
1808 | struct CHIPDESC *desc = chip->desc; | ||
1809 | |||
1810 | switch (qc->id) { | ||
1811 | case V4L2_CID_AUDIO_MUTE: | ||
1812 | if (desc->flags & CHIP_HAS_INPUTSEL) | ||
1813 | return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); | ||
1814 | break; | ||
1815 | case V4L2_CID_AUDIO_VOLUME: | ||
1816 | if (desc->flags & CHIP_HAS_VOLUME) | ||
1817 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); | ||
1818 | break; | ||
1819 | case V4L2_CID_AUDIO_BALANCE: | ||
1820 | if (desc->flags & CHIP_HAS_VOLUME) | ||
1821 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); | ||
1822 | break; | ||
1823 | case V4L2_CID_AUDIO_BASS: | ||
1824 | case V4L2_CID_AUDIO_TREBLE: | ||
1825 | if (desc->flags & CHIP_HAS_BASSTREBLE) | ||
1826 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); | ||
1827 | break; | ||
1828 | default: | ||
1829 | break; | ||
1830 | } | ||
1831 | return -EINVAL; | ||
1832 | } | ||
1833 | |||
1834 | static int tvaudio_s_routing(struct v4l2_subdev *sd, | 1745 | static int tvaudio_s_routing(struct v4l2_subdev *sd, |
1835 | u32 input, u32 output, u32 config) | 1746 | u32 input, u32 output, u32 config) |
1836 | { | 1747 | { |
@@ -1934,13 +1845,32 @@ static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide | |||
1934 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0); | 1845 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0); |
1935 | } | 1846 | } |
1936 | 1847 | ||
1848 | static int tvaudio_log_status(struct v4l2_subdev *sd) | ||
1849 | { | ||
1850 | struct CHIPSTATE *chip = to_state(sd); | ||
1851 | struct CHIPDESC *desc = chip->desc; | ||
1852 | |||
1853 | v4l2_info(sd, "Chip: %s\n", desc->name); | ||
1854 | v4l2_ctrl_handler_log_status(&chip->hdl, sd->name); | ||
1855 | return 0; | ||
1856 | } | ||
1857 | |||
1937 | /* ----------------------------------------------------------------------- */ | 1858 | /* ----------------------------------------------------------------------- */ |
1938 | 1859 | ||
1860 | static const struct v4l2_ctrl_ops tvaudio_ctrl_ops = { | ||
1861 | .s_ctrl = tvaudio_s_ctrl, | ||
1862 | }; | ||
1863 | |||
1939 | static const struct v4l2_subdev_core_ops tvaudio_core_ops = { | 1864 | static const struct v4l2_subdev_core_ops tvaudio_core_ops = { |
1865 | .log_status = tvaudio_log_status, | ||
1940 | .g_chip_ident = tvaudio_g_chip_ident, | 1866 | .g_chip_ident = tvaudio_g_chip_ident, |
1941 | .queryctrl = tvaudio_queryctrl, | 1867 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
1942 | .g_ctrl = tvaudio_g_ctrl, | 1868 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, |
1943 | .s_ctrl = tvaudio_s_ctrl, | 1869 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, |
1870 | .g_ctrl = v4l2_subdev_g_ctrl, | ||
1871 | .s_ctrl = v4l2_subdev_s_ctrl, | ||
1872 | .queryctrl = v4l2_subdev_queryctrl, | ||
1873 | .querymenu = v4l2_subdev_querymenu, | ||
1944 | .s_std = tvaudio_s_std, | 1874 | .s_std = tvaudio_s_std, |
1945 | }; | 1875 | }; |
1946 | 1876 | ||
@@ -2025,6 +1955,10 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2025 | else | 1955 | else |
2026 | chip_cmd(chip, "init", &desc->init); | 1956 | chip_cmd(chip, "init", &desc->init); |
2027 | 1957 | ||
1958 | v4l2_ctrl_handler_init(&chip->hdl, 5); | ||
1959 | if (desc->flags & CHIP_HAS_INPUTSEL) | ||
1960 | v4l2_ctrl_new_std(&chip->hdl, &tvaudio_ctrl_ops, | ||
1961 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | ||
2028 | if (desc->flags & CHIP_HAS_VOLUME) { | 1962 | if (desc->flags & CHIP_HAS_VOLUME) { |
2029 | if (!desc->volfunc) { | 1963 | if (!desc->volfunc) { |
2030 | /* This shouldn't be happen. Warn user, but keep working | 1964 | /* This shouldn't be happen. Warn user, but keep working |
@@ -2033,12 +1967,14 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2033 | v4l2_info(sd, "volume callback undefined!\n"); | 1967 | v4l2_info(sd, "volume callback undefined!\n"); |
2034 | desc->flags &= ~CHIP_HAS_VOLUME; | 1968 | desc->flags &= ~CHIP_HAS_VOLUME; |
2035 | } else { | 1969 | } else { |
2036 | chip->volume = desc->volinit ? desc->volinit : 65535; | 1970 | chip->volume = v4l2_ctrl_new_std(&chip->hdl, |
2037 | chip->balance = 32768; | 1971 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, |
2038 | chip_write(chip, desc->leftreg, | 1972 | 0, 65535, 65535 / 100, |
2039 | desc->volfunc(chip->volume)); | 1973 | desc->volinit ? desc->volinit : 65535); |
2040 | chip_write(chip, desc->rightreg, | 1974 | chip->balance = v4l2_ctrl_new_std(&chip->hdl, |
2041 | desc->volfunc(chip->volume)); | 1975 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_BALANCE, |
1976 | 0, 65535, 65535 / 100, 32768); | ||
1977 | v4l2_ctrl_cluster(2, &chip->volume); | ||
2042 | } | 1978 | } |
2043 | } | 1979 | } |
2044 | if (desc->flags & CHIP_HAS_BASSTREBLE) { | 1980 | if (desc->flags & CHIP_HAS_BASSTREBLE) { |
@@ -2049,17 +1985,28 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2049 | v4l2_info(sd, "bass/treble callbacks undefined!\n"); | 1985 | v4l2_info(sd, "bass/treble callbacks undefined!\n"); |
2050 | desc->flags &= ~CHIP_HAS_BASSTREBLE; | 1986 | desc->flags &= ~CHIP_HAS_BASSTREBLE; |
2051 | } else { | 1987 | } else { |
2052 | chip->treble = desc->trebleinit ? | 1988 | v4l2_ctrl_new_std(&chip->hdl, |
2053 | desc->trebleinit : 32768; | 1989 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_BASS, |
2054 | chip->bass = desc->bassinit ? | 1990 | 0, 65535, 65535 / 100, |
2055 | desc->bassinit : 32768; | 1991 | desc->bassinit ? desc->bassinit : 32768); |
2056 | chip_write(chip, desc->bassreg, | 1992 | v4l2_ctrl_new_std(&chip->hdl, |
2057 | desc->bassfunc(chip->bass)); | 1993 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_TREBLE, |
2058 | chip_write(chip, desc->treblereg, | 1994 | 0, 65535, 65535 / 100, |
2059 | desc->treblefunc(chip->treble)); | 1995 | desc->trebleinit ? desc->trebleinit : 32768); |
2060 | } | 1996 | } |
2061 | } | 1997 | } |
2062 | 1998 | ||
1999 | sd->ctrl_handler = &chip->hdl; | ||
2000 | if (chip->hdl.error) { | ||
2001 | int err = chip->hdl.error; | ||
2002 | |||
2003 | v4l2_ctrl_handler_free(&chip->hdl); | ||
2004 | kfree(chip); | ||
2005 | return err; | ||
2006 | } | ||
2007 | /* set controls to the default values */ | ||
2008 | v4l2_ctrl_handler_setup(&chip->hdl); | ||
2009 | |||
2063 | chip->thread = NULL; | 2010 | chip->thread = NULL; |
2064 | init_timer(&chip->wt); | 2011 | init_timer(&chip->wt); |
2065 | if (desc->flags & CHIP_NEED_CHECKMODE) { | 2012 | if (desc->flags & CHIP_NEED_CHECKMODE) { |
@@ -2095,6 +2042,7 @@ static int tvaudio_remove(struct i2c_client *client) | |||
2095 | } | 2042 | } |
2096 | 2043 | ||
2097 | v4l2_device_unregister_subdev(sd); | 2044 | v4l2_device_unregister_subdev(sd); |
2045 | v4l2_ctrl_handler_free(&chip->hdl); | ||
2098 | kfree(chip); | 2046 | kfree(chip); |
2099 | return 0; | 2047 | return 0; |
2100 | } | 2048 | } |