aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:47:46 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:47:46 -0500
commita421018e8c10e5593a1fee076af72a66c3fe8ca3 (patch)
tree2854511845d0e07d33726a13eda6de1059a5c9df /sound/soc/soc-dapm.c
parent3ad1f3b35e8309ec93454dbf89beaafcdb5312da (diff)
parent86e1d57e4f24ca27ce813bdc2afaac4adafcbaf4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (294 commits) S3C64XX: Staticise platform data for PCM devices ASoC: Rename controls with a / in wm_hubs snd-fm801: autodetect SF64-PCR (tuner-only) card ALSA: tea575x-tuner: fix mute ASoC: au1x: dbdma2: plug memleak in pcm device creation error path ASoC: au1x: dbdma2: fix oops on soc device removal. ALSA: hda - Fix memory leaks in the previous patch ALSA: hda - Add ALC661/259, ALC892/888VD support ALSA: opti9xx: remove snd_opti9xx fields ALSA: aaci - Clean up duplicate code ALSA: usb - Fix mixer map for Hercules Gamesurround Muse Pocket LT ALSA: hda - Add position_fix quirk for HP dv3 ALSA: hda - Add a pin-fix for FSC Amilo Pi1505 ALSA: hda - Fix Cxt5047 test mode ASoC: pxa/raumfeld: adopt new snd_soc_dai_set_pll() API ASoC: sh: fsi: Add runtime PM support sh: ms7724se: Add runtime PM support for FSI ALSA: hda - Add a position_fix quirk for MSI Wind U115 ALSA: opti-miro: add PnP detection ALSA: opti-miro: separate comon probing code ...
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c135
1 files changed, 99 insertions, 36 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 66d4c165f99b..0d294ef72590 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -719,6 +719,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
719 719
720 /* Check if one of our outputs is connected */ 720 /* Check if one of our outputs is connected */
721 list_for_each_entry(path, &w->sinks, list_source) { 721 list_for_each_entry(path, &w->sinks, list_source) {
722 if (path->connected &&
723 !path->connected(path->source, path->sink))
724 continue;
725
722 if (path->sink && path->sink->power_check && 726 if (path->sink && path->sink->power_check &&
723 path->sink->power_check(path->sink)) { 727 path->sink->power_check(path->sink)) {
724 power = 1; 728 power = 1;
@@ -1152,6 +1156,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1152 w->active ? "active" : "inactive"); 1156 w->active ? "active" : "inactive");
1153 1157
1154 list_for_each_entry(p, &w->sources, list_sink) { 1158 list_for_each_entry(p, &w->sources, list_sink) {
1159 if (p->connected && !p->connected(w, p->sink))
1160 continue;
1161
1155 if (p->connect) 1162 if (p->connect)
1156 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1163 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1157 " in %s %s\n", 1164 " in %s %s\n",
@@ -1159,6 +1166,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1159 p->source->name); 1166 p->source->name);
1160 } 1167 }
1161 list_for_each_entry(p, &w->sinks, list_source) { 1168 list_for_each_entry(p, &w->sinks, list_source) {
1169 if (p->connected && !p->connected(w, p->sink))
1170 continue;
1171
1162 if (p->connect) 1172 if (p->connect)
1163 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1173 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1164 " out %s %s\n", 1174 " out %s %s\n",
@@ -1206,8 +1216,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1206 1216
1207/* test and update the power status of a mux widget */ 1217/* test and update the power status of a mux widget */
1208static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1218static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1209 struct snd_kcontrol *kcontrol, int mask, 1219 struct snd_kcontrol *kcontrol, int change,
1210 int mux, int val, struct soc_enum *e) 1220 int mux, struct soc_enum *e)
1211{ 1221{
1212 struct snd_soc_dapm_path *path; 1222 struct snd_soc_dapm_path *path;
1213 int found = 0; 1223 int found = 0;
@@ -1216,7 +1226,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1216 widget->id != snd_soc_dapm_value_mux) 1226 widget->id != snd_soc_dapm_value_mux)
1217 return -ENODEV; 1227 return -ENODEV;
1218 1228
1219 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 1229 if (!change)
1220 return 0; 1230 return 0;
1221 1231
1222 /* find dapm widget path assoc with kcontrol */ 1232 /* find dapm widget path assoc with kcontrol */
@@ -1401,10 +1411,13 @@ int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1401EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1411EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1402 1412
1403static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1413static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1404 const char *sink, const char *control, const char *source) 1414 const struct snd_soc_dapm_route *route)
1405{ 1415{
1406 struct snd_soc_dapm_path *path; 1416 struct snd_soc_dapm_path *path;
1407 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1417 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1418 const char *sink = route->sink;
1419 const char *control = route->control;
1420 const char *source = route->source;
1408 int ret = 0; 1421 int ret = 0;
1409 1422
1410 /* find src and dest widgets */ 1423 /* find src and dest widgets */
@@ -1428,6 +1441,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1428 1441
1429 path->source = wsource; 1442 path->source = wsource;
1430 path->sink = wsink; 1443 path->sink = wsink;
1444 path->connected = route->connected;
1431 INIT_LIST_HEAD(&path->list); 1445 INIT_LIST_HEAD(&path->list);
1432 INIT_LIST_HEAD(&path->list_source); 1446 INIT_LIST_HEAD(&path->list_source);
1433 INIT_LIST_HEAD(&path->list_sink); 1447 INIT_LIST_HEAD(&path->list_sink);
@@ -1528,8 +1542,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1528 int i, ret; 1542 int i, ret;
1529 1543
1530 for (i = 0; i < num; i++) { 1544 for (i = 0; i < num; i++) {
1531 ret = snd_soc_dapm_add_route(codec, route->sink, 1545 ret = snd_soc_dapm_add_route(codec, route);
1532 route->control, route->source);
1533 if (ret < 0) { 1546 if (ret < 0) {
1534 printk(KERN_ERR "Failed to add route %s->%s\n", 1547 printk(KERN_ERR "Failed to add route %s->%s\n",
1535 route->source, 1548 route->source,
@@ -1766,7 +1779,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1766{ 1779{
1767 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1780 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1768 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1781 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1769 unsigned int val, mux; 1782 unsigned int val, mux, change;
1770 unsigned int mask, bitmask; 1783 unsigned int mask, bitmask;
1771 int ret = 0; 1784 int ret = 0;
1772 1785
@@ -1786,20 +1799,21 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1786 1799
1787 mutex_lock(&widget->codec->mutex); 1800 mutex_lock(&widget->codec->mutex);
1788 widget->value = val; 1801 widget->value = val;
1789 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1802 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1790 if (widget->event) { 1803 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1791 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1804
1792 ret = widget->event(widget, 1805 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1793 kcontrol, SND_SOC_DAPM_PRE_REG); 1806 ret = widget->event(widget,
1794 if (ret < 0) 1807 kcontrol, SND_SOC_DAPM_PRE_REG);
1795 goto out; 1808 if (ret < 0)
1796 } 1809 goto out;
1797 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1810 }
1798 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1811
1799 ret = widget->event(widget, 1812 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1800 kcontrol, SND_SOC_DAPM_POST_REG); 1813
1801 } else 1814 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1802 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1815 ret = widget->event(widget,
1816 kcontrol, SND_SOC_DAPM_POST_REG);
1803 1817
1804out: 1818out:
1805 mutex_unlock(&widget->codec->mutex); 1819 mutex_unlock(&widget->codec->mutex);
@@ -1808,6 +1822,54 @@ out:
1808EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1822EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1809 1823
1810/** 1824/**
1825 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
1826 * @kcontrol: mixer control
1827 * @ucontrol: control element information
1828 *
1829 * Returns 0 for success.
1830 */
1831int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1832 struct snd_ctl_elem_value *ucontrol)
1833{
1834 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1835
1836 ucontrol->value.enumerated.item[0] = widget->value;
1837
1838 return 0;
1839}
1840EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1841
1842/**
1843 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
1844 * @kcontrol: mixer control
1845 * @ucontrol: control element information
1846 *
1847 * Returns 0 for success.
1848 */
1849int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
1850 struct snd_ctl_elem_value *ucontrol)
1851{
1852 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1853 struct soc_enum *e =
1854 (struct soc_enum *)kcontrol->private_value;
1855 int change;
1856 int ret = 0;
1857
1858 if (ucontrol->value.enumerated.item[0] >= e->max)
1859 return -EINVAL;
1860
1861 mutex_lock(&widget->codec->mutex);
1862
1863 change = widget->value != ucontrol->value.enumerated.item[0];
1864 widget->value = ucontrol->value.enumerated.item[0];
1865 dapm_mux_update_power(widget, kcontrol, change, widget->value, e);
1866
1867 mutex_unlock(&widget->codec->mutex);
1868 return ret;
1869}
1870EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
1871
1872/**
1811 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1873 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1812 * callback 1874 * callback
1813 * @kcontrol: mixer control 1875 * @kcontrol: mixer control
@@ -1865,7 +1927,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1865{ 1927{
1866 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1928 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1867 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1929 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1868 unsigned int val, mux; 1930 unsigned int val, mux, change;
1869 unsigned int mask; 1931 unsigned int mask;
1870 int ret = 0; 1932 int ret = 0;
1871 1933
@@ -1883,20 +1945,21 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1883 1945
1884 mutex_lock(&widget->codec->mutex); 1946 mutex_lock(&widget->codec->mutex);
1885 widget->value = val; 1947 widget->value = val;
1886 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1948 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1887 if (widget->event) { 1949 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1888 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1950
1889 ret = widget->event(widget, 1951 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1890 kcontrol, SND_SOC_DAPM_PRE_REG); 1952 ret = widget->event(widget,
1891 if (ret < 0) 1953 kcontrol, SND_SOC_DAPM_PRE_REG);
1892 goto out; 1954 if (ret < 0)
1893 } 1955 goto out;
1894 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1956 }
1895 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1957
1896 ret = widget->event(widget, 1958 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1897 kcontrol, SND_SOC_DAPM_POST_REG); 1959
1898 } else 1960 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1899 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1961 ret = widget->event(widget,
1962 kcontrol, SND_SOC_DAPM_POST_REG);
1900 1963
1901out: 1964out:
1902 mutex_unlock(&widget->codec->mutex); 1965 mutex_unlock(&widget->codec->mutex);