Skip to content

Commit 31870fc

Browse files
committed
ASoC: SOF: sof-audio: Traverse paths with aggregated DAI widgets
Aggregated DAI widgets exist in topology for representation and are not actually initialized in the firmware. But in preparation for using this as a virtual DAI for loopback capture, make sure that we can traverse the path from an aggregated DAI widget to the host widget. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
1 parent 99c257d commit 31870fc

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

sound/soc/sof/sof-audio.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@
1313
#include "sof-audio.h"
1414
#include "ops.h"
1515

16+
/*
17+
* Check if a DAI widget is an aggregated DAI. Aggregated DAI's have names ending in numbers
18+
* starting with 0. For example: in the case of a SDW speaker with 2 amps, the topology contains
19+
* 2 DAI's names alh-copier.SDW1.Playback.0 and alh-copier-SDW1.Playback.1. In this case, only the
20+
* DAI alh-copier.SDW1.Playback.0 is set up in the firmware. The other DAI,
21+
* alh-copier.SDW1.Playback.1 in topology is for the sake of completeness to show aggregation for
22+
* the speaker amp and does not need any firmware configuration.
23+
*/
24+
static bool is_aggregated_dai(struct snd_sof_widget *swidget)
25+
{
26+
return (WIDGET_IS_DAI(swidget->id) &&
27+
isdigit(swidget->widget->name[strlen(swidget->widget->name) - 1]) &&
28+
swidget->widget->name[strlen(swidget->widget->name) - 1] != '0');
29+
}
30+
1631
static bool is_virtual_widget(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget,
1732
const char *func)
1833
{
@@ -402,8 +417,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
402417
if (is_virtual_widget(sdev, widget, __func__))
403418
return;
404419

405-
/* skip if the widget is in use or if it is already unprepared */
406-
if (!swidget || !swidget->prepared || swidget->use_count > 0)
420+
/* skip if the widget in use or already unprepared or is an aggregated DAI */
421+
if (!swidget || !swidget->prepared || swidget->use_count > 0 ||
422+
is_aggregated_dai(swidget))
407423
goto sink_unprepare;
408424

409425
widget_ops = tplg_ops ? tplg_ops->widget : NULL;
@@ -449,6 +465,10 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
449465
if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared)
450466
goto sink_prepare;
451467

468+
/* skip aggregated DAIs */
469+
if (is_aggregated_dai(swidget))
470+
goto sink_prepare;
471+
452472
/* prepare the source widget */
453473
ret = widget_ops[widget->id].ipc_prepare(swidget, fe_params, platform_params,
454474
pipeline_params, dir);
@@ -493,15 +513,19 @@ static int sof_free_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dap
493513
int dir, struct snd_sof_pcm *spcm)
494514
{
495515
struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list;
516+
struct snd_sof_widget *swidget;
496517
struct snd_soc_dapm_path *p;
497518
int err;
498519
int ret = 0;
499520

500521
if (is_virtual_widget(sdev, widget, __func__))
501522
return 0;
502523

503-
if (widget->dobj.private) {
504-
err = sof_widget_free(sdev, widget->dobj.private);
524+
swidget = widget->dobj.private;
525+
526+
/* no need to free aggregated DAI widgets */
527+
if (swidget && !is_aggregated_dai(swidget)) {
528+
err = sof_widget_free(sdev, swidget);
505529
if (err < 0)
506530
ret = err;
507531
}
@@ -545,7 +569,10 @@ static int sof_set_up_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_d
545569
if (swidget) {
546570
int i;
547571

548-
ret = sof_widget_setup(sdev, widget->dobj.private);
572+
if (is_aggregated_dai(swidget))
573+
goto sink_setup;
574+
575+
ret = sof_widget_setup(sdev, swidget);
549576
if (ret < 0)
550577
return ret;
551578

0 commit comments

Comments
 (0)