* [PATCH v1 0/2] soundwire: qcom: Restore and fix set_channel_map support for SWR master
@ 2026-06-29 14:16 Mohammad Rafi Shaik
2026-06-29 14:16 ` [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs Mohammad Rafi Shaik
2026-06-29 14:16 ` [PATCH v1 2/2] soundwire: qcom: Add set_channel_map support to SWR master DAI Mohammad Rafi Shaik
0 siblings, 2 replies; 5+ messages in thread
From: Mohammad Rafi Shaik @ 2026-06-29 14:16 UTC (permalink / raw)
To: Srinivas Kandagatla, Vinod Koul, Bard Liao, Liam Girdwood,
Mark Brown, Jaroslav Kysela, Takashi Iwai, Mohammad Rafi Shaik
Cc: Pierre-Louis Bossart, linux-sound, linux-arm-msm, linux-kernel
The original support for set_channel_map in the Qualcomm SoundWire master
commit 7796c97df6b1 ("soundwire: qcom: Add set_channel_map api support")
was reverted due to multiple issues reported on sdm845 board, including
kernel crashes and data structure corruption. The root causes included
incorrect port indexing, array size mismatches, and improper handling
of TX/RX channel information. This series reintroduces set_channel_map
support with a corrected and safer implementation, and fixes the sdm845
machine driver to avoid misuse ofthe API.
Add a robust qcom_swrm_set_channel_map() implementation that stores
per-port TX/RX channel masks safely under controller lock. Ensure the
configuration is only applied to valid ports and does not corrupt memory
or overwrite unrelated data. Preserve existing behavior for ports that do
not use set_channel_map, by falling back to the default SoundWire stream
configuration. Fix the sdm845 machine driver to avoid applying SLIMbus
channel maps to SoundWire DAIs by skipping DAIs that own an SDW stream
(identified via .set_stream).
Mohammad Rafi Shaik (2):
ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs
soundwire: qcom: Add set_channel_map support to SWR master DAI
drivers/soundwire/qcom.c | 54 ++++++++++++++++++++++++++++++++++++++++
sound/soc/qcom/sdm845.c | 27 ++++++++++++++------
2 files changed, 74 insertions(+), 7 deletions(-)
base-commit: 3d5670d672ae08b8c534b7beed6f57c8b44e7b43
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs
2026-06-29 14:16 [PATCH v1 0/2] soundwire: qcom: Restore and fix set_channel_map support for SWR master Mohammad Rafi Shaik
@ 2026-06-29 14:16 ` Mohammad Rafi Shaik
2026-06-29 14:29 ` Srinivas Kandagatla
2026-06-29 14:16 ` [PATCH v1 2/2] soundwire: qcom: Add set_channel_map support to SWR master DAI Mohammad Rafi Shaik
1 sibling, 1 reply; 5+ messages in thread
From: Mohammad Rafi Shaik @ 2026-06-29 14:16 UTC (permalink / raw)
To: Srinivas Kandagatla, Vinod Koul, Bard Liao, Liam Girdwood,
Mark Brown, Jaroslav Kysela, Takashi Iwai, Mohammad Rafi Shaik
Cc: Pierre-Louis Bossart, linux-sound, linux-arm-msm, linux-kernel
On sdm845 the SLIM Playback backend lists wcd934x alongside the qcom
SoundWire master and its SWR slave speaker codecs as codec DAIs on the
same link. sdm845_dai_init() was calling set_channel_map with hardcoded
wcd934x SLIM channel numbers for every codec DAI on that link, including
the SoundWire ones, corrupting their channel configuration.
Skip set_channel_map for any DAI that implements .set_stream, as that op
is the distinguishing marker of DAIs that own an SDW stream path — both
the qcom SWR master and SWR slave codecs register it, while wcd934x does
not. This confines the SLIM channel map to wcd934x where it belongs.
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
sound/soc/qcom/sdm845.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 0ce9dff4dc52..509d7a551397 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -294,13 +294,26 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
return 0;
for_each_rtd_codec_dais(rtd, i, codec_dai) {
- rval = snd_soc_dai_set_channel_map(codec_dai,
- ARRAY_SIZE(tx_ch),
- tx_ch,
- ARRAY_SIZE(rx_ch),
- rx_ch);
- if (rval != 0 && rval != -ENOTSUPP)
- return rval;
+ component = codec_dai->component;
+
+ if (!component || !component->dev)
+ continue;
+
+ /*
+ * Only wcd934x (SLIM codec) needs these static channel maps.
+ * DAIs that own an SDW stream — the qcom SWR master and SWR
+ * slave speaker codecs — implement .set_stream; skip them.
+ */
+ if (!codec_dai->driver || !codec_dai->driver->ops ||
+ !codec_dai->driver->ops->set_stream) {
+ rval = snd_soc_dai_set_channel_map(codec_dai,
+ ARRAY_SIZE(tx_ch),
+ tx_ch,
+ ARRAY_SIZE(rx_ch),
+ rx_ch);
+ if (rval != 0 && rval != -ENOTSUPP)
+ return rval;
+ }
snd_soc_dai_set_sysclk(codec_dai, 0,
WCD934X_DEFAULT_MCLK_RATE,
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 2/2] soundwire: qcom: Add set_channel_map support to SWR master DAI
2026-06-29 14:16 [PATCH v1 0/2] soundwire: qcom: Restore and fix set_channel_map support for SWR master Mohammad Rafi Shaik
2026-06-29 14:16 ` [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs Mohammad Rafi Shaik
@ 2026-06-29 14:16 ` Mohammad Rafi Shaik
1 sibling, 0 replies; 5+ messages in thread
From: Mohammad Rafi Shaik @ 2026-06-29 14:16 UTC (permalink / raw)
To: Srinivas Kandagatla, Vinod Koul, Bard Liao, Liam Girdwood,
Mark Brown, Jaroslav Kysela, Takashi Iwai, Mohammad Rafi Shaik
Cc: Pierre-Louis Bossart, linux-sound, linux-arm-msm, linux-kernel,
Yongqin Liu, Jie Gan, Dan Carpenter
Add .set_channel_map support to the SWR master DAI so the ASoC
layer can program per-port channel masks used by port_enable().
Fix several issues in channel map handling: clip programming to
available ports to avoid out-of-bounds access, use 1-based port
indexing, and store TX/RX masks separately. Also track per-direction
validity and select the effective mask based on port role to avoid
incorrect precedence and ensure full-width masks are preserved.
Fall back to the SDW stream-provided channel mask when no mapping is
configured, preserving existing behaviour.
Fixes: 7796c97df6b1 ("soundwire: qcom: Add set_channel_map api support")
Reported-by: Yongqin Liu <yongqin.liu@linaro.org>
Closes: https://lore.kernel.org/all/4ddd6855-3817-4dc4-81c4-d8ddaa039865@oss.qualcomm.com/
Reported-by: Jie Gan <jie.gan@oss.qualcomm.com>
Closes: https://lore.kernel.org/all/CAMSo37U1kJq_gK8jiW9iMbhHXtn=Chr7NawiK4fPUPj4kyqH2w@mail.gmail.com/
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/all/33fe8fe7-719a-405a-9ed2-d9f816ce1d57@sabinyo.mountain/
Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
---
drivers/soundwire/qcom.c | 54 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index 3d8f5a81eff1..e63736e82478 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -160,6 +160,10 @@ struct qcom_swrm_port_config {
u8 word_length;
u8 blk_group_count;
u8 lane_control;
+ u8 tx_ch_mask;
+ u8 rx_ch_mask;
+ bool tx_ch_map_valid;
+ bool rx_ch_map_valid;
};
/*
@@ -1109,12 +1113,28 @@ static int qcom_swrm_port_enable(struct sdw_bus *bus,
{
u32 reg;
struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
+ struct qcom_swrm_port_config *pcfg;
u32 val;
u32 offset = ctrl->reg_layout[SWRM_OFFSET_DP_PORT_CTRL_BANK];
reg = SWRM_DPn_PORT_CTRL_BANK(offset, enable_ch->port_num, bank);
ctrl->reg_read(ctrl, reg, &val);
+ pcfg = &ctrl->pconfig[enable_ch->port_num];
+
+ mutex_lock(&ctrl->port_lock);
+ if (enable_ch->port_num <= ctrl->num_dout_ports) {
+ if (pcfg->rx_ch_map_valid)
+ enable_ch->ch_mask = pcfg->rx_ch_mask;
+ else if (pcfg->tx_ch_map_valid)
+ enable_ch->ch_mask = pcfg->tx_ch_mask;
+ } else {
+ if (pcfg->tx_ch_map_valid)
+ enable_ch->ch_mask = pcfg->tx_ch_mask;
+ else if (pcfg->rx_ch_map_valid)
+ enable_ch->ch_mask = pcfg->rx_ch_mask;
+ }
+ mutex_unlock(&ctrl->port_lock);
if (enable_ch->enable)
val |= (enable_ch->ch_mask << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT);
@@ -1334,6 +1354,39 @@ static void *qcom_swrm_get_sdw_stream(struct snd_soc_dai *dai, int direction)
return ctrl->sruntime[dai->id];
}
+static int qcom_swrm_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, const unsigned int *tx_slot,
+ unsigned int rx_num, const unsigned int *rx_slot)
+{
+ struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
+ unsigned int max_ports = ctrl->nports;
+ unsigned int i;
+
+ if ((tx_num && !tx_slot) || (rx_num && !rx_slot))
+ return -EINVAL;
+
+ mutex_lock(&ctrl->port_lock);
+ for (i = 1; i <= max_ports; i++) {
+ ctrl->pconfig[i].tx_ch_map_valid = false;
+ ctrl->pconfig[i].rx_ch_map_valid = false;
+
+ /* TX setup */
+ if (tx_slot && i < tx_num) {
+ ctrl->pconfig[i].tx_ch_mask = tx_slot[i];
+ ctrl->pconfig[i].tx_ch_map_valid = true;
+ }
+
+ /* RX setup */
+ if (rx_slot && i < rx_num) {
+ ctrl->pconfig[i].rx_ch_mask = rx_slot[i];
+ ctrl->pconfig[i].rx_ch_map_valid = true;
+ }
+ }
+ mutex_unlock(&ctrl->port_lock);
+
+ return 0;
+}
+
static int qcom_swrm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -1370,6 +1423,7 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = {
.shutdown = qcom_swrm_shutdown,
.set_stream = qcom_swrm_set_sdw_stream,
.get_stream = qcom_swrm_get_sdw_stream,
+ .set_channel_map = qcom_swrm_set_channel_map,
};
static const struct snd_soc_component_driver qcom_swrm_dai_component = {
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs
2026-06-29 14:16 ` [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs Mohammad Rafi Shaik
@ 2026-06-29 14:29 ` Srinivas Kandagatla
2026-07-07 4:34 ` Mohammad Rafi Shaik
0 siblings, 1 reply; 5+ messages in thread
From: Srinivas Kandagatla @ 2026-06-29 14:29 UTC (permalink / raw)
To: Mohammad Rafi Shaik, Srinivas Kandagatla, Vinod Koul, Bard Liao,
Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Mohammad Rafi Shaik
Cc: Pierre-Louis Bossart, linux-sound, linux-arm-msm, linux-kernel
On 6/29/26 3:16 PM, Mohammad Rafi Shaik wrote:
> On sdm845 the SLIM Playback backend lists wcd934x alongside the qcom
> SoundWire master and its SWR slave speaker codecs as codec DAIs on the
> same link. sdm845_dai_init() was calling set_channel_map with hardcoded
> wcd934x SLIM channel numbers for every codec DAI on that link, including
> the SoundWire ones, corrupting their channel configuration.
>
> Skip set_channel_map for any DAI that implements .set_stream, as that op
> is the distinguishing marker of DAIs that own an SDW stream path — both
> the qcom SWR master and SWR slave codecs register it, while wcd934x does
> not. This confines the SLIM channel map to wcd934x where it belongs.
>
> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
> ---
> sound/soc/qcom/sdm845.c | 27 ++++++++++++++++++++-------
> 1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
> index 0ce9dff4dc52..509d7a551397 100644
> --- a/sound/soc/qcom/sdm845.c
> +++ b/sound/soc/qcom/sdm845.c
> @@ -294,13 +294,26 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
> return 0;
>
> for_each_rtd_codec_dais(rtd, i, codec_dai) {
> - rval = snd_soc_dai_set_channel_map(codec_dai,
> - ARRAY_SIZE(tx_ch),
> - tx_ch,
> - ARRAY_SIZE(rx_ch),
> - rx_ch);
> - if (rval != 0 && rval != -ENOTSUPP)
> - return rval;
> + component = codec_dai->component;
> +
> + if (!component || !component->dev)
> + continue;
> +
> + /*
> + * Only wcd934x (SLIM codec) needs these static channel maps.
> + * DAIs that own an SDW stream — the qcom SWR master and SWR
> + * slave speaker codecs — implement .set_stream; skip them.
> + */
> + if (!codec_dai->driver || !codec_dai->driver->ops ||
> + !codec_dai->driver->ops->set_stream) {
This is totally a hack.
--srini
> + rval = snd_soc_dai_set_channel_map(codec_dai,
> + ARRAY_SIZE(tx_ch),
> + tx_ch,
> + ARRAY_SIZE(rx_ch),
> + rx_ch);
> + if (rval != 0 && rval != -ENOTSUPP)
> + return rval;
> + }
>
> snd_soc_dai_set_sysclk(codec_dai, 0,
> WCD934X_DEFAULT_MCLK_RATE,
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs
2026-06-29 14:29 ` Srinivas Kandagatla
@ 2026-07-07 4:34 ` Mohammad Rafi Shaik
0 siblings, 0 replies; 5+ messages in thread
From: Mohammad Rafi Shaik @ 2026-07-07 4:34 UTC (permalink / raw)
To: Srinivas Kandagatla, Srinivas Kandagatla, Vinod Koul, Bard Liao,
Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Mohammad Rafi Shaik
Cc: Pierre-Louis Bossart, linux-sound, linux-arm-msm, linux-kernel
On 6/29/2026 7:59 PM, Srinivas Kandagatla wrote:
>
>
> On 6/29/26 3:16 PM, Mohammad Rafi Shaik wrote:
>> On sdm845 the SLIM Playback backend lists wcd934x alongside the qcom
>> SoundWire master and its SWR slave speaker codecs as codec DAIs on the
>> same link. sdm845_dai_init() was calling set_channel_map with hardcoded
>> wcd934x SLIM channel numbers for every codec DAI on that link, including
>> the SoundWire ones, corrupting their channel configuration.
>>
>> Skip set_channel_map for any DAI that implements .set_stream, as that op
>> is the distinguishing marker of DAIs that own an SDW stream path — both
>> the qcom SWR master and SWR slave codecs register it, while wcd934x does
>> not. This confines the SLIM channel map to wcd934x where it belongs.
>>
>> Signed-off-by: Mohammad Rafi Shaik <mohammad.rafi.shaik@oss.qualcomm.com>
>> ---
>> sound/soc/qcom/sdm845.c | 27 ++++++++++++++++++++-------
>> 1 file changed, 20 insertions(+), 7 deletions(-)
>>
>> diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
>> index 0ce9dff4dc52..509d7a551397 100644
>> --- a/sound/soc/qcom/sdm845.c
>> +++ b/sound/soc/qcom/sdm845.c
>> @@ -294,13 +294,26 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
>> return 0;
>>
>> for_each_rtd_codec_dais(rtd, i, codec_dai) {
>> - rval = snd_soc_dai_set_channel_map(codec_dai,
>> - ARRAY_SIZE(tx_ch),
>> - tx_ch,
>> - ARRAY_SIZE(rx_ch),
>> - rx_ch);
>> - if (rval != 0 && rval != -ENOTSUPP)
>> - return rval;
>> + component = codec_dai->component;
>> +
>> + if (!component || !component->dev)
>> + continue;
>> +
>> + /*
>> + * Only wcd934x (SLIM codec) needs these static channel maps.
>> + * DAIs that own an SDW stream — the qcom SWR master and SWR
>> + * slave speaker codecs — implement .set_stream; skip them.
>> + */
>> + if (!codec_dai->driver || !codec_dai->driver->ops ||
>> + !codec_dai->driver->ops->set_stream) {
>
> This is totally a hack.
>
> --srini
ACK,
The intention was to apply the static channel mapping only for the
WCD934x (SLIM codec) DAIs.
The existing machine driver logic uses hardcoded channel maps which are
only applicable to WCD934x, and this path was unintentionally applying
them to the SoundWire master DAIs as well, which is not correct.
I agree that the current approach is not ideal. I'll rework this and
address it properly in the next version.
Thanks & regards,
Rafi
>> + rval = snd_soc_dai_set_channel_map(codec_dai,
>> + ARRAY_SIZE(tx_ch),
>> + tx_ch,
>> + ARRAY_SIZE(rx_ch),
>> + rx_ch);
>> + if (rval != 0 && rval != -ENOTSUPP)
>> + return rval;
>> + }
>>
>> snd_soc_dai_set_sysclk(codec_dai, 0,
>> WCD934X_DEFAULT_MCLK_RATE,
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-07 4:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-29 14:16 [PATCH v1 0/2] soundwire: qcom: Restore and fix set_channel_map support for SWR master Mohammad Rafi Shaik
2026-06-29 14:16 ` [PATCH v1 1/2] ASoC: qcom: sdm845: skip set_channel_map for SDW stream DAIs Mohammad Rafi Shaik
2026-06-29 14:29 ` Srinivas Kandagatla
2026-07-07 4:34 ` Mohammad Rafi Shaik
2026-06-29 14:16 ` [PATCH v1 2/2] soundwire: qcom: Add set_channel_map support to SWR master DAI Mohammad Rafi Shaik
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®