[alsa-devel] [PATCH 09/17] ASoC: Intel: Skylake: Add support for virtual dsp widgets

Mark Brown broonie at kernel.org
Fri Oct 30 03:08:38 CET 2015


The patch

   ASoC: Intel: Skylake: Add support for virtual dsp widgets

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 9a3b9dc636b03a01c9f1b7ce699242983a32d579 Mon Sep 17 00:00:00 2001
From: Jeeja KP <jeeja.kp at intel.com>
Date: Tue, 27 Oct 2015 09:22:52 +0900
Subject: [PATCH] ASoC: Intel: Skylake: Add support for virtual dsp widgets

In SKL topology routes, some paths can be connected by a widget
which are not a DSP FW widget and virtual with respect to
firmware. In these case when module has to bind, then the
virtual DSP modules needs to skipped till a actual DSP module is
found which connects the pipelines.

So we need to walk the graph and find a widget which is real in
nature. This patch adds that support and splits
skl_tplg_pga_dapm_pre_pmu_event() fn with parsing code to
skl_tplg_bind_sinks() fn and call that recursively as well as
while parsing

The patch moves code a bit while splitting so diffstat doesn't
tell real picture

Signed-off-by: Jeeja KP <jeeja.kp at intel.com>
Signed-off-by: Vinod Koul <vinod.koul at intel.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 sound/soc/intel/skylake/skl-topology.c | 133 ++++++++++++++++++++-------------
 1 file changed, 83 insertions(+), 50 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index abbf8e7..0c6e783 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -397,40 +397,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-/*
- * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
- * we need to do following:
- *   - Bind to sink pipeline
- *      Since the sink pipes can be running and we don't get mixer event on
- *      connect for already running mixer, we need to find the sink pipes
- *      here and bind to them. This way dynamic connect works.
- *   - Start sink pipeline, if not running
- *   - Then run current pipe
- */
-static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
-							struct skl *skl)
+static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
+				struct skl *skl,
+				struct skl_module_cfg *src_mconfig)
 {
 	struct snd_soc_dapm_path *p;
-	struct snd_soc_dapm_widget *source, *sink;
-	struct skl_module_cfg *src_mconfig, *sink_mconfig;
+	struct snd_soc_dapm_widget *sink = NULL;
+	struct skl_module_cfg *sink_mconfig;
 	struct skl_sst *ctx = skl->skl_sst;
-	int ret = 0;
-
-	source = w;
-	src_mconfig = source->priv;
+	int ret;
 
-	/*
-	 * find which sink it is connected to, bind with the sink,
-	 * if sink is not started, start sink pipe first, then start
-	 * this pipe
-	 */
-	snd_soc_dapm_widget_for_each_source_path(w, p) {
+	snd_soc_dapm_widget_for_each_sink_path(w, p) {
 		if (!p->connect)
 			continue;
 
 		dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
 		dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
 
+		sink = p->sink;
 		/*
 		 * here we will check widgets in sink pipelines, so that
 		 * can be any widgets type and we are only interested if
@@ -440,7 +424,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
 					is_skl_dsp_widget_type(p->sink)) {
 
 			sink = p->sink;
-			src_mconfig = source->priv;
 			sink_mconfig = sink->priv;
 
 			/* Bind source to sink, mixin is always source */
@@ -454,10 +437,43 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
 				if (ret)
 					return ret;
 			}
-			break;
 		}
 	}
 
+	if (!sink)
+		return skl_tplg_bind_sinks(sink, skl, src_mconfig);
+
+	return 0;
+}
+
+/*
+ * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
+ * we need to do following:
+ *   - Bind to sink pipeline
+ *      Since the sink pipes can be running and we don't get mixer event on
+ *      connect for already running mixer, we need to find the sink pipes
+ *      here and bind to them. This way dynamic connect works.
+ *   - Start sink pipeline, if not running
+ *   - Then run current pipe
+ */
+static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
+								struct skl *skl)
+{
+	struct skl_module_cfg *src_mconfig;
+	struct skl_sst *ctx = skl->skl_sst;
+	int ret = 0;
+
+	src_mconfig = w->priv;
+
+	/*
+	 * find which sink it is connected to, bind with the sink,
+	 * if sink is not started, start sink pipe first, then start
+	 * this pipe
+	 */
+	ret = skl_tplg_bind_sinks(w, skl, src_mconfig);
+	if (ret)
+		return ret;
+
 	/* Start source pipe last after starting all sinks */
 	ret = skl_run_pipe(ctx, src_mconfig->pipe);
 	if (ret)
@@ -466,6 +482,38 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
+static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
+		struct snd_soc_dapm_widget *w, struct skl *skl)
+{
+	struct snd_soc_dapm_path *p;
+	struct snd_soc_dapm_widget *src_w = NULL;
+	struct skl_sst *ctx = skl->skl_sst;
+
+	snd_soc_dapm_widget_for_each_source_path(w, p) {
+		src_w = p->source;
+		if (!p->connect)
+			continue;
+
+		dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
+		dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
+
+		/*
+		 * here we will check widgets in sink pipelines, so that can
+		 * be any widgets type and we are only interested if they are
+		 * ones used for SKL so check that first
+		 */
+		if ((p->source->priv != NULL) &&
+					is_skl_dsp_widget_type(p->source)) {
+			return p->source;
+		}
+	}
+
+	if (src_w != NULL)
+		return skl_get_src_dsp_widget(src_w, skl);
+
+	return NULL;
+}
+
 /*
  * in the Post-PMU event of mixer we need to do following:
  *   - Check if this pipe is running
@@ -479,7 +527,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
 							struct skl *skl)
 {
 	int ret = 0;
-	struct snd_soc_dapm_path *p;
 	struct snd_soc_dapm_widget *source, *sink;
 	struct skl_module_cfg *src_mconfig, *sink_mconfig;
 	struct skl_sst *ctx = skl->skl_sst;
@@ -493,32 +540,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
 	 * one more sink before this sink got connected, Since source is
 	 * started, bind this sink to source and start this pipe.
 	 */
-	snd_soc_dapm_widget_for_each_sink_path(w, p) {
-		if (!p->connect)
-			continue;
-
-		dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
-		dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
+	source = skl_get_src_dsp_widget(w, skl);
+	if (source != NULL) {
+		src_mconfig = source->priv;
+		sink_mconfig = sink->priv;
+		src_pipe_started = 1;
 
 		/*
-		 * here we will check widgets in sink pipelines, so that
-		 * can be any widgets type and we are only interested if
-		 * they are ones used for SKL so check that first
+		 * check pipe state, then no need to bind or start the
+		 * pipe
 		 */
-		if ((p->source->priv != NULL) &&
-					is_skl_dsp_widget_type(p->source)) {
-			source = p->source;
-			src_mconfig = source->priv;
-			sink_mconfig = sink->priv;
-			src_pipe_started = 1;
-
-			/*
-			 * check pipe state, then no need to bind or start
-			 * the pipe
-			 */
-			if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
-				src_pipe_started = 0;
-		}
+		if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
+			src_pipe_started = 0;
 	}
 
 	if (src_pipe_started) {
-- 
2.6.1



More information about the Alsa-devel mailing list