diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:47:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 10:47:46 -0500 |
commit | a421018e8c10e5593a1fee076af72a66c3fe8ca3 (patch) | |
tree | 2854511845d0e07d33726a13eda6de1059a5c9df /sound/soc/soc-dapm.c | |
parent | 3ad1f3b35e8309ec93454dbf89beaafcdb5312da (diff) | |
parent | 86e1d57e4f24ca27ce813bdc2afaac4adafcbaf4 (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.c | 135 |
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 */ |
1208 | static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, | 1218 | static 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) | |||
1401 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); | 1411 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); |
1402 | 1412 | ||
1403 | static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, | 1413 | static 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 | ||
1804 | out: | 1818 | out: |
1805 | mutex_unlock(&widget->codec->mutex); | 1819 | mutex_unlock(&widget->codec->mutex); |
@@ -1808,6 +1822,54 @@ out: | |||
1808 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); | 1822 | EXPORT_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 | */ | ||
1831 | int 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 | } | ||
1840 | EXPORT_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 | */ | ||
1849 | int 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 | } | ||
1870 | EXPORT_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 | ||
1901 | out: | 1964 | out: |
1902 | mutex_unlock(&widget->codec->mutex); | 1965 | mutex_unlock(&widget->codec->mutex); |