* [PATCH 0/7] Add support for cs42l45 into the Intel machine driver
@ 2025-11-27 16:34 Charles Keepax
2025-11-27 16:34 ` [PATCH 1/7] ASoC: SDCA: Align mute controls to ALSA expectations Charles Keepax
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
Now that the full class driver is in place we can add support to the
Intel machine driver for Cirrus's new SDCA audio CODEC the cs42l45. This
makes some minor tweaks to the machine driver itself to support SDCA
devices, and then adds the necessary tables etc. to define the device.
Note, this series shouldn't have any dependencies on the other series of
improvements to the class driver that is already on the list. So either
can be merged first.
Thanks,
Charles
Charles Keepax (7):
ASoC: SDCA: Align mute controls to ALSA expectations
ASoC: SDCA: Add terminal type into input/output widget name
ASoC: sdw_utils: Add codec_conf for every DAI
ASoC: sdw_utils: Move codec_name to dai info
ASoC: intel: sof_sdw: Add ability to have auxiliary devices
ASoC: sdw_utils: Add cs42l45 support functions
ASoC: intel: sof_sdw: Add codec_info for cs42l45
include/sound/sdca_function.h | 4 +-
include/sound/soc_sdw_utils.h | 17 ++++-
sound/soc/amd/acp/acp-sdw-legacy-mach.c | 19 +++--
sound/soc/amd/acp/acp-sdw-sof-mach.c | 12 +++-
sound/soc/intel/boards/sof_sdw.c | 21 ++++--
sound/soc/sdca/sdca_asoc.c | 51 ++-----------
sound/soc/sdca/sdca_functions.c | 56 ++++++++++++++-
sound/soc/sdw_utils/Makefile | 1 +
sound/soc/sdw_utils/soc_sdw_cs42l45.c | 80 +++++++++++++++++++++
sound/soc/sdw_utils/soc_sdw_utils.c | 95 +++++++++++++++++++------
10 files changed, 275 insertions(+), 81 deletions(-)
create mode 100644 sound/soc/sdw_utils/soc_sdw_cs42l45.c
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/7] ASoC: SDCA: Align mute controls to ALSA expectations
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
@ 2025-11-27 16:34 ` Charles Keepax
2025-11-27 19:16 ` Mark Brown
2025-11-27 16:34 ` [PATCH 2/7] ASoC: SDCA: Add terminal type into input/output widget name Charles Keepax
` (6 subsequent siblings)
7 siblings, 1 reply; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
Currently mute controls will be called "FU xx Mute Switch" (note
the switch is added programmatically outside the coverage of this
patch) and the accompanying volume control would be called "FU xx
Channel Volume". These names are taken from the SDCA specification,
however, this does not mesh well with the ALSA naming system. ALSA
generally expects enables rather than mutes and expects that mutes
and volumes have matching names.
Update the names and invert the mute controls to make them more
standard "FU XX Channel Switch", this does slightly deviate from
the SDCA specification but it makes the rest of the Linux ecosystem
a lot happier.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/sdca_function.h | 2 +-
sound/soc/sdca/sdca_asoc.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index c97861508a158..2564fad33fd46 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -611,7 +611,7 @@ enum sdca_entity0_controls {
#define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type"
#define SDCA_CTL_MIXER_NAME "Mixer"
#define SDCA_CTL_SELECTOR_NAME "Selector"
-#define SDCA_CTL_MUTE_NAME "Mute"
+#define SDCA_CTL_MUTE_NAME "Channel"
#define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume"
#define SDCA_CTL_AGC_NAME "AGC"
#define SDCA_CTL_BASS_BOOST_NAME "Bass Boost"
diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
index 4e3f193c75eff..0e21ed1091720 100644
--- a/sound/soc/sdca/sdca_asoc.c
+++ b/sound/soc/sdca/sdca_asoc.c
@@ -886,6 +886,9 @@ static int populate_control(struct device *dev,
mc->min = 0;
mc->max = clamp((0x1ull << control->nbits) - 1, 0, type_max(mc->max));
+ if (SDCA_CTL_TYPE(entity->type, control->sel) == SDCA_CTL_TYPE_S(FU, MUTE))
+ mc->invert = true;
+
(*kctl)->name = control_name;
(*kctl)->private_value = (unsigned long)mc;
(*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/7] ASoC: SDCA: Add terminal type into input/output widget name
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 16:34 ` Charles Keepax
2025-11-27 16:34 ` [PATCH 3/7] ASoC: sdw_utils: Add codec_conf for every DAI Charles Keepax
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
There have been some complaints around the UCM files for SDCA
devices that the control system is quite hard to follow. This is
definitely true without the specification handy the naming can be
a little cryptic. However, as most of the information is parsed
from DisCo there are some limits to what the driver can safely do
to improve this.
However, one area that can be improved is the non-streaming
input/output terminals. These have a field (enum sdca_terminal_type)
that describes the usage of that terminal. These types can be
appended to the entity name to give the users a better clue as
to the purpose. For example "OT 43", would now become "OT 43
Headphone". This would follow through into the jack controls which
would change from "OT 43 Jack" to "OT 43 Headphone Jack", making the
purpose much more obvious to the user.
This provides slightly more readable controls without relying on
implicit knowledge that individual parts might not conform to.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
include/sound/sdca_function.h | 2 ++
sound/soc/sdca/sdca_asoc.c | 48 ++--------------------------
sound/soc/sdca/sdca_functions.c | 56 ++++++++++++++++++++++++++++++++-
3 files changed, 59 insertions(+), 47 deletions(-)
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index 2564fad33fd46..6e9391b3816c6 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -1456,6 +1456,8 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
struct sdca_function_desc *desc,
struct sdca_function_data *function);
+const char *sdca_find_terminal_name(enum sdca_terminal_type type);
+
struct sdca_control *sdca_selector_find_control(struct device *dev,
struct sdca_entity *entity,
const int sel);
diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
index 0e21ed1091720..2d328bbb95b94 100644
--- a/sound/soc/sdca/sdca_asoc.c
+++ b/sound/soc/sdca/sdca_asoc.c
@@ -115,50 +115,6 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
}
EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA");
-static const char *get_terminal_name(enum sdca_terminal_type type)
-{
- switch (type) {
- case SDCA_TERM_TYPE_LINEIN_STEREO:
- return SDCA_TERM_TYPE_LINEIN_STEREO_NAME;
- case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
- return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME;
- case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
- return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME;
- case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
- return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME;
- case SDCA_TERM_TYPE_LINEIN_REAR_LR:
- return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME;
- case SDCA_TERM_TYPE_LINEOUT_STEREO:
- return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME;
- case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
- return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME;
- case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
- return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME;
- case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
- return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME;
- case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
- return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME;
- case SDCA_TERM_TYPE_MIC_JACK:
- return SDCA_TERM_TYPE_MIC_JACK_NAME;
- case SDCA_TERM_TYPE_STEREO_JACK:
- return SDCA_TERM_TYPE_STEREO_JACK_NAME;
- case SDCA_TERM_TYPE_FRONT_LR_JACK:
- return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME;
- case SDCA_TERM_TYPE_CENTER_LFE_JACK:
- return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME;
- case SDCA_TERM_TYPE_SURROUND_LR_JACK:
- return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME;
- case SDCA_TERM_TYPE_REAR_LR_JACK:
- return SDCA_TERM_TYPE_REAR_LR_JACK_NAME;
- case SDCA_TERM_TYPE_HEADPHONE_JACK:
- return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME;
- case SDCA_TERM_TYPE_HEADSET_JACK:
- return SDCA_TERM_TYPE_HEADSET_JACK_NAME;
- default:
- return NULL;
- }
-}
-
static int entity_early_parse_ge(struct device *dev,
struct sdca_function_data *function,
struct sdca_entity *entity)
@@ -217,7 +173,7 @@ static int entity_early_parse_ge(struct device *dev,
type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i);
values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i);
- texts[i + 3] = get_terminal_name(type);
+ texts[i + 3] = sdca_find_terminal_name(type);
if (!texts[i + 3]) {
dev_err(dev, "%s: unrecognised terminal type: %#x\n",
entity->label, type);
@@ -499,7 +455,7 @@ static int entity_parse_su_device(struct device *dev,
return -EINVAL;
}
- add_route(route, entity->label, get_terminal_name(term),
+ add_route(route, entity->label, sdca_find_terminal_name(term),
entity->sources[affected->val - 1]->label);
}
}
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index e4b3efeb30f0b..5a1f120487ef0 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/property.h>
#include <linux/soundwire/sdw.h>
+#include <linux/string.h>
#include <linux/types.h>
#include <sound/sdca.h>
#include <sound/sdca_function.h>
@@ -1120,6 +1121,14 @@ static int find_sdca_entity_iot(struct device *dev,
terminal->type = tmp;
terminal->is_dataport = find_sdca_iot_dataport(terminal);
+ if (!terminal->is_dataport) {
+ const char *type_name = sdca_find_terminal_name(terminal->type);
+
+ if (type_name)
+ entity->label = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
+ entity->label, type_name);
+ }
+
ret = fwnode_property_read_u32(entity_node,
"mipi-sdca-terminal-reference-number", &tmp);
if (!ret)
@@ -1565,7 +1574,7 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data *
for (i = 0; i < function->num_entities; i++) {
struct sdca_entity *entity = &function->entities[i];
- if (!strcmp(entity->label, entity_label))
+ if (!strncmp(entity->label, entity_label, strlen(entity_label)))
return entity;
}
@@ -2156,6 +2165,51 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
}
EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA");
+const char *sdca_find_terminal_name(enum sdca_terminal_type type)
+{
+ switch (type) {
+ case SDCA_TERM_TYPE_LINEIN_STEREO:
+ return SDCA_TERM_TYPE_LINEIN_STEREO_NAME;
+ case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
+ return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME;
+ case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
+ return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME;
+ case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
+ return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME;
+ case SDCA_TERM_TYPE_LINEIN_REAR_LR:
+ return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME;
+ case SDCA_TERM_TYPE_LINEOUT_STEREO:
+ return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME;
+ case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
+ return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME;
+ case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
+ return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME;
+ case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
+ return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME;
+ case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
+ return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME;
+ case SDCA_TERM_TYPE_MIC_JACK:
+ return SDCA_TERM_TYPE_MIC_JACK_NAME;
+ case SDCA_TERM_TYPE_STEREO_JACK:
+ return SDCA_TERM_TYPE_STEREO_JACK_NAME;
+ case SDCA_TERM_TYPE_FRONT_LR_JACK:
+ return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME;
+ case SDCA_TERM_TYPE_CENTER_LFE_JACK:
+ return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME;
+ case SDCA_TERM_TYPE_SURROUND_LR_JACK:
+ return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME;
+ case SDCA_TERM_TYPE_REAR_LR_JACK:
+ return SDCA_TERM_TYPE_REAR_LR_JACK_NAME;
+ case SDCA_TERM_TYPE_HEADPHONE_JACK:
+ return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME;
+ case SDCA_TERM_TYPE_HEADSET_JACK:
+ return SDCA_TERM_TYPE_HEADSET_JACK_NAME;
+ default:
+ return NULL;
+ }
+}
+EXPORT_SYMBOL_NS(sdca_find_terminal_name, "SND_SOC_SDCA");
+
struct sdca_control *sdca_selector_find_control(struct device *dev,
struct sdca_entity *entity,
const int sel)
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/7] ASoC: sdw_utils: Add codec_conf for every DAI
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 16:34 ` [PATCH 2/7] ASoC: SDCA: Add terminal type into input/output widget name Charles Keepax
@ 2025-11-27 16:34 ` Charles Keepax
2025-11-27 16:34 ` [PATCH 4/7] ASoC: sdw_utils: Move codec_name to dai info Charles Keepax
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
The assumption so far is that all the DAI links for a given audio part
would be on the same device. However, as SDCA implements each audio
function on a separate auxiliary driver this will no longer be true.
This means it is necessary to add additional codec_conf structures to
get the prefix for an audio part to apply to all the auxiliary drivers
that make up that part.
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
sound/soc/amd/acp/acp-sdw-legacy-mach.c | 9 ++++++---
sound/soc/intel/boards/sof_sdw.c | 9 ++++++---
sound/soc/sdw_utils/soc_sdw_utils.c | 19 ++++++++++---------
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
index 54f823f7cecff..f1f43eeb60378 100644
--- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
@@ -364,6 +364,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
struct snd_soc_dai_link *dai_links;
int num_devs = 0;
int num_ends = 0;
+ int num_confs;
int num_links;
int be_id = 0;
int ret;
@@ -374,6 +375,8 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
return ret;
}
+ num_confs = num_ends;
+
/* One per DAI link, worst case is a DAI link for every endpoint */
soc_dais = kcalloc(num_ends, sizeof(*soc_dais), GFP_KERNEL);
if (!soc_dais)
@@ -384,7 +387,7 @@ 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_devs);
+ ret = asoc_sdw_parse_sdw_endpoints(card, soc_dais, soc_ends, &num_confs);
if (ret < 0)
return ret;
@@ -396,7 +399,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
- codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
+ codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf)
return -ENOMEM;
@@ -407,7 +410,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
return -ENOMEM;
card->codec_conf = codec_conf;
- card->num_configs = num_devs;
+ card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 6c86a79e8c242..0c6677d66ec73 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -1191,6 +1191,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
struct asoc_sdw_dailink *sof_dais;
int num_devs = 0;
int num_ends = 0;
+ int num_confs;
struct snd_soc_dai_link *dai_links;
int num_links;
int be_id = 0;
@@ -1204,6 +1205,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
return ret;
}
+ num_confs = num_ends;
+
/*
* One per DAI link, worst case is a DAI link for every endpoint, also
* add one additional to act as a terminator such that code can iterate
@@ -1220,7 +1223,7 @@ 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_devs);
+ ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_confs);
if (ret < 0)
goto err_end;
@@ -1268,7 +1271,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
sdw_be_num, ssp_num, dmic_num,
intel_ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
- codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
+ codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf) {
ret = -ENOMEM;
goto err_end;
@@ -1283,7 +1286,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
}
card->codec_conf = codec_conf;
- card->num_configs = num_devs;
+ card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 824fb613c4869..f2f1954adf221 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1442,15 +1442,6 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
- codec_name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, i);
- if (!codec_name)
- return -ENOMEM;
-
- dev_dbg(dev, "Adding prefix %s for %s\n",
- adr_dev->name_prefix, codec_name);
-
- soc_end->name_prefix = adr_dev->name_prefix;
-
if (codec_info->count_sidecar && codec_info->add_sidecar) {
ret = codec_info->count_sidecar(card, &num_dais, num_devs);
if (ret)
@@ -1538,6 +1529,16 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
num_link_dailinks += !!list_empty(&soc_dai->endpoints);
list_add_tail(&soc_end->list, &soc_dai->endpoints);
+ codec_name = asoc_sdw_get_codec_name(dev, codec_info,
+ adr_link, i);
+ if (!codec_name)
+ return -ENOMEM;
+
+ dev_dbg(dev, "Adding prefix %s for %s\n",
+ adr_dev->name_prefix, codec_name);
+
+ soc_end->name_prefix = adr_dev->name_prefix;
+
soc_end->link_mask = adr_link->mask;
soc_end->codec_name = codec_name;
soc_end->codec_info = codec_info;
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/7] ASoC: sdw_utils: Move codec_name to dai info
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
` (2 preceding siblings ...)
2025-11-27 16:34 ` [PATCH 3/7] ASoC: sdw_utils: Add codec_conf for every DAI Charles Keepax
@ 2025-11-27 16:34 ` Charles Keepax
2025-11-27 16:34 ` [PATCH 5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices Charles Keepax
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
As SDCA devices will support each DAI link on a different child device,
move the codec name from codec_info to each dai_info. To allow the
appropriate function device to be bound to each DAI link.
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 | 4 ++--
sound/soc/sdw_utils/soc_sdw_utils.c | 19 ++++++++++---------
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 76c64c5245d47..714e207d4c013 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -45,6 +45,7 @@ struct asoc_sdw_codec_info;
struct asoc_sdw_dai_info {
const bool direction[2]; /* playback & capture support */
+ const char *codec_name;
const char *dai_name;
const char *component_name;
const int dai_type;
@@ -67,7 +68,6 @@ struct asoc_sdw_dai_info {
struct asoc_sdw_codec_info {
const int part_id;
const int version_id;
- const char *codec_name;
const char *name_prefix;
int amp_num;
const u8 acpi_id[ACPI_ID_LEN];
@@ -131,7 +131,7 @@ int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
const char *asoc_sdw_get_codec_name(struct device *dev,
- const struct asoc_sdw_codec_info *codec_info,
+ const struct asoc_sdw_dai_info *dai_info,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index);
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index f2f1954adf221..f31213e00a16a 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -656,12 +656,12 @@ struct asoc_sdw_codec_info codec_info_list[] = {
{
.part_id = 0x4243,
.name_prefix = "cs42l43",
- .codec_name = "cs42l43-codec",
.count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
.add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
.dais = {
{
.direction = {true, false},
+ .codec_name = "cs42l43-codec",
.dai_name = "cs42l43-dp5",
.dai_type = SOC_SDW_DAI_TYPE_JACK,
.dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
@@ -673,6 +673,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
+ .codec_name = "cs42l43-codec",
.dai_name = "cs42l43-dp1",
.dai_type = SOC_SDW_DAI_TYPE_MIC,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
@@ -684,12 +685,14 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
+ .codec_name = "cs42l43-codec",
.dai_name = "cs42l43-dp2",
.dai_type = SOC_SDW_DAI_TYPE_JACK,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
},
{
.direction = {true, false},
+ .codec_name = "cs42l43-codec",
.dai_name = "cs42l43-dp6",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
@@ -1094,7 +1097,6 @@ static bool asoc_sdw_is_unique_device(const struct snd_soc_acpi_link_adr *adr_li
}
static const char *_asoc_sdw_get_codec_name(struct device *dev,
- const struct asoc_sdw_codec_info *codec_info,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index)
{
@@ -1116,14 +1118,14 @@ static const char *_asoc_sdw_get_codec_name(struct device *dev,
}
const char *asoc_sdw_get_codec_name(struct device *dev,
- const struct asoc_sdw_codec_info *codec_info,
+ const struct asoc_sdw_dai_info *dai_info,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index)
{
- if (codec_info->codec_name)
- return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL);
+ if (dai_info->codec_name)
+ return devm_kstrdup(dev, dai_info->codec_name, GFP_KERNEL);
- return _asoc_sdw_get_codec_name(dev, codec_info, adr_link, adr_index);
+ return _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
}
EXPORT_SYMBOL_NS(asoc_sdw_get_codec_name, "SND_SOC_SDW_UTILS");
@@ -1354,8 +1356,7 @@ static int is_sdca_endpoint_present(struct device *dev,
}
kfree(dlc);
- sdw_codec_name = _asoc_sdw_get_codec_name(dev, codec_info,
- adr_link, adr_index);
+ sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
if (!sdw_codec_name)
return -ENOMEM;
@@ -1529,7 +1530,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
num_link_dailinks += !!list_empty(&soc_dai->endpoints);
list_add_tail(&soc_end->list, &soc_dai->endpoints);
- codec_name = asoc_sdw_get_codec_name(dev, codec_info,
+ codec_name = asoc_sdw_get_codec_name(dev, dai_info,
adr_link, i);
if (!codec_name)
return -ENOMEM;
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
` (3 preceding siblings ...)
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
2025-11-27 16:34 ` [PATCH 6/7] ASoC: sdw_utils: Add cs42l45 support functions Charles Keepax
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/7] ASoC: sdw_utils: Add cs42l45 support functions
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
` (4 preceding siblings ...)
2025-11-27 16:34 ` [PATCH 5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices Charles Keepax
@ 2025-11-27 16:34 ` 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
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
Add the helper functions into the machine driver for the cs42l45,
this will register a jack for jack detection and add things into
to the components string if they are needed.
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 | 2 +
sound/soc/sdw_utils/Makefile | 1 +
sound/soc/sdw_utils/soc_sdw_cs42l45.c | 80 +++++++++++++++++++++++++++
3 files changed, 83 insertions(+)
create mode 100644 sound/soc/sdw_utils/soc_sdw_cs42l45.c
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 48719fde308c0..227347c8f0b33 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -257,6 +257,8 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da
int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
/* TI */
diff --git a/sound/soc/sdw_utils/Makefile b/sound/soc/sdw_utils/Makefile
index a87c53e1a2c18..e8bd5ffb1a6ad 100644
--- a/sound/soc/sdw_utils/Makefile
+++ b/sound/soc/sdw_utils/Makefile
@@ -5,6 +5,7 @@ snd-soc-sdw-utils-y := soc_sdw_utils.o soc_sdw_dmic.o soc_sdw_rt_dmic.o \
soc_sdw_rt_amp.o soc_sdw_rt_mf_sdca.o \
soc_sdw_bridge_cs35l56.o \
soc_sdw_cs42l42.o soc_sdw_cs42l43.o \
+ soc_sdw_cs42l45.o \
soc_sdw_cs_amp.o \
soc_sdw_maxim.o \
soc_sdw_ti_amp.o
diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l45.c b/sound/soc/sdw_utils/soc_sdw_cs42l45.c
new file mode 100644
index 0000000000000..647923d9669fd
--- /dev/null
+++ b/sound/soc/sdw_utils/soc_sdw_cs42l45.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Based on sof_sdw_rt5682.c
+// This file incorporates work covered by the following copyright notice:
+// Copyright (c) 2023 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
+
+/*
+ * soc_sdw_cs42l45 - Helpers to handle CS42L45 from generic machine driver
+ */
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-card.h>
+#include <sound/soc-component.h>
+#include <sound/soc-dai.h>
+#include <sound/soc_sdw_utils.h>
+
+static struct snd_soc_jack_pin soc_jack_pins[] = {
+ {
+ .pin = "cs42l45 OT 43 Headphone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "cs42l45 OT 45 Headset",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "cs42l45 IT 31 Microphone",
+ .mask = SND_JACK_MICROPHONE,
+ },
+ {
+ .pin = "cs42l45 IT 33 Headset",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
+int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_jack *jack = &ctx->sdw_headset;
+ int ret;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l45",
+ card->components);
+ if (!card->components)
+ return -ENOMEM;
+
+ ret = snd_soc_card_jack_new_pins(card, "Jack", SND_JACK_MECHANICAL |
+ SND_JACK_HEADSET | SND_JACK_LINEOUT, jack,
+ soc_jack_pins, ARRAY_SIZE(soc_jack_pins));
+ if (ret) {
+ dev_err(card->dev, "Failed to create jack: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_component_set_jack(component, jack, NULL);
+ if (ret) {
+ dev_err(card->dev, "Failed to register jack: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l45_hs_rtd_init, "SND_SOC_SDW_UTILS");
+
+int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+{
+ struct snd_soc_card *card = rtd->card;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l45-dmic",
+ card->components);
+ if (!card->components)
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l45_dmic_rtd_init, "SND_SOC_SDW_UTILS");
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/7] ASoC: intel: sof_sdw: Add codec_info for cs42l45
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
` (5 preceding siblings ...)
2025-11-27 16:34 ` [PATCH 6/7] ASoC: sdw_utils: Add cs42l45 support functions Charles Keepax
@ 2025-11-27 16:34 ` Charles Keepax
2025-11-28 18:01 ` [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Mark Brown
7 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-27 16:34 UTC (permalink / raw)
To: broonie
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
Add support for the Cirrus Logic CS42L45 standalone using SoundWire.
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 36 +++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index f57e02bea5b4e..6c656b2f7f3ae 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -707,6 +707,42 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
.dai_num = 4,
},
+ {
+ .part_id = 0x4245,
+ .name_prefix = "cs42l45",
+ .dais = {
+ {
+ .direction = {true, false},
+ .codec_name = "snd_soc_sdca.UAJ.1",
+ .dai_name = "IT 41",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l45_hs_rtd_init,
+ },
+ {
+ .direction = {false, true},
+ .codec_name = "snd_soc_sdca.SmartMic.0",
+ .dai_name = "OT 113",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l45_dmic_rtd_init,
+ },
+ {
+ .direction = {false, true},
+ .codec_name = "snd_soc_sdca.UAJ.1",
+ .dai_name = "OT 36",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ },
+ .dai_num = 3,
+ .auxs = {
+ {
+ .codec_name = "snd_soc_sdca.HID.2",
+ },
+ },
+ .aux_num = 1,
+ },
{
.part_id = 0xaaaa, /* generic codec mockup */
.name_prefix = "sdw_mockup_mmulti-function",
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/7] ASoC: SDCA: Align mute controls to ALSA expectations
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
0 siblings, 1 reply; 11+ messages in thread
From: Mark Brown @ 2025-11-27 19:16 UTC (permalink / raw)
To: Charles Keepax
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
[-- Attachment #1: Type: text/plain, Size: 1847 bytes --]
On Thu, Nov 27, 2025 at 04:34:20PM +0000, Charles Keepax wrote:
> Update the names and invert the mute controls to make them more
> standard "FU XX Channel Switch", this does slightly deviate from
> the SDCA specification but it makes the rest of the Linux ecosystem
> a lot happier.
And there was me thinking you were going to address the FU bit. :)
>
> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
> ---
> include/sound/sdca_function.h | 2 +-
> sound/soc/sdca/sdca_asoc.c | 3 +++
> 2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
> index c97861508a158..2564fad33fd46 100644
> --- a/include/sound/sdca_function.h
> +++ b/include/sound/sdca_function.h
> @@ -611,7 +611,7 @@ enum sdca_entity0_controls {
> #define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type"
> #define SDCA_CTL_MIXER_NAME "Mixer"
> #define SDCA_CTL_SELECTOR_NAME "Selector"
> -#define SDCA_CTL_MUTE_NAME "Mute"
> +#define SDCA_CTL_MUTE_NAME "Channel"
> #define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume"
> #define SDCA_CTL_AGC_NAME "AGC"
> #define SDCA_CTL_BASS_BOOST_NAME "Bass Boost"
> diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
> index 4e3f193c75eff..0e21ed1091720 100644
> --- a/sound/soc/sdca/sdca_asoc.c
> +++ b/sound/soc/sdca/sdca_asoc.c
> @@ -886,6 +886,9 @@ static int populate_control(struct device *dev,
> mc->min = 0;
> mc->max = clamp((0x1ull << control->nbits) - 1, 0, type_max(mc->max));
>
> + if (SDCA_CTL_TYPE(entity->type, control->sel) == SDCA_CTL_TYPE_S(FU, MUTE))
> + mc->invert = true;
> +
> (*kctl)->name = control_name;
> (*kctl)->private_value = (unsigned long)mc;
> (*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
> --
> 2.47.3
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/7] ASoC: SDCA: Align mute controls to ALSA expectations
2025-11-27 19:16 ` Mark Brown
@ 2025-11-28 9:23 ` Charles Keepax
0 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2025-11-28 9:23 UTC (permalink / raw)
To: Mark Brown
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
On Thu, Nov 27, 2025 at 07:16:36PM +0000, Mark Brown wrote:
> On Thu, Nov 27, 2025 at 04:34:20PM +0000, Charles Keepax wrote:
>
> > Update the names and invert the mute controls to make them more
> > standard "FU XX Channel Switch", this does slightly deviate from
> > the SDCA specification but it makes the rest of the Linux ecosystem
> > a lot happier.
>
> And there was me thinking you were going to address the FU bit. :)
Lol, yes it's a spectacular choice isn't it, I mean it just
screams Functional Unit.
Thanks,
Charles
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/7] Add support for cs42l45 into the Intel machine driver
2025-11-27 16:34 [PATCH 0/7] Add support for cs42l45 into the Intel machine driver Charles Keepax
` (6 preceding siblings ...)
2025-11-27 16:34 ` [PATCH 7/7] ASoC: intel: sof_sdw: Add codec_info for cs42l45 Charles Keepax
@ 2025-11-28 18:01 ` Mark Brown
7 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2025-11-28 18:01 UTC (permalink / raw)
To: Charles Keepax
Cc: yung-chuan.liao, pierre-louis.bossart, lgirdwood, peter.ujfalusi,
linux-sound, patches
On Thu, 27 Nov 2025 16:34:19 +0000, Charles Keepax wrote:
> Now that the full class driver is in place we can add support to the
> Intel machine driver for Cirrus's new SDCA audio CODEC the cs42l45. This
> makes some minor tweaks to the machine driver itself to support SDCA
> devices, and then adds the necessary tables etc. to define the device.
>
> Note, this series shouldn't have any dependencies on the other series of
> improvements to the class driver that is already on the list. So either
> can be merged first.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/7] ASoC: SDCA: Align mute controls to ALSA expectations
commit: 5fee9edf791a50182382fae23f30690c93e16cec
[2/7] ASoC: SDCA: Add terminal type into input/output widget name
commit: 48fa77af2f4a55ab961520f2a0e50560dc0baca8
[3/7] ASoC: sdw_utils: Add codec_conf for every DAI
commit: 26ee34d2f5c7fba968fcc2f1fd94110e1c1660db
[4/7] ASoC: sdw_utils: Move codec_name to dai info
commit: 2ae4659533d8e2b5e06e8f570e2b4b7b88ae0716
[5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices
commit: c66297d09e1a5813eb743bae8cda4e115b8a5c56
[6/7] ASoC: sdw_utils: Add cs42l45 support functions
commit: 3f6b562f2107ab2467908fa1543e1a6ea8442bd1
[7/7] ASoC: intel: sof_sdw: Add codec_info for cs42l45
commit: 1e645bca9d1e4c5970778114d2d9fc247fe12e7b
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-28 18:01 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 5/7] ASoC: intel: sof_sdw: Add ability to have auxiliary devices Charles Keepax
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox