[alsa-devel] [PATCH] ASoC: dpcm: prevent error for paths including static links
According to the DPCM documentation using static codec <-> codec links along dynamic ones is a valid use case, however this causes errors of the following form to be printed to the kernel log:
ASoC: can't get [playback|caputure] BE for <widget name> ASoC: no BE found for <widget name>
This happens when setting up, e.g. a route starting with a dynamic DAI, which passes through a static DAI (say, "Some FE" -> "Some BE" -> "Codec to Modem link"). All DAPM widgets involved in that path will be passed to dpcm_add_paths in order to establish FE <-> BE connections, which will result in dpcm_get_be trying to locate back-ends for dynamic, as well as static links, causing a spurious error to be logged for the latter.
This patch changes dpcm_get_be to look up a non front-end runtime for a stream widget, and renames it accordingly. Like this both dynamic and static links can be handled properly in dpcm_add_paths, i.e. an actual missing BE can be distinguished from a normal link.
Signed-off-by: Piotr Stankiewicz piotrs@opensource.wolfsonmicro.com --- sound/soc/soc-pcm.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1af4f23..ff5ea7e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1220,47 +1220,47 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) } }
-/* get BE for DAI widget and stream */ -static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, +/* get runtime for DAI widget and stream */ +static struct snd_soc_pcm_runtime *dpcm_get_rtd(struct snd_soc_card *card, struct snd_soc_dapm_widget *widget, int stream) { - struct snd_soc_pcm_runtime *be; + struct snd_soc_pcm_runtime *rtd; int i;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - list_for_each_entry(be, &card->rtd_list, list) { + list_for_each_entry(rtd, &card->rtd_list, list) {
- if (!be->dai_link->no_pcm) + if (rtd->dai_link->dynamic) continue;
- if (be->cpu_dai->playback_widget == widget) - return be; + if (rtd->cpu_dai->playback_widget == widget) + return rtd;
- for (i = 0; i < be->num_codecs; i++) { - struct snd_soc_dai *dai = be->codec_dais[i]; + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *dai = rtd->codec_dais[i]; if (dai->playback_widget == widget) - return be; + return rtd; } } } else {
- list_for_each_entry(be, &card->rtd_list, list) { + list_for_each_entry(rtd, &card->rtd_list, list) {
- if (!be->dai_link->no_pcm) + if (rtd->dai_link->dynamic) continue;
- if (be->cpu_dai->capture_widget == widget) - return be; + if (rtd->cpu_dai->capture_widget == widget) + return rtd;
- for (i = 0; i < be->num_codecs; i++) { - struct snd_soc_dai *dai = be->codec_dais[i]; + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *dai = rtd->codec_dais[i]; if (dai->capture_widget == widget) - return be; + return rtd; } } }
- dev_err(card->dev, "ASoC: can't get %s BE for %s\n", + dev_err(card->dev, "ASoC: can't get %s runtime for %s\n", stream ? "capture" : "playback", widget->name); return NULL; } @@ -1367,15 +1367,15 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, continue; }
- /* is there a valid BE rtd for this widget */ - be = dpcm_get_be(card, list->widgets[i], stream); + /* is there a valid rtd for this widget */ + be = dpcm_get_rtd(card, list->widgets[i], stream); if (!be) { - dev_err(fe->dev, "ASoC: no BE found for %s\n", + dev_err(fe->dev, "ASoC: no runtime found for %s\n", list->widgets[i]->name); continue; }
- /* make sure BE is a real BE */ + /* check if the runtime is a BE */ if (!be->dai_link->no_pcm) continue;
On Tue, Mar 15, 2016 at 03:34:49PM +0000, Piotr Stankiewicz wrote:
This happens when setting up, e.g. a route starting with a dynamic DAI, which passes through a static DAI (say, "Some FE" -> "Some BE" -> "Codec to Modem link"). All DAPM widgets involved in that path will
Is this not just a normal CODEC connected to a back end on a DPCM system? What are a "dynamic DAI" and "static DAI"? Your changelog is very unclear, I really can't tell from your changelog what this is aiming to do or how it proposes to do it.
I'm also concerned that nobody else seems to be seeing this, that's a bit of a warning sign that you might be misusing things here. Your mention of a "Codec to Modem link" sounds like you might be trying to use DPCM for off-SoC components somehow which is just not something that's expected to work.
At a minimum this needs a much better changelog.
On Tue, Mar 29, 2016 at 02:22:24PM -0700, Mark Brown wrote:
On Tue, Mar 15, 2016 at 03:34:49PM +0000, Piotr Stankiewicz wrote:
This happens when setting up, e.g. a route starting with a dynamic DAI, which passes through a static DAI (say, "Some FE" -> "Some BE" -> "Codec to Modem link"). All DAPM widgets involved in that path will
Is this not just a normal CODEC connected to a back end on a DPCM system? What are a "dynamic DAI" and "static DAI"? Your changelog is very unclear, I really can't tell from your changelog what this is aiming to do or how it proposes to do it.
The issue is basically if you have a path with a DPCM DAI at the front, but then a regular CODEC to CODEC DAI link later in the path. Say for example a CODEC attached to a CPU that uses DPCM but then the path goes through a CODEC to CODEC link to a speaker AMP after the CODEC.
I'm also concerned that nobody else seems to be seeing this, that's a bit of a warning sign that you might be misusing things here. Your mention of a "Codec to Modem link" sounds like you might be trying to use DPCM for off-SoC components somehow which is just not something that's expected to work.
At a minimum this needs a much better changelog.
Piotr is on holiday this week but should be back start of next week, so should be able to respin the patch then. For what its worth though I have seen this warning on other systems from the one he is working on as well.
Thanks, Charles
On Wed, Mar 30, 2016 at 09:58:12AM +0100, Charles Keepax wrote:
On Tue, Mar 29, 2016 at 02:22:24PM -0700, Mark Brown wrote:
Is this not just a normal CODEC connected to a back end on a DPCM system? What are a "dynamic DAI" and "static DAI"? Your changelog is very unclear, I really can't tell from your changelog what this is aiming to do or how it proposes to do it.
The issue is basically if you have a path with a DPCM DAI at the front, but then a regular CODEC to CODEC DAI link later in the path. Say for example a CODEC attached to a CPU that uses DPCM but then the path goes through a CODEC to CODEC link to a speaker AMP after the CODEC.
Doesn't this mean that the appropriate fix is to terminate the DPCM routing at the first back end DAI so we're not trying to DPCM outside the SoC?
On Wed, Mar 30, 2016 at 09:36:50AM -0700, Mark Brown wrote:
On Wed, Mar 30, 2016 at 09:58:12AM +0100, Charles Keepax wrote:
On Tue, Mar 29, 2016 at 02:22:24PM -0700, Mark Brown wrote:
Is this not just a normal CODEC connected to a back end on a DPCM system? What are a "dynamic DAI" and "static DAI"? Your changelog is very unclear, I really can't tell from your changelog what this is aiming to do or how it proposes to do it.
The issue is basically if you have a path with a DPCM DAI at the front, but then a regular CODEC to CODEC DAI link later in the path. Say for example a CODEC attached to a CPU that uses DPCM but then the path goes through a CODEC to CODEC link to a speaker AMP after the CODEC.
Doesn't this mean that the appropriate fix is to terminate the DPCM routing at the first back end DAI so we're not trying to DPCM outside the SoC?
I think (not 100% certain) you can have multiple backends connected to a single front end, which makes it hard to know when to stop or even if it is assured that all the backends will be before any other spurious DAIs in the widget list.
Thanks, Charles
On Wed, Mar 30, 2016 at 06:13:14PM +0100, Charles Keepax wrote:
On Wed, Mar 30, 2016 at 09:36:50AM -0700, Mark Brown wrote:
Doesn't this mean that the appropriate fix is to terminate the DPCM routing at the first back end DAI so we're not trying to DPCM outside the SoC?
I think (not 100% certain) you can have multiple backends connected to a single front end, which makes it hard to know when to stop or even if it is assured that all the backends will be before any other spurious DAIs in the widget list.
You can have multiple backends connected but they shouldn't be chained together, they should be connected in parallel. We can tell if we're walking a node that's a backend, why would we walk the graph beyond that?
On Wed, Mar 30, 2016 at 10:27:02AM -0700, Mark Brown wrote:
On Wed, Mar 30, 2016 at 06:13:14PM +0100, Charles Keepax wrote:
On Wed, Mar 30, 2016 at 09:36:50AM -0700, Mark Brown wrote:
Doesn't this mean that the appropriate fix is to terminate the DPCM routing at the first back end DAI so we're not trying to DPCM outside the SoC?
I think (not 100% certain) you can have multiple backends connected to a single front end, which makes it hard to know when to stop or even if it is assured that all the backends will be before any other spurious DAIs in the widget list.
You can have multiple backends connected but they shouldn't be chained together, they should be connected in parallel. We can tell if we're walking a node that's a backend, why would we walk the graph beyond that?
Ah ok apologies, I misunderstood your suggestion. I thought you meant aborting the widget list search in dpcm_add_paths, but you actually mean aborting the graph walk in snd_soc_dapm_dai_get_connnected_widgets. That looks totally like it would work, although it needs a bit of thought as I guess the original intention was for get_connected_widgets to be pretty generic, but it does only have the single user.
I will get Piotr to have a look at respinning the patch, when he returns.
Thanks, Charles
participants (3)
-
Charles Keepax
-
Mark Brown
-
Piotr Stankiewicz