diff options
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index fd2d774797bb..746349faf2db 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -593,6 +593,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
593 | } | 593 | } |
594 | 594 | ||
595 | list_for_each_entry(path, &widget->sinks, list_source) { | 595 | list_for_each_entry(path, &widget->sinks, list_source) { |
596 | if (path->weak) | ||
597 | continue; | ||
598 | |||
596 | if (path->walked) | 599 | if (path->walked) |
597 | continue; | 600 | continue; |
598 | 601 | ||
@@ -643,6 +646,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
643 | } | 646 | } |
644 | 647 | ||
645 | list_for_each_entry(path, &widget->sources, list_sink) { | 648 | list_for_each_entry(path, &widget->sources, list_sink) { |
649 | if (path->weak) | ||
650 | continue; | ||
651 | |||
646 | if (path->walked) | 652 | if (path->walked) |
647 | continue; | 653 | continue; |
648 | 654 | ||
@@ -724,6 +730,9 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) | |||
724 | 730 | ||
725 | /* Check if one of our outputs is connected */ | 731 | /* Check if one of our outputs is connected */ |
726 | list_for_each_entry(path, &w->sinks, list_source) { | 732 | list_for_each_entry(path, &w->sinks, list_source) { |
733 | if (path->weak) | ||
734 | continue; | ||
735 | |||
727 | if (path->connected && | 736 | if (path->connected && |
728 | !path->connected(path->source, path->sink)) | 737 | !path->connected(path->source, path->sink)) |
729 | continue; | 738 | continue; |
@@ -1806,6 +1815,84 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, | |||
1806 | } | 1815 | } |
1807 | EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); | 1816 | EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); |
1808 | 1817 | ||
1818 | static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, | ||
1819 | const struct snd_soc_dapm_route *route) | ||
1820 | { | ||
1821 | struct snd_soc_dapm_widget *source = dapm_find_widget(dapm, | ||
1822 | route->source, | ||
1823 | true); | ||
1824 | struct snd_soc_dapm_widget *sink = dapm_find_widget(dapm, | ||
1825 | route->sink, | ||
1826 | true); | ||
1827 | struct snd_soc_dapm_path *path; | ||
1828 | int count = 0; | ||
1829 | |||
1830 | if (!source) { | ||
1831 | dev_err(dapm->dev, "Unable to find source %s for weak route\n", | ||
1832 | route->source); | ||
1833 | return -ENODEV; | ||
1834 | } | ||
1835 | |||
1836 | if (!sink) { | ||
1837 | dev_err(dapm->dev, "Unable to find sink %s for weak route\n", | ||
1838 | route->sink); | ||
1839 | return -ENODEV; | ||
1840 | } | ||
1841 | |||
1842 | if (route->control || route->connected) | ||
1843 | dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n", | ||
1844 | route->source, route->sink); | ||
1845 | |||
1846 | list_for_each_entry(path, &source->sinks, list_source) { | ||
1847 | if (path->sink == sink) { | ||
1848 | path->weak = 1; | ||
1849 | count++; | ||
1850 | } | ||
1851 | } | ||
1852 | |||
1853 | if (count == 0) | ||
1854 | dev_err(dapm->dev, "No path found for weak route %s->%s\n", | ||
1855 | route->source, route->sink); | ||
1856 | if (count > 1) | ||
1857 | dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n", | ||
1858 | count, route->source, route->sink); | ||
1859 | |||
1860 | return 0; | ||
1861 | } | ||
1862 | |||
1863 | /** | ||
1864 | * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak | ||
1865 | * @dapm: DAPM context | ||
1866 | * @route: audio routes | ||
1867 | * @num: number of routes | ||
1868 | * | ||
1869 | * Mark existing routes matching those specified in the passed array | ||
1870 | * as being weak, meaning that they are ignored for the purpose of | ||
1871 | * power decisions. The main intended use case is for sidetone paths | ||
1872 | * which couple audio between other independent paths if they are both | ||
1873 | * active in order to make the combination work better at the user | ||
1874 | * level but which aren't intended to be "used". | ||
1875 | * | ||
1876 | * Note that CODEC drivers should not use this as sidetone type paths | ||
1877 | * can frequently also be used as bypass paths. | ||
1878 | */ | ||
1879 | int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm, | ||
1880 | const struct snd_soc_dapm_route *route, int num) | ||
1881 | { | ||
1882 | int i, err; | ||
1883 | int ret = 0; | ||
1884 | |||
1885 | for (i = 0; i < num; i++) { | ||
1886 | err = snd_soc_dapm_weak_route(dapm, route); | ||
1887 | if (err) | ||
1888 | ret = err; | ||
1889 | route++; | ||
1890 | } | ||
1891 | |||
1892 | return ret; | ||
1893 | } | ||
1894 | EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes); | ||
1895 | |||
1809 | /** | 1896 | /** |
1810 | * snd_soc_dapm_new_widgets - add new dapm widgets | 1897 | * snd_soc_dapm_new_widgets - add new dapm widgets |
1811 | * @dapm: DAPM context | 1898 | * @dapm: DAPM context |