summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/topology.c
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2023-01-27 14:00:25 +0200
committerMark Brown <broonie@kernel.org>2023-01-27 12:14:08 +0000
commit9c04363d222bc94d49d883458b2854334a848b5f (patch)
tree425932b2a1edc2ed429594e8d62f1c3242f4ab1c /sound/soc/sof/topology.c
parent2d271af1af241e64726ada07c6bef6572f1be6a5 (diff)
downloadlinux-stable-9c04363d222bc94d49d883458b2854334a848b5f.tar.gz
linux-stable-9c04363d222bc94d49d883458b2854334a848b5f.tar.bz2
linux-stable-9c04363d222bc94d49d883458b2854334a848b5f.zip
ASoC: SOF: Introduce struct snd_sof_pipeline
Introduce struct snd_sof_pipeline to save the information about pipelines including the pipeline widget, their status wrt how many PCM's are using them and whether they are complete or not. In struct snd_sof_widget, replace pipe_widget with spipe and remove complete. In struct snd_sof_pcm_stream_pipeline_list, replace pipe_widgets with pipelines. Update all users accordingly. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20230127120031.10709-13-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/topology.c')
-rw-r--r--sound/soc/sof/topology.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 51f6fed45ae7..33ca3067262b 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -1402,7 +1402,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
swidget->scomp = scomp;
swidget->widget = w;
swidget->comp_id = sdev->next_comp_id++;
- swidget->complete = 0;
swidget->id = w->id;
swidget->pipeline_id = index;
swidget->private = NULL;
@@ -1553,6 +1552,23 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
}
}
+ /* create and add pipeline for scheduler type widgets */
+ if (w->id == snd_soc_dapm_scheduler) {
+ struct snd_sof_pipeline *spipe;
+
+ spipe = kzalloc(sizeof(*spipe), GFP_KERNEL);
+ if (!spipe) {
+ kfree(swidget->private);
+ kfree(swidget->tuples);
+ kfree(swidget);
+ return -ENOMEM;
+ }
+
+ spipe->pipe_widget = swidget;
+ swidget->spipe = spipe;
+ list_add(&spipe->list, &sdev->pipeline_list);
+ }
+
w->dobj.private = swidget;
list_add(&swidget->list, &sdev->widget_list);
return ret;
@@ -1608,6 +1624,15 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
sof_disconnect_dai_widget(scomp, widget);
break;
+ case snd_soc_dapm_scheduler:
+ {
+ struct snd_sof_pipeline *spipe = swidget->spipe;
+
+ list_del(&spipe->list);
+ kfree(spipe);
+ swidget->spipe = NULL;
+ break;
+ }
default:
break;
}
@@ -2082,18 +2107,19 @@ err:
}
/**
- * sof_set_pipe_widget - Set pipe_widget for a component
+ * sof_set_widget_pipeline - Set pipeline for a component
* @sdev: pointer to struct snd_sof_dev
- * @pipe_widget: pointer to struct snd_sof_widget of type snd_soc_dapm_scheduler
+ * @spipe: pointer to struct snd_sof_pipeline
* @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget
*
* Return: 0 if successful, -EINVAL on error.
* The function checks if @swidget is associated with any volatile controls. If so, setting
* the dynamic_pipeline_widget is disallowed.
*/
-static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *pipe_widget,
- struct snd_sof_widget *swidget)
+static int sof_set_widget_pipeline(struct snd_sof_dev *sdev, struct snd_sof_pipeline *spipe,
+ struct snd_sof_widget *swidget)
{
+ struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
struct snd_sof_control *scontrol;
if (pipe_widget->dynamic_pipeline_widget) {
@@ -2108,8 +2134,8 @@ static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *
}
}
- /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */
- swidget->pipe_widget = pipe_widget;
+ /* set the pipeline and apply the dynamic_pipeline_widget_flag */
+ swidget->spipe = spipe;
swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget;
return 0;
@@ -2123,6 +2149,7 @@ static int sof_complete(struct snd_soc_component *scomp)
struct snd_sof_widget *swidget, *comp_swidget;
const struct sof_ipc_tplg_widget_ops *widget_ops;
struct snd_sof_control *scontrol;
+ struct snd_sof_pipeline *spipe;
int ret;
widget_ops = tplg_ops ? tplg_ops->widget : NULL;
@@ -2155,23 +2182,21 @@ static int sof_complete(struct snd_soc_component *scomp)
}
/* set the pipe_widget and apply the dynamic_pipeline_widget_flag */
- list_for_each_entry(swidget, &sdev->widget_list, list) {
- switch (swidget->id) {
- case snd_soc_dapm_scheduler:
- /*
- * Apply the dynamic_pipeline_widget flag and set the pipe_widget field
- * for all widgets that have the same pipeline ID as the scheduler widget
- */
- list_for_each_entry(comp_swidget, &sdev->widget_list, list)
- if (comp_swidget->pipeline_id == swidget->pipeline_id) {
- ret = sof_set_pipe_widget(sdev, swidget, comp_swidget);
- if (ret < 0)
- return ret;
- }
- break;
- default:
- break;
- }
+ list_for_each_entry(spipe, &sdev->pipeline_list, list) {
+ struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
+
+ /*
+ * Apply the dynamic_pipeline_widget flag and set the pipe_widget field
+ * for all widgets that have the same pipeline ID as the scheduler widget.
+ * Skip the scheduler widgets as they have their pipeline set during widget_ready
+ */
+ list_for_each_entry(comp_swidget, &sdev->widget_list, list)
+ if (comp_swidget->widget->id != snd_soc_dapm_scheduler &&
+ comp_swidget->pipeline_id == pipe_widget->pipeline_id) {
+ ret = sof_set_widget_pipeline(sdev, spipe, comp_swidget);
+ if (ret < 0)
+ return ret;
+ }
}
/* verify topology components loading including dynamic pipelines */