diff options
Diffstat (limited to 'drivers/media/i2c/tvaudio.c')
-rw-r--r-- | drivers/media/i2c/tvaudio.c | 238 |
1 files changed, 88 insertions, 150 deletions
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index 3b24d3fc1866..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/65535/32768/32768 */ | 97 | /* initialize with (defaults to 65535/32768/32768 */ |
97 | int leftinit,rightinit,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 left, right, 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 */ |
@@ -1523,8 +1535,7 @@ static struct CHIPDESC chiplist[] = { | |||
1523 | .rightreg = TDA9875_MVR, | 1535 | .rightreg = TDA9875_MVR, |
1524 | .bassreg = TDA9875_MBA, | 1536 | .bassreg = TDA9875_MBA, |
1525 | .treblereg = TDA9875_MTR, | 1537 | .treblereg = TDA9875_MTR, |
1526 | .leftinit = 58880, | 1538 | .volinit = 58880, |
1527 | .rightinit = 58880, | ||
1528 | }, | 1539 | }, |
1529 | { | 1540 | { |
1530 | .name = "tda9850", | 1541 | .name = "tda9850", |
@@ -1618,7 +1629,8 @@ static struct CHIPDESC chiplist[] = { | |||
1618 | 1629 | ||
1619 | .inputreg = -1, | 1630 | .inputreg = -1, |
1620 | .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC }, | 1631 | .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC }, |
1621 | .inputmute = TEA6300_S_GMU, | 1632 | .inputmute = TEA6420_S_GMU, |
1633 | .inputmask = 0x07, | ||
1622 | }, | 1634 | }, |
1623 | { | 1635 | { |
1624 | .name = "tda8425", | 1636 | .name = "tda8425", |
@@ -1679,121 +1691,39 @@ 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 | { | 1695 | { |
1696 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
1685 | struct CHIPSTATE *chip = to_state(sd); | 1697 | struct CHIPSTATE *chip = to_state(sd); |
1686 | struct CHIPDESC *desc = chip->desc; | 1698 | struct CHIPDESC *desc = chip->desc; |
1687 | 1699 | ||
1688 | switch (ctrl->id) { | 1700 | switch (ctrl->id) { |
1689 | case V4L2_CID_AUDIO_MUTE: | 1701 | case V4L2_CID_AUDIO_MUTE: |
1690 | if (!(desc->flags & CHIP_HAS_INPUTSEL)) | 1702 | chip->muted = ctrl->val; |
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 = max(chip->left,chip->right); | ||
1698 | return 0; | ||
1699 | case V4L2_CID_AUDIO_BALANCE: | ||
1700 | { | ||
1701 | int volume; | ||
1702 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1703 | break; | ||
1704 | volume = max(chip->left,chip->right); | ||
1705 | if (volume) | ||
1706 | ctrl->value=(32768*min(chip->left,chip->right))/volume; | ||
1707 | else | ||
1708 | ctrl->value=32768; | ||
1709 | return 0; | ||
1710 | } | ||
1711 | case V4L2_CID_AUDIO_BASS: | ||
1712 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | ||
1713 | break; | ||
1714 | ctrl->value = chip->bass; | ||
1715 | return 0; | ||
1716 | case V4L2_CID_AUDIO_TREBLE: | ||
1717 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | ||
1718 | break; | ||
1719 | ctrl->value = chip->treble; | ||
1720 | return 0; | ||
1721 | } | ||
1722 | return -EINVAL; | ||
1723 | } | ||
1724 | |||
1725 | static int tvaudio_s_ctrl(struct v4l2_subdev *sd, | ||
1726 | struct v4l2_control *ctrl) | ||
1727 | { | ||
1728 | struct CHIPSTATE *chip = to_state(sd); | ||
1729 | struct CHIPDESC *desc = chip->desc; | ||
1730 | |||
1731 | switch (ctrl->id) { | ||
1732 | case V4L2_CID_AUDIO_MUTE: | ||
1733 | if (!(desc->flags & CHIP_HAS_INPUTSEL)) | ||
1734 | break; | ||
1735 | |||
1736 | if (ctrl->value < 0 || ctrl->value >= 2) | ||
1737 | return -ERANGE; | ||
1738 | chip->muted = ctrl->value; | ||
1739 | if (chip->muted) | 1703 | if (chip->muted) |
1740 | chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); | 1704 | chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask); |
1741 | else | 1705 | else |
1742 | chip_write_masked(chip,desc->inputreg, | 1706 | chip_write_masked(chip,desc->inputreg, |
1743 | desc->inputmap[chip->input],desc->inputmask); | 1707 | desc->inputmap[chip->input],desc->inputmask); |
1744 | return 0; | 1708 | return 0; |
1745 | case V4L2_CID_AUDIO_VOLUME: | 1709 | case V4L2_CID_AUDIO_VOLUME: { |
1746 | { | 1710 | u32 volume, balance; |
1747 | int volume,balance; | 1711 | u32 left, right; |
1748 | |||
1749 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1750 | break; | ||
1751 | |||
1752 | volume = max(chip->left,chip->right); | ||
1753 | if (volume) | ||
1754 | balance=(32768*min(chip->left,chip->right))/volume; | ||
1755 | else | ||
1756 | balance=32768; | ||
1757 | |||
1758 | volume=ctrl->value; | ||
1759 | chip->left = (min(65536 - balance,32768) * volume) / 32768; | ||
1760 | chip->right = (min(balance,volume *(__u16)32768)) / 32768; | ||
1761 | |||
1762 | chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); | ||
1763 | chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); | ||
1764 | |||
1765 | return 0; | ||
1766 | } | ||
1767 | case V4L2_CID_AUDIO_BALANCE: | ||
1768 | { | ||
1769 | int volume, balance; | ||
1770 | |||
1771 | if (!(desc->flags & CHIP_HAS_VOLUME)) | ||
1772 | break; | ||
1773 | |||
1774 | volume = max(chip->left, chip->right); | ||
1775 | balance = ctrl->value; | ||
1776 | chip->left = (min(65536 - balance, 32768) * volume) / 32768; | ||
1777 | chip->right = (min(balance, volume * (__u16)32768)) / 32768; | ||
1778 | 1712 | ||
1779 | chip_write(chip, desc->leftreg, desc->volfunc(chip->left)); | 1713 | volume = chip->volume->val; |
1780 | chip_write(chip, desc->rightreg, desc->volfunc(chip->right)); | 1714 | balance = chip->balance->val; |
1715 | left = (min(65536U - balance, 32768U) * volume) / 32768U; | ||
1716 | right = (min(balance, 32768U) * volume) / 32768U; | ||
1781 | 1717 | ||
1718 | chip_write(chip, desc->leftreg, desc->volfunc(left)); | ||
1719 | chip_write(chip, desc->rightreg, desc->volfunc(right)); | ||
1782 | return 0; | 1720 | return 0; |
1783 | } | 1721 | } |
1784 | case V4L2_CID_AUDIO_BASS: | 1722 | case V4L2_CID_AUDIO_BASS: |
1785 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | 1723 | chip_write(chip, desc->bassreg, desc->bassfunc(ctrl->val)); |
1786 | break; | ||
1787 | chip->bass = ctrl->value; | ||
1788 | chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); | ||
1789 | |||
1790 | return 0; | 1724 | return 0; |
1791 | case V4L2_CID_AUDIO_TREBLE: | 1725 | case V4L2_CID_AUDIO_TREBLE: |
1792 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) | 1726 | chip_write(chip, desc->treblereg, desc->treblefunc(ctrl->val)); |
1793 | break; | ||
1794 | chip->treble = ctrl->value; | ||
1795 | chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); | ||
1796 | |||
1797 | return 0; | 1727 | return 0; |
1798 | } | 1728 | } |
1799 | return -EINVAL; | 1729 | return -EINVAL; |
@@ -1812,35 +1742,6 @@ static int tvaudio_s_radio(struct v4l2_subdev *sd) | |||
1812 | return 0; | 1742 | return 0; |
1813 | } | 1743 | } |
1814 | 1744 | ||
1815 | static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
1816 | { | ||
1817 | struct CHIPSTATE *chip = to_state(sd); | ||
1818 | struct CHIPDESC *desc = chip->desc; | ||
1819 | |||
1820 | switch (qc->id) { | ||
1821 | case V4L2_CID_AUDIO_MUTE: | ||
1822 | if (desc->flags & CHIP_HAS_INPUTSEL) | ||
1823 | return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); | ||
1824 | break; | ||
1825 | case V4L2_CID_AUDIO_VOLUME: | ||
1826 | if (desc->flags & CHIP_HAS_VOLUME) | ||
1827 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); | ||
1828 | break; | ||
1829 | case V4L2_CID_AUDIO_BALANCE: | ||
1830 | if (desc->flags & CHIP_HAS_VOLUME) | ||
1831 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); | ||
1832 | break; | ||
1833 | case V4L2_CID_AUDIO_BASS: | ||
1834 | case V4L2_CID_AUDIO_TREBLE: | ||
1835 | if (desc->flags & CHIP_HAS_BASSTREBLE) | ||
1836 | return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); | ||
1837 | break; | ||
1838 | default: | ||
1839 | break; | ||
1840 | } | ||
1841 | return -EINVAL; | ||
1842 | } | ||
1843 | |||
1844 | static int tvaudio_s_routing(struct v4l2_subdev *sd, | 1745 | static int tvaudio_s_routing(struct v4l2_subdev *sd, |
1845 | u32 input, u32 output, u32 config) | 1746 | u32 input, u32 output, u32 config) |
1846 | { | 1747 | { |
@@ -1944,13 +1845,32 @@ static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide | |||
1944 | 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); |
1945 | } | 1846 | } |
1946 | 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 | |||
1947 | /* ----------------------------------------------------------------------- */ | 1858 | /* ----------------------------------------------------------------------- */ |
1948 | 1859 | ||
1860 | static const struct v4l2_ctrl_ops tvaudio_ctrl_ops = { | ||
1861 | .s_ctrl = tvaudio_s_ctrl, | ||
1862 | }; | ||
1863 | |||
1949 | 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, | ||
1950 | .g_chip_ident = tvaudio_g_chip_ident, | 1866 | .g_chip_ident = tvaudio_g_chip_ident, |
1951 | .queryctrl = tvaudio_queryctrl, | 1867 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
1952 | .g_ctrl = tvaudio_g_ctrl, | 1868 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, |
1953 | .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, | ||
1954 | .s_std = tvaudio_s_std, | 1874 | .s_std = tvaudio_s_std, |
1955 | }; | 1875 | }; |
1956 | 1876 | ||
@@ -2035,6 +1955,10 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2035 | else | 1955 | else |
2036 | chip_cmd(chip, "init", &desc->init); | 1956 | chip_cmd(chip, "init", &desc->init); |
2037 | 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); | ||
2038 | if (desc->flags & CHIP_HAS_VOLUME) { | 1962 | if (desc->flags & CHIP_HAS_VOLUME) { |
2039 | if (!desc->volfunc) { | 1963 | if (!desc->volfunc) { |
2040 | /* This shouldn't be happen. Warn user, but keep working | 1964 | /* This shouldn't be happen. Warn user, but keep working |
@@ -2043,12 +1967,14 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2043 | v4l2_info(sd, "volume callback undefined!\n"); | 1967 | v4l2_info(sd, "volume callback undefined!\n"); |
2044 | desc->flags &= ~CHIP_HAS_VOLUME; | 1968 | desc->flags &= ~CHIP_HAS_VOLUME; |
2045 | } else { | 1969 | } else { |
2046 | chip->left = desc->leftinit ? desc->leftinit : 65535; | 1970 | chip->volume = v4l2_ctrl_new_std(&chip->hdl, |
2047 | chip->right = desc->rightinit ? desc->rightinit : 65535; | 1971 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, |
2048 | chip_write(chip, desc->leftreg, | 1972 | 0, 65535, 65535 / 100, |
2049 | desc->volfunc(chip->left)); | 1973 | desc->volinit ? desc->volinit : 65535); |
2050 | chip_write(chip, desc->rightreg, | 1974 | chip->balance = v4l2_ctrl_new_std(&chip->hdl, |
2051 | desc->volfunc(chip->right)); | 1975 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_BALANCE, |
1976 | 0, 65535, 65535 / 100, 32768); | ||
1977 | v4l2_ctrl_cluster(2, &chip->volume); | ||
2052 | } | 1978 | } |
2053 | } | 1979 | } |
2054 | if (desc->flags & CHIP_HAS_BASSTREBLE) { | 1980 | if (desc->flags & CHIP_HAS_BASSTREBLE) { |
@@ -2059,17 +1985,28 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * | |||
2059 | v4l2_info(sd, "bass/treble callbacks undefined!\n"); | 1985 | v4l2_info(sd, "bass/treble callbacks undefined!\n"); |
2060 | desc->flags &= ~CHIP_HAS_BASSTREBLE; | 1986 | desc->flags &= ~CHIP_HAS_BASSTREBLE; |
2061 | } else { | 1987 | } else { |
2062 | chip->treble = desc->trebleinit ? | 1988 | v4l2_ctrl_new_std(&chip->hdl, |
2063 | desc->trebleinit : 32768; | 1989 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_BASS, |
2064 | chip->bass = desc->bassinit ? | 1990 | 0, 65535, 65535 / 100, |
2065 | desc->bassinit : 32768; | 1991 | desc->bassinit ? desc->bassinit : 32768); |
2066 | chip_write(chip, desc->bassreg, | 1992 | v4l2_ctrl_new_std(&chip->hdl, |
2067 | desc->bassfunc(chip->bass)); | 1993 | &tvaudio_ctrl_ops, V4L2_CID_AUDIO_TREBLE, |
2068 | chip_write(chip, desc->treblereg, | 1994 | 0, 65535, 65535 / 100, |
2069 | desc->treblefunc(chip->treble)); | 1995 | desc->trebleinit ? desc->trebleinit : 32768); |
2070 | } | 1996 | } |
2071 | } | 1997 | } |
2072 | 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 | |||
2073 | chip->thread = NULL; | 2010 | chip->thread = NULL; |
2074 | init_timer(&chip->wt); | 2011 | init_timer(&chip->wt); |
2075 | if (desc->flags & CHIP_NEED_CHECKMODE) { | 2012 | if (desc->flags & CHIP_NEED_CHECKMODE) { |
@@ -2105,6 +2042,7 @@ static int tvaudio_remove(struct i2c_client *client) | |||
2105 | } | 2042 | } |
2106 | 2043 | ||
2107 | v4l2_device_unregister_subdev(sd); | 2044 | v4l2_device_unregister_subdev(sd); |
2045 | v4l2_ctrl_handler_free(&chip->hdl); | ||
2108 | kfree(chip); | 2046 | kfree(chip); |
2109 | return 0; | 2047 | return 0; |
2110 | } | 2048 | } |