From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: broonie@kernel.org
Cc: yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
lgirdwood@gmail.com, peter.ujfalusi@linux.intel.com,
linux-sound@vger.kernel.org, patches@opensource.cirrus.com
Subject: [PATCH 5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices
Date: Thu, 27 Nov 2025 16:34:24 +0000 [thread overview]
Message-ID: <20251127163426.2500633-6-ckeepax@opensource.cirrus.com> (raw)
In-Reply-To: <20251127163426.2500633-1-ckeepax@opensource.cirrus.com>
Currently the sof_sdw machine driver assumes that all devices involved
in the sound card are connected through a DAI link. However for SDCA
devices we still want the HID (Human Interface Device, used for jack
buttons) to be part of the sound card, but it contains no DAI links.
Add support into the machine driver to specify a list of auxiliary
devices to merged into the card.
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/soc_sdw_utils.h | 11 ++++++++++-
sound/soc/amd/acp/acp-sdw-legacy-mach.c | 12 ++++++++++--
sound/soc/amd/acp/acp-sdw-sof-mach.c | 12 ++++++++++--
sound/soc/intel/boards/sof_sdw.c | 14 ++++++++++++--
sound/soc/sdw_utils/soc_sdw_utils.c | 23 ++++++++++++++++++++---
5 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 714e207d4c013..48719fde308c0 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -13,6 +13,7 @@
#include <sound/soc-acpi.h>
#define SOC_SDW_MAX_DAI_NUM 8
+#define SOC_SDW_MAX_AUX_NUM 2
#define SOC_SDW_MAX_NO_PROPS 2
#define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
@@ -65,6 +66,10 @@ struct asoc_sdw_dai_info {
bool quirk_exclude;
};
+struct asoc_sdw_aux_info {
+ const char *codec_name;
+};
+
struct asoc_sdw_codec_info {
const int part_id;
const int version_id;
@@ -75,6 +80,8 @@ struct asoc_sdw_codec_info {
const struct snd_soc_ops *ops;
struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
const int dai_num;
+ struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
+ const int aux_num;
int (*codec_card_late_probe)(struct snd_soc_card *card);
@@ -165,13 +172,15 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd),
const struct snd_soc_ops *ops);
-int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);
+int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
+ int *num_devs, int *num_ends, int *num_aux);
struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
const struct snd_soc_acpi_endpoint *new);
int asoc_sdw_get_dai_type(u32 type);
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
+ struct snd_soc_aux_dev *soc_aux,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
int *num_devs);
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
index f1f43eeb60378..fae94b9edd5a3 100644
--- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
@@ -360,16 +360,18 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
struct asoc_sdw_endpoint *soc_ends __free(kfree) = NULL;
struct asoc_sdw_dailink *soc_dais __free(kfree) = NULL;
+ struct snd_soc_aux_dev *soc_aux;
struct snd_soc_codec_conf *codec_conf;
struct snd_soc_dai_link *dai_links;
int num_devs = 0;
int num_ends = 0;
+ int num_aux = 0;
int num_confs;
int num_links;
int be_id = 0;
int ret;
- ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
+ ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
if (ret < 0) {
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
return ret;
@@ -387,7 +389,11 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
if (!soc_ends)
return -ENOMEM;
- ret = asoc_sdw_parse_sdw_endpoints(card, soc_dais, soc_ends, &num_confs);
+ soc_aux = devm_kcalloc(dev, num_aux, sizeof(*soc_aux), GFP_KERNEL);
+ if (!soc_aux)
+ return -ENOMEM;
+
+ ret = asoc_sdw_parse_sdw_endpoints(card, soc_aux, soc_dais, soc_ends, &num_confs);
if (ret < 0)
return ret;
@@ -413,6 +419,8 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
+ card->aux_dev = soc_aux;
+ card->num_aux_devs = num_aux;
/* SDW */
if (sdw_be_num) {
diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c
index d055582a3bf1a..5677ae63fca92 100644
--- a/sound/soc/amd/acp/acp-sdw-sof-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c
@@ -272,15 +272,17 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
struct asoc_sdw_endpoint *sof_ends __free(kfree) = NULL;
struct asoc_sdw_dailink *sof_dais __free(kfree) = NULL;
+ struct snd_soc_aux_dev *sof_aux;
struct snd_soc_codec_conf *codec_conf;
struct snd_soc_dai_link *dai_links;
int num_devs = 0;
int num_ends = 0;
+ int num_aux = 0;
int num_links;
int be_id = 0;
int ret;
- ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
+ ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
if (ret < 0) {
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
return ret;
@@ -296,7 +298,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
if (!sof_ends)
return -ENOMEM;
- ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
+ sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL);
+ if (!sof_aux)
+ return -ENOMEM;
+
+ ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_devs);
if (ret < 0)
return ret;
@@ -322,6 +328,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
card->num_configs = num_devs;
card->dai_link = dai_links;
card->num_links = num_links;
+ card->aux_dev = sof_aux;
+ card->num_aux_devs = num_aux;
/* SDW */
if (sdw_be_num) {
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 0c6677d66ec73..2c1001148d540 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -1189,8 +1189,10 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
struct asoc_sdw_codec_info *ssp_info;
struct asoc_sdw_endpoint *sof_ends;
struct asoc_sdw_dailink *sof_dais;
+ struct snd_soc_aux_dev *sof_aux;
int num_devs = 0;
int num_ends = 0;
+ int num_aux = 0;
int num_confs;
struct snd_soc_dai_link *dai_links;
int num_links;
@@ -1199,7 +1201,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
unsigned long ssp_mask;
int ret;
- ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
+ ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
if (ret < 0) {
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
return ret;
@@ -1223,7 +1225,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
goto err_dai;
}
- ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_confs);
+ sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL);
+ if (!sof_aux) {
+ ret = -ENOMEM;
+ goto err_dai;
+ }
+
+ ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_confs);
if (ret < 0)
goto err_end;
@@ -1289,6 +1297,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
+ card->aux_dev = sof_aux;
+ card->num_aux_devs = num_aux;
/* SDW */
if (sdw_be_num) {
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index f31213e00a16a..f57e02bea5b4e 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1252,7 +1252,8 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
}
EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, "SND_SOC_SDW_UTILS");
-int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends)
+int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
+ int *num_devs, int *num_ends, int *num_aux)
{
struct device *dev = card->dev;
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
@@ -1263,8 +1264,18 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *
for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
*num_devs += adr_link->num_adr;
- for (i = 0; i < adr_link->num_adr; i++)
- *num_ends += adr_link->adr_d[i].num_endpoints;
+ for (i = 0; i < adr_link->num_adr; i++) {
+ const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
+ struct asoc_sdw_codec_info *codec_info;
+
+ *num_ends += adr_dev->num_endpoints;
+
+ codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ *num_aux += codec_info->aux_num;
+ }
}
dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends);
@@ -1402,6 +1413,7 @@ static int is_sdca_endpoint_present(struct device *dev,
}
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
+ struct snd_soc_aux_dev *soc_aux,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
int *num_devs)
@@ -1441,6 +1453,11 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
if (!codec_info)
return -EINVAL;
+ for (j = 0; j < codec_info->aux_num; j++) {
+ soc_aux->dlc.name = codec_info->auxs[j].codec_name;
+ soc_aux++;
+ }
+
ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
if (codec_info->count_sidecar && codec_info->add_sidecar) {
--
2.47.3
next prev parent reply other threads:[~2025-11-27 16:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
2025-11-27 16:34 ` [PATCH 1/7] ASoC: SDCA: Align mute controls to ALSA expectations Charles Keepax
2025-11-27 19:16 ` Mark Brown
2025-11-28 9:23 ` Charles Keepax
2025-11-27 16:34 ` [PATCH 2/7] ASoC: SDCA: Add terminal type into input/output widget name Charles Keepax
2025-11-27 16:34 ` [PATCH 3/7] ASoC: sdw_utils: Add codec_conf for every DAI Charles Keepax
2025-11-27 16:34 ` [PATCH 4/7] ASoC: sdw_utils: Move codec_name to dai info Charles Keepax
2025-11-27 16:34 ` Charles Keepax [this message]
2025-11-27 16:34 ` [PATCH 6/7] ASoC: sdw_utils: Add cs42l45 support functions Charles Keepax
2025-11-27 16:34 ` [PATCH 7/7] ASoC: intel: sof_sdw: Add codec_info for cs42l45 Charles Keepax
2025-11-28 18:01 ` [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Mark Brown
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=20251127163426.2500633-6-ckeepax@opensource.cirrus.com \
--to=ckeepax@opensource.cirrus.com \
--cc=broonie@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-sound@vger.kernel.org \
--cc=patches@opensource.cirrus.com \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.dev \
--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