]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: Intel: sof_sdw: Add a DAI link for loopback capture
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Wed, 4 Feb 2026 08:18:27 +0000 (10:18 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 4 Feb 2026 13:26:04 +0000 (13:26 +0000)
Add a DAI link for loopback capture as the last link to make sure
the other DAI link ID's remain unaffected. It serves as a dummy DAI link
to enable echo reference capture in the SDW topologies which do not have
an actual backend capture DAI.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260204081833.16630-5-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_sdw.c

index 50b838be24e95c3acfd09237a8efe8bfe260d6ec..ee34282828e4278101f25984cc0ac6df8ef7c91d 100644 (file)
@@ -1186,6 +1186,34 @@ static int create_bt_dailinks(struct snd_soc_card *card,
        return 0;
 }
 
+static int create_echoref_dailink(struct snd_soc_card *card,
+                                 struct snd_soc_dai_link **dai_links, int *be_id)
+{
+       struct device *dev = card->dev;
+       int ret;
+       char *name = devm_kasprintf(dev, GFP_KERNEL, "Loopback_Virtual");
+
+       if (!name)
+               return -ENOMEM;
+
+       /*
+        * use dummy DAI names as this won't be connected to an actual DAI but just to establish a
+        * fe <-> be connection for loopback capture for echo reference
+        */
+       ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
+                                           0, 1, "Loopback Virtual Pin", "dummy",
+                                           snd_soc_dummy_dlc.name, snd_soc_dummy_dlc.dai_name,
+                                           1, NULL, NULL);
+       if (ret)
+               return ret;
+
+       (*dai_links)++;
+
+       dev_dbg(dev, "Added echo reference DAI link\n");
+
+       return 0;
+}
+
 static int sof_card_dai_links_create(struct snd_soc_card *card)
 {
        struct device *dev = card->dev;
@@ -1294,8 +1322,12 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
                goto err_end;
        }
 
-       /* allocate BE dailinks */
-       num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
+       /*
+        * allocate BE dailinks, add an extra DAI link for echo reference capture.
+        * This should be the last DAI link and it is expected both for monolithic
+        * and functional SOF topologies to support echo reference.
+        */
+       num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num + 1;
        dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
        if (!dai_links) {
                ret = -ENOMEM;
@@ -1344,6 +1376,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
                        goto err_end;
        }
 
+       /* dummy echo ref link. keep this as the last DAI link. The DAI link ID does not matter */
+       ret = create_echoref_dailink(card, &dai_links, &be_id);
+       if (ret) {
+               dev_err(dev, "failed to create echo ref dai link: %d\n", ret);
+               goto err_end;
+       }
+
        WARN_ON(codec_conf != card->codec_conf + card->num_configs);
        WARN_ON(dai_links != card->dai_link + card->num_links);