aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-12-21 05:05:44 -0500
committerMark Brown <broonie@kernel.org>2014-12-22 07:44:59 -0500
commit86d7500326ea71ea72aeaf0da78671eef28be2af (patch)
treeb839a6c58819f2d9d3a278d422112a6caba5fe62
parent768c0564439bce179e3f0f2ffafe8dcab6a08f40 (diff)
ASoC: dapm: Simplify fully route card handling
For legacy reasons the ASoC framework assumes that a CODEC INPUT or OUTPUT widget that is not explicitly connected to a external source or sink is potentially connected to a source or a sink and hence the framework treats the widget itself as source (for INPUT) or sink (for OUTPUT). For this reason a INPUT or OUTPUT widget that is really not connected needs to be explicitly marked as so. Setting the card's fully_routed flag will cause the ASoC core, once that all widgets and routes have been registered, to go through the list of all widgets and mark all INPUT and OUTPUT that are not externally connected as non-connected. This essentially negates the default behaviour of treating INPUT or OUTPUT widgets without external routes as sources or sinks. This patch takes a different approach while getting the same result. Instead of first marking INPUT and OUTPUT widgets as sinks/sources and then later marking them as non-connected, just never mark them as a sink or a source if the fully_routed flag is set on a card. This requires a lot less code and also results in a slightly faster card initialization since there is no need to iterate over all widgets and check whether the INPUT and OUTPUT widgets are connected or not. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--sound/soc/soc-core.c3
-rw-r--r--sound/soc/soc-dapm.c104
3 files changed, 16 insertions, 92 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 89823cfe6f04..ecffeccb5534 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -431,7 +431,6 @@ int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
431 const char *pin); 431 const char *pin);
432int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 432int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
433 const char *pin); 433 const char *pin);
434void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card);
435unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol); 434unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
436 435
437/* Mostly internal - should not normally be used */ 436/* Mostly internal - should not normally be used */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 985052b3fbed..89aa6717f26a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1626,9 +1626,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1626 } 1626 }
1627 } 1627 }
1628 1628
1629 if (card->fully_routed)
1630 snd_soc_dapm_auto_nc_pins(card);
1631
1632 snd_soc_dapm_new_widgets(card); 1629 snd_soc_dapm_new_widgets(card);
1633 1630
1634 ret = snd_card_register(card->snd_card); 1631 ret = snd_card_register(card->snd_card);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b8eba93b5faf..ea496842ee83 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2279,6 +2279,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
2279 2279
2280 switch (w->id) { 2280 switch (w->id) {
2281 case snd_soc_dapm_input: 2281 case snd_soc_dapm_input:
2282 /* On a fully routed card a input is never a source */
2283 if (w->dapm->card->fully_routed)
2284 break;
2282 w->is_source = 1; 2285 w->is_source = 1;
2283 list_for_each_entry(p, &w->sources, list_sink) { 2286 list_for_each_entry(p, &w->sources, list_sink) {
2284 if (p->source->id == snd_soc_dapm_micbias || 2287 if (p->source->id == snd_soc_dapm_micbias ||
@@ -2291,6 +2294,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
2291 } 2294 }
2292 break; 2295 break;
2293 case snd_soc_dapm_output: 2296 case snd_soc_dapm_output:
2297 /* On a fully routed card a output is never a sink */
2298 if (w->dapm->card->fully_routed)
2299 break;
2294 w->is_sink = 1; 2300 w->is_sink = 1;
2295 list_for_each_entry(p, &w->sinks, list_source) { 2301 list_for_each_entry(p, &w->sinks, list_source) {
2296 if (p->sink->id == snd_soc_dapm_spk || 2302 if (p->sink->id == snd_soc_dapm_spk ||
@@ -3085,16 +3091,24 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3085 3091
3086 switch (w->id) { 3092 switch (w->id) {
3087 case snd_soc_dapm_mic: 3093 case snd_soc_dapm_mic:
3088 case snd_soc_dapm_input:
3089 w->is_source = 1; 3094 w->is_source = 1;
3090 w->power_check = dapm_generic_check_power; 3095 w->power_check = dapm_generic_check_power;
3091 break; 3096 break;
3097 case snd_soc_dapm_input:
3098 if (!dapm->card->fully_routed)
3099 w->is_source = 1;
3100 w->power_check = dapm_generic_check_power;
3101 break;
3092 case snd_soc_dapm_spk: 3102 case snd_soc_dapm_spk:
3093 case snd_soc_dapm_hp: 3103 case snd_soc_dapm_hp:
3094 case snd_soc_dapm_output:
3095 w->is_sink = 1; 3104 w->is_sink = 1;
3096 w->power_check = dapm_generic_check_power; 3105 w->power_check = dapm_generic_check_power;
3097 break; 3106 break;
3107 case snd_soc_dapm_output:
3108 if (!dapm->card->fully_routed)
3109 w->is_sink = 1;
3110 w->power_check = dapm_generic_check_power;
3111 break;
3098 case snd_soc_dapm_vmid: 3112 case snd_soc_dapm_vmid:
3099 case snd_soc_dapm_siggen: 3113 case snd_soc_dapm_siggen:
3100 w->is_source = 1; 3114 w->is_source = 1;
@@ -3809,92 +3823,6 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
3809EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 3823EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
3810 3824
3811/** 3825/**
3812 * dapm_is_external_path() - Checks if a path is a external path
3813 * @card: The card the path belongs to
3814 * @path: The path to check
3815 *
3816 * Returns true if the path is either between two different DAPM contexts or
3817 * between two external pins of the same DAPM context. Otherwise returns
3818 * false.
3819 */
3820static bool dapm_is_external_path(struct snd_soc_card *card,
3821 struct snd_soc_dapm_path *path)
3822{
3823 dev_dbg(card->dev,
3824 "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
3825 path->source->name, path->source->id, path->source->dapm,
3826 path->sink->name, path->sink->id, path->sink->dapm);
3827
3828 /* Connection between two different DAPM contexts */
3829 if (path->source->dapm != path->sink->dapm)
3830 return true;
3831
3832 /* Loopback connection from external pin to external pin */
3833 if (path->sink->id == snd_soc_dapm_input) {
3834 switch (path->source->id) {
3835 case snd_soc_dapm_output:
3836 case snd_soc_dapm_micbias:
3837 return true;
3838 default:
3839 break;
3840 }
3841 }
3842
3843 return false;
3844}
3845
3846static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
3847 struct snd_soc_dapm_widget *w)
3848{
3849 struct snd_soc_dapm_path *p;
3850
3851 list_for_each_entry(p, &w->sources, list_sink) {
3852 if (dapm_is_external_path(card, p))
3853 return true;
3854 }
3855
3856 list_for_each_entry(p, &w->sinks, list_source) {
3857 if (dapm_is_external_path(card, p))
3858 return true;
3859 }
3860
3861 return false;
3862}
3863
3864/**
3865 * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins
3866 * @card: The card whose pins should be processed
3867 *
3868 * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card
3869 * which are unused. Pins are used if they are connected externally to a
3870 * component, whether that be to some other device, or a loop-back connection to
3871 * the component itself.
3872 */
3873void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card)
3874{
3875 struct snd_soc_dapm_widget *w;
3876
3877 dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm);
3878
3879 list_for_each_entry(w, &card->widgets, list) {
3880 switch (w->id) {
3881 case snd_soc_dapm_input:
3882 case snd_soc_dapm_output:
3883 dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n",
3884 w->name);
3885 if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
3886 dev_dbg(card->dev,
3887 "... Not in map; disabling\n");
3888 snd_soc_dapm_nc_pin(w->dapm, w->name);
3889 }
3890 break;
3891 default:
3892 break;
3893 }
3894 }
3895}
3896
3897/**
3898 * snd_soc_dapm_free - free dapm resources 3826 * snd_soc_dapm_free - free dapm resources
3899 * @dapm: DAPM context 3827 * @dapm: DAPM context
3900 * 3828 *