From be6e6a0bcb3a40f2661740c8426fce11058150ac Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 3 Dec 2025 17:14:01 +0000 Subject: [PATCH 1/3] soundwire: Add missing EXPORT for sdw_slave_type include/sdw_type.h provides the function is_sdw_slave() which requires sdw_slave_type. But sdw_slave_type it was not exported. Change-Id: I629f9c120d443308b03bbc90cbe71d259bd15bd6 Signed-off-by: Richard Fitzgerald --- drivers/soundwire/slave.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index 3d4d00188c26cc..d933cebad52b43 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -23,6 +23,7 @@ const struct device_type sdw_slave_type = { .release = sdw_slave_release, .uevent = sdw_slave_uevent, }; +EXPORT_SYMBOL_GPL(sdw_slave_type); int sdw_slave_add(struct sdw_bus *bus, struct sdw_slave_id *id, struct fwnode_handle *fwnode) From 023cb37c4a1e5e9a7a21056ed86c40a1d96c4618 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 3 Dec 2025 17:16:25 +0000 Subject: [PATCH 2/3] ASoC: sdw_utils: Call init callbacks on the correct codec DAI asoc_sdw_rtd_init() needs to call the rtd_init() callbacks for each codec in a dailink. It was finding the codecs by looking for the matching DAI name in codec_info_list[] but this is not reliable because the DAI name isn't guaranteed to be unique. Parts using the same codec driver (so the same DAI names) might require different machine driver setup. Instead, get the struct sdw_slave for the dai->component and from that the soundWire part ID can be extracted. This can be used to match against the .part_id value in codec_info_list[]. Change-Id: Ic89712176e1c7289ec00e8c6ef83a6677874d953 Signed-off-by: Richard Fitzgerald --- sound/soc/sdw_utils/soc_sdw_utils.c | 43 ++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index d79e6d1dc06459..1c69b7d623e9d5 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -802,6 +802,19 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr) } EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, "SND_SOC_SDW_UTILS"); +static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_sdw_id(const struct sdw_slave_id *id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) + if (id->part_id == codec_info_list[i].part_id && + (!codec_info_list[i].version_id || + id->sdw_version == codec_info_list[i].version_id)) + return &codec_info_list[i]; + + return NULL; +} + struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id) { int i; @@ -834,21 +847,45 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, i } EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS"); +static int asoc_sdw_find_codec_info_dai_index(const struct asoc_sdw_codec_info *codec_info, + const char *dai_name) +{ + int i; + + for (i = 0; i < codec_info->dai_num; i++) { + if (!strcmp(codec_info->dais[i].dai_name, dai_name)) + return i; + } + + return -ENOENT; +} + int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct asoc_sdw_codec_info *codec_info; struct snd_soc_dai *dai; + struct sdw_slave *sdw_peripheral; const char *spk_components=""; int dai_index; int ret; int i; for_each_rtd_codec_dais(rtd, i, dai) { - codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index); + if (is_sdw_slave(dai->component->dev)) + sdw_peripheral = dev_to_sdw_dev(dai->component->dev); + else if (dai->component->dev->parent && is_sdw_slave(dai->component->dev->parent)) + sdw_peripheral = dev_to_sdw_dev(dai->component->dev->parent); + else + continue; + + codec_info = asoc_sdw_find_codec_info_sdw_id(&sdw_peripheral->id); if (!codec_info) return -EINVAL; + dai_index = asoc_sdw_find_codec_info_dai_index(codec_info, dai->name); + WARN_ON(dai_index < 0); + /* * A codec dai can be connected to different dai links for capture and playback, * but we only need to call the rtd_init function once. @@ -858,6 +895,10 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) if (codec_info->dais[dai_index].rtd_init_done) continue; + dev_dbg(card->dev, "%#x/%s initializing for %s/%s\n", + codec_info->part_id, codec_info->dais[dai_index].dai_name, + dai->component->name, dai->name); + /* * Add card controls and dapm widgets for the first codec dai. * The controls and widgets will be used for all codec dais. From a255a7e99f7ada06d1bb3c62e0df7c69448fb1d4 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Thu, 4 Dec 2025 10:43:55 +0000 Subject: [PATCH 3/3] ASoC: sdw_utils: Remove asoc_sdw_find_codec_info_dai() Remove the asoc_sdw_find_codec_info_dai() function because it isn't reliable and is now unused. It was finding the entry in codec_info_list[] by looking for the matching DAI name. But this is not reliable because the DAI name isn't guaranteed to be unique. Parts using the same codec driver (so the same DAI names) might require different machine driver setup. Change-Id: I178b5e136436b9259242fd5a79e39c011211ca7d Signed-off-by: Richard Fitzgerald --- include/sound/soc_sdw_utils.h | 3 --- sound/soc/sdw_utils/soc_sdw_utils.c | 17 ----------------- 2 files changed, 20 deletions(-) diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h index 76c64c5245d47c..7ce84db8a9e0c4 100644 --- a/include/sound/soc_sdw_utils.h +++ b/include/sound/soc_sdw_utils.h @@ -139,9 +139,6 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr); struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id); -struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, - int *dai_index); - struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card, const char *dai_name); diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index 1c69b7d623e9d5..5e376011133a2b 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -830,23 +830,6 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id) } EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_acpi, "SND_SOC_SDW_UTILS"); -struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, int *dai_index) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - for (j = 0; j < codec_info_list[i].dai_num; j++) { - if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) { - *dai_index = j; - return &codec_info_list[i]; - } - } - } - - return NULL; -} -EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS"); - static int asoc_sdw_find_codec_info_dai_index(const struct asoc_sdw_codec_info *codec_info, const char *dai_name) {