* [PATCH 1/2] ASoC: cs35l56: Add DAI for SDCA OT25 stream
2026-10-05 15:52 [PATCH 0/2] ASoC: cs35l56/57/62/63: Use the correct SoundWire DP for feedback Richard Fitzgerald
@ 2026-10-05 15:52 ` Richard Fitzgerald
2026-10-05 15:52 ` [PATCH 2/2] ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI Richard Fitzgerald
2026-10-05 18:33 ` [PATCH 0/2] ASoC: cs35l56/57/62/63: Use the correct SoundWire DP for feedback Pierre-Louis Bossart
2 siblings, 0 replies; 4+ messages in thread
From: Richard Fitzgerald @ 2026-10-05 15:52 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Add a DAI for the SDCA OT25 stream on SoundWire DP4.
The SDCA-defined OT25 stream is an amp reference feedback, typically used
for AEC. The firmware outputs this on DP4. The firmware owns all control
registers for this stream so there are no mixer controls or any other
configuration options.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
include/sound/cs35l56.h | 1 +
sound/soc/codecs/cs35l56-sdw.c | 9 ++++--
sound/soc/codecs/cs35l56.c | 54 ++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
index 45a5df574aa6d..747e10ec1a274 100644
--- a/include/sound/cs35l56.h
+++ b/include/sound/cs35l56.h
@@ -312,6 +312,7 @@ struct snd_ctl_elem_value;
#define CS35L56_SDW1_PLAYBACK_PORT 1
#define CS35L56_SDW1_CAPTURE_PORT 3
+#define CS35L56_OT25_CAPTURE_PORT 4
#define CS35L56_NUM_BULK_SUPPLIES 3
#define CS35L56_NUM_DSP_REGIONS 5
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index 98bb4542b9143..e10f04d677f4d 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -265,11 +265,11 @@ static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)
if (ret == 0)
prop->clk_stop_mode1 = !!clock_stop_1;
- ports = devm_kcalloc(cs35l56->base.dev, 2, sizeof(*ports), GFP_KERNEL);
+ ports = devm_kcalloc(cs35l56->base.dev, 3, sizeof(*ports), GFP_KERNEL);
if (!ports)
return -ENOMEM;
- prop->source_ports = BIT(CS35L56_SDW1_CAPTURE_PORT);
+ prop->source_ports = BIT(CS35L56_SDW1_CAPTURE_PORT) | BIT(CS35L56_OT25_CAPTURE_PORT);
prop->sink_ports = BIT(CS35L56_SDW1_PLAYBACK_PORT);
prop->paging_support = true;
prop->use_domain_irq = true;
@@ -286,6 +286,11 @@ static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)
ports[1].num = CS35L56_SDW1_CAPTURE_PORT;
ports[1].type = SDW_DPN_FULL;
ports[1].ch_prep_timeout = 10;
+
+ /* DP4 - capture */
+ ports[2].num = CS35L56_OT25_CAPTURE_PORT;
+ ports[2].type = SDW_DPN_FULL;
+ ports[2].ch_prep_timeout = 10;
prop->src_dpn_prop = &ports[1];
dev_dbg(&peripheral->dev, "clock stop mode 1 supported: %s\n",
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 74129fcc79dce..dd264c310e1eb 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -32,6 +32,7 @@
#include <sound/cs-amp-lib.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
@@ -324,6 +325,7 @@ static const struct snd_soc_dapm_widget cs35l56_dapm_widgets[] = {
SND_SOC_DAPM_SIGGEN("VDDBMON ADC"),
SND_SOC_DAPM_SIGGEN("VBSTMON ADC"),
SND_SOC_DAPM_SIGGEN("TEMPMON ADC"),
+ SND_SOC_DAPM_SIGGEN("OT25 Reference"),
SND_SOC_DAPM_INPUT("Calibrate"),
};
@@ -388,6 +390,8 @@ static const struct snd_soc_dapm_route cs35l56_audio_map[] = {
{ "SDW1 Capture", NULL, "SDW1 TX2 Source" },
{ "SDW1 Capture", NULL, "SDW1 TX3 Source" },
{ "SDW1 Capture", NULL, "SDW1 TX4 Source" },
+
+ { "OT25", NULL, "OT25 Reference" },
};
static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
@@ -722,6 +726,37 @@ static int cs35l56_sdw_dai_set_stream(struct snd_soc_dai *dai,
return 0;
}
+static int cs35l56_ot25_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
+ struct sdw_stream_config sconfig = { };
+ struct sdw_port_config pconfig = { };
+ int ret;
+
+ dev_dbg(cs35l56->base.dev, "%s: rate %d\n", __func__, params_rate(params));
+
+ if (!cs35l56->base.init_done)
+ return -ENODEV;
+
+ if (!sdw_stream)
+ return -EINVAL;
+
+ snd_sdw_params_to_config(substream, params, &sconfig, &pconfig);
+ pconfig.num = CS35L56_OT25_CAPTURE_PORT;
+
+ ret = sdw_stream_add_slave(cs35l56->sdw_peripheral, &sconfig, &pconfig,
+ 1, sdw_stream);
+ if (ret) {
+ dev_err(dai->dev, "Failed to add OT25 stream: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops cs35l56_sdw_dai_ops = {
.set_tdm_slot = cs35l56_sdw_dai_set_tdm_slot,
.shutdown = cs35l56_sdw_dai_shutdown,
@@ -730,6 +765,13 @@ static const struct snd_soc_dai_ops cs35l56_sdw_dai_ops = {
.set_stream = cs35l56_sdw_dai_set_stream,
};
+static const struct snd_soc_dai_ops cs35l56_ot25_dai_ops = {
+ .shutdown = cs35l56_sdw_dai_shutdown,
+ .hw_params = cs35l56_ot25_dai_hw_params,
+ .hw_free = cs35l56_sdw_dai_hw_free,
+ .set_stream = cs35l56_sdw_dai_set_stream,
+};
+
static struct snd_soc_dai_driver cs35l56_dai[] = {
{
.name = "cs35l56-asp1",
@@ -778,6 +820,18 @@ static struct snd_soc_dai_driver cs35l56_dai[] = {
.symmetric_rate = 1,
.ops = &cs35l56_sdw_dai_ops,
},
+ {
+ .name = "cs35l56-ot25",
+ .id = 3,
+ .capture = {
+ .stream_name = "OT25",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS35L56_RATES,
+ .formats = CS35L56_TX_FORMATS,
+ },
+ .ops = &cs35l56_ot25_dai_ops,
+ },
};
static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 2/2] ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI
2026-10-05 15:52 [PATCH 0/2] ASoC: cs35l56/57/62/63: Use the correct SoundWire DP for feedback Richard Fitzgerald
2026-10-05 15:52 ` [PATCH 1/2] ASoC: cs35l56: Add DAI for SDCA OT25 stream Richard Fitzgerald
@ 2026-10-05 15:52 ` Richard Fitzgerald
2026-10-05 18:33 ` [PATCH 0/2] ASoC: cs35l56/57/62/63: Use the correct SoundWire DP for feedback Pierre-Louis Bossart
2 siblings, 0 replies; 4+ messages in thread
From: Richard Fitzgerald @ 2026-10-05 15:52 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Change the CS35L56/57/62/63 entries in codec_info_list[] to use
the OT25 DAI for amp feedback.
The AMP feedback was incorrectly using a DAI connected to DP3,
but that is reserved for SDCA companion amp. The correct amp
output is DP4, which is the SDCA OT25 feedback output.
Fixes: 898cd43bde307 ("ASoC: intel: sof_sdw: Add support for CS35L63 into machine driver")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 14aee10b40ba7..7a19de75f32b5 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1035,7 +1035,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
},
@@ -1063,7 +1063,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
},
@@ -1091,7 +1091,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
},
@@ -1119,7 +1119,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
},
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread