mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Matthew Schwartz <matthew.schwartz@linux.dev>
To: broonie@kernel.org
Cc: Matthew Schwartz <matthew.schwartz@linux.dev>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	Vijendar Mukunda <Vijendar.Mukunda@amd.com>,
	Venkata Prasad Potturu <venkataprasad.potturu@amd.com>,
	Cezary Rojewski <cezary.rojewski@intel.com>,
	Peter Ujfalusi <peter.ujfalusi@linux.intel.com>,
	Bard Liao <yung-chuan.liao@linux.intel.com>,
	Kai Vehmanen <kai.vehmanen@linux.intel.com>,
	Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 4/5] ASoC: sdw_utils: honor empty DisCo port lists when creating DAI links
Date: Fri, 16 Oct 2026 16:24:14 -0700	[thread overview]
Message-ID: <20261016232416.2628603-5-matthew.schwartz@linux.dev> (raw)
In-Reply-To: <20261016232416.2628603-1-matthew.schwartz@linux.dev>

The codec_info tables give each DAI a fixed direction, so a TAS2783
always gets an amp feedback capture link. The ASUS ROG Xbox Ally X20
BIOS declares mipi-sdw-source-port-list as 0 for both of its TAS2783s,
so the capture port has no DisCo properties and every open of the
SmartAmp capture PCM fails in sdw_program_slave_port_params() with
-EINVAL. The PCM is probed at session start, which logs a burst of
transport errors on every boot, and the same failure is reported on the
ASUS ProArt PX13.

Store the effective direction in each endpoint and drop a direction
when the peripheral declares an empty port list for it. A missing port
list keeps the table direction, so platforms that do not describe their
ports are unaffected.

Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
 include/sound/soc_sdw_utils.h           |  1 +
 sound/soc/amd/acp/acp-sdw-legacy-mach.c |  2 +-
 sound/soc/amd/acp/acp-sdw-sof-mach.c    |  2 +-
 sound/soc/intel/boards/sof_sdw.c        |  2 +-
 sound/soc/sdw_utils/soc_sdw_utils.c     | 36 ++++++++++++++++++++++---
 5 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 418466438ea1c..8e247a457a7c6 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -114,6 +114,7 @@ struct asoc_sdw_endpoint {
 	const char *codec_name;
 	const char *name_prefix;
 	bool include_sidecar;
+	bool direction[2]; /* dai_info direction limited by the DisCo port lists */
 
 	struct asoc_sdw_codec_info *codec_info;
 	const struct asoc_sdw_dai_info *dai_info;
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
index a8b62817b2344..d485cee42542c 100644
--- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
@@ -262,7 +262,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
 			return -ENOMEM;
 
 		list_for_each_entry(soc_end, &soc_dai->endpoints, list) {
-			if (!soc_end->dai_info->direction[stream])
+			if (!soc_end->direction[stream])
 				continue;
 
 			/*
diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c
index ec3e1f5f1052c..87e495e601bcd 100644
--- a/sound/soc/amd/acp/acp-sdw-sof-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c
@@ -177,7 +177,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
 			return -ENOMEM;
 
 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
-			if (!sof_end->dai_info->direction[stream])
+			if (!sof_end->direction[stream])
 				continue;
 
 			int link_num = ffs(sof_end->link_mask) - 1;
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 72fe013fffe86..42c6c262cc80e 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -973,7 +973,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
 			return -ENOMEM;
 
 		list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
-			if (!sof_end->dai_info->direction[stream])
+			if (!sof_end->direction[stream])
 				continue;
 
 			if (cur_link != sof_end->link_mask) {
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 7a19de75f32b5..126ff1b2dc450 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -2407,6 +2407,32 @@ static int is_sdca_endpoint_present(struct device *dev,
 	return 0;
 }
 
+/* A DisCo port list that is present but empty means the stream cannot run */
+static bool asoc_sdw_has_ports(struct device *dev,
+			       const struct snd_soc_acpi_link_adr *adr_link,
+			       int adr_index, int stream)
+{
+	const char *prop = stream == SNDRV_PCM_STREAM_PLAYBACK ?
+			   "mipi-sdw-sink-port-list" : "mipi-sdw-source-port-list";
+	const char *sdw_codec_name;
+	struct device *sdw_dev;
+	u32 ports;
+	int ret;
+
+	sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
+	if (!sdw_codec_name)
+		return true;
+
+	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_codec_name);
+	if (!sdw_dev)
+		return true;
+
+	ret = device_property_read_u32(sdw_dev, prop, &ports);
+	put_device(sdw_dev);
+
+	return ret || ports;
+}
+
 int asoc_sdw_parse_sdw_endpoints(struct device *dev,
 				 struct asoc_sdw_mc_private *ctx,
 				 struct snd_soc_aux_dev *soc_aux,
@@ -2529,12 +2555,16 @@ int asoc_sdw_parse_sdw_endpoints(struct device *dev,
 					}
 				}
 
+				for_each_pcm_streams(stream)
+					soc_end->direction[stream] = dai_info->direction[stream] &&
+						asoc_sdw_has_ports(dev, adr_link, i, stream);
+
 				dev_dbg(dev,
 					"Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n",
 					ffs(adr_link->mask) - 1, adr_dev->adr,
 					adr_end->num, dai_info->dai_type,
-					dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
-					dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
+					soc_end->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
+					soc_end->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
 					adr_end->aggregated ? "group" : "solo",
 					adr_end->group_id);
 
@@ -2555,7 +2585,7 @@ int asoc_sdw_parse_sdw_endpoints(struct device *dev,
 						return -EINVAL;
 					}
 
-					if (dai_info->direction[stream]) {
+					if (soc_end->direction[stream]) {
 						num_dais += !soc_dai->num_devs[stream];
 						soc_dai->num_devs[stream]++;
 						soc_dai->link_mask[stream] |= adr_link->mask;
-- 
2.56.0


  parent reply	other threads:[~2026-10-16 23:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 23:24 [PATCH 0/5] ASoC: support the ASUS ROG Xbox Ally X20 audio Matthew Schwartz
2026-10-16 23:24 ` [PATCH 1/5] ASoC: amd: acp-config: force SoundWire probe on ASUS RC74XA Matthew Schwartz
2026-10-16 23:24 ` [PATCH 2/5] ASoC: amd: acp: add ACP70 SoundWire machine entry for " Matthew Schwartz
2026-10-16 23:24 ` [PATCH 3/5] ASoC: tas2783-sdw: use the BIOS speaker ID in the firmware name Matthew Schwartz
2026-10-16 23:24 ` Matthew Schwartz [this message]
2026-10-16 23:24 ` [PATCH 5/5] ASoC: rt721-sdca: wait for PDEs to reach PS0 after powering them up Matthew Schwartz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261016232416.2628603-5-matthew.schwartz@linux.dev \
    --to=matthew.schwartz@linux.dev \
    --cc=Vijendar.Mukunda@amd.com \
    --cc=broonie@kernel.org \
    --cc=cezary.rojewski@intel.com \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=peter.ujfalusi@linux.intel.com \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=tiwai@suse.com \
    --cc=venkataprasad.potturu@amd.com \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®