diff mbox

ASoC: dpcm: prevent error for paths including static links

Message ID 1458056089-885-1-git-send-email-piotrs@opensource.wolfsonmicro.com (mailing list archive)
State New, archived
Headers show

Commit Message

Piotr Stankiewicz March 15, 2016, 3:34 p.m. UTC
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(-)

Comments

Mark Brown March 29, 2016, 9:22 p.m. UTC | #1
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.
Charles Keepax March 30, 2016, 8:58 a.m. UTC | #2
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
Mark Brown March 30, 2016, 4:36 p.m. UTC | #3
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?
Charles Keepax March 30, 2016, 5:13 p.m. UTC | #4
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
Mark Brown March 30, 2016, 5:27 p.m. UTC | #5
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?
Charles Keepax March 31, 2016, 8:17 a.m. UTC | #6
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
diff mbox

Patch

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;