[PATCH 6.6.y 1/2] ASoC: SOF: topology: Parse DAI type token for dspless mode

From: Artem Dinaburg

Date: Thu Oct 08 2026 - 15:01:29 EST


From: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx>

[ Upstream commit f9618ff105a0f6f5a6beed3edc557ea6a7d26df6 ]

Starting with LunarLake, the dspless mode can handle SoundWire/ALH,
DMIC and SSPs, so we need to identify the dai type from topology.

[ Backport to 6.6.y: 6.6.y still uses a stack-allocated snd_sof_dai in
the dspless topology path; parse the DAI type into that existing object
before connecting it. ]

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx>
Reviewed-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx>
Link: https://msgid.link/r/20240213101247.28887-12-peter.ujfalusi@xxxxxxxxxxxxxxx
Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@xxxxxxxxxxxxxxx>
---
This is patch 1 of 2 in the ordered 6.6.y backport series.
This is the prerequisite needed for the CVE-2025-21870 backport. Stores and
populates each SOF DAI type so the following ALH hardening can distinguish
ALH DAI widgets from same-name non-DAI or non-ALH widgets.
This needed a target-specific adjustment; I called it out in the bracketed
backport note above.

The fix is already present in 6.12.y, 6.18.y, and 7.2.y, but not in 6.6.y.
This fix also affects 6.1.y, which will need a separate backport; this
submission contains only the 6.6.y patch.

sound/soc/sof/ipc4-topology.c | 1 +
sound/soc/sof/sof-audio.h | 1 +
sound/soc/sof/topology.c | 11 +++++++++++
3 files changed, 13 insertions(+)

diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 39e4f0fdd5e4..18096aefce13 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -534,6 +534,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name,
node_type, ipc4_copier->dai_type, ipc4_copier->dai_index);

+ dai->type = ipc4_copier->dai_type;
ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);

pipe_widget = swidget->spipe->pipe_widget;
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 7620596ead07..13b9026ffd4d 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -514,6 +514,7 @@ struct snd_sof_route {
struct snd_sof_dai {
struct snd_soc_component *scomp;
const char *name;
+ u32 type;

int number_configs;
int current_config;
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 7eb8eb35b137..011095722a80 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -2364,7 +2364,10 @@ static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,
struct snd_soc_tplg_dapm_widget *tw)
{
if (WIDGET_IS_DAI(w->id)) {
+ static const struct sof_topology_token dai_tokens[] = {
+ {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 0}};
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_soc_tplg_private *priv = &tw->priv;
struct snd_sof_widget *swidget;
struct snd_sof_dai dai;
int ret;
@@ -2375,6 +2378,14 @@ static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,

memset(&dai, 0, sizeof(dai));

+ ret = sof_parse_tokens(scomp, &dai.type, dai_tokens, ARRAY_SIZE(dai_tokens),
+ priv->array, le32_to_cpu(priv->size));
+ if (ret < 0) {
+ dev_err(scomp->dev, "Failed to parse DAI tokens for %s\n", tw->name);
+ kfree(swidget);
+ return ret;
+ }
+
ret = sof_connect_dai_widget(scomp, w, tw, &dai);
if (ret) {
kfree(swidget);
--
2.39.5