* [PATCH] ASoC: codecs: wcd939x: read the SoundWire port switches per channel
@ 2026-10-07 12:39 Joonhoe Kim
2026-10-12 23:03 ` Mark Brown
0 siblings, 1 reply; 2+ messages in thread
From: Joonhoe Kim @ 2026-10-07 12:39 UTC (permalink / raw)
To: srini, broonie, lgirdwood
Cc: perex, tiwai, neil.armstrong, jonathan, linux-sound,
linux-arm-msm, linux-kernel
The "HPHL/HPHR", "ADCn" and "DMICn" switches are channels of shared
SoundWire ports (ADC1-4 are channels 0-3 of the ADC_1_4 port), but
wcd939x_get_swr_port() reports a per-port flag. Once one channel of a
port is switched on, every switch on that port reads back as on:
amixer cset name='ADC1 Switch' on -> ADC1..ADC4 Switch all read "on"
Setting one of the others then looks like a no-op to userspace, and
"alsactl store" saves all of them as on, so a later "alsactl restore"
really enables the unused channels of the port.
Read the channel's own bit in the port's channel mask instead, drop the
now unused port_enable[] and return 0 from the put handler when the
switch does not change, as ALSA expects.
Fixes: 10f514bd172a ("ASoC: codecs: Add WCD939x Codec driver")
Link: https://lore.kernel.org/all/20251124064850.15419-6-jonathan@marek.ca/
Assisted-by: LLM
Signed-off-by: Joonhoe Kim <26rote@gmail.com>
---
Jonathan Marek posted the same read-back change in November 2025 as
part of a wcd938x/wcd939x series [1]; the discussion stayed on the wsa
patches of that series and this one was not picked up. This version also
makes the put handler report "no change", which the original did not.
wcd938x and wcd937x keep the same per-port flag.
Tested on a Lenovo TB323FU (WCD9395, two-mic capture on ADC1/ADC3).
Before: with only ADC1 switched on, ADC1-4 all read back as on, and
after "alsactl store" and "alsactl restore" the TX port's ChannelEn was
0xf during capture. With this patch: ADC1-4 read on/off/on/off and
ChannelEn is 0x5. Writing the same value again no longer sends a change
event.
[1] https://lore.kernel.org/all/20251124064850.15419-1-jonathan@marek.ca/
sound/soc/codecs/wcd939x.c | 10 +++++++---
sound/soc/codecs/wcd939x.h | 1 -
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/wcd939x.c b/sound/soc/codecs/wcd939x.c
index 26fe0b6313cd..2d463f062e6d 100644
--- a/sound/soc/codecs/wcd939x.c
+++ b/sound/soc/codecs/wcd939x.c
@@ -1794,8 +1794,9 @@ static int wcd939x_get_swr_port(struct snd_kcontrol *kcontrol,
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(comp);
struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[mixer->shift];
unsigned int portidx = wcd->ch_info[mixer->reg].port_num;
+ u8 ch_mask = wcd->ch_info[mixer->reg].ch_mask;
- ucontrol->value.integer.value[0] = wcd->port_enable[portidx] ? 1 : 0;
+ ucontrol->value.integer.value[0] = !!(wcd->port_config[portidx - 1].ch_mask & ch_mask);
return 0;
}
@@ -1821,10 +1822,13 @@ static int wcd939x_set_swr_port(struct snd_kcontrol *kcontrol,
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(comp);
struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[mixer->shift];
unsigned int portidx = wcd->ch_info[mixer->reg].port_num;
+ u8 ch_mask = wcd->ch_info[mixer->reg].ch_mask;
+ bool enable = !!ucontrol->value.integer.value[0];
- wcd->port_enable[portidx] = !!ucontrol->value.integer.value[0];
+ if (enable == !!(wcd->port_config[portidx - 1].ch_mask & ch_mask))
+ return 0;
- wcd939x_connect_port(wcd, portidx, mixer->reg, wcd->port_enable[portidx]);
+ wcd939x_connect_port(wcd, portidx, mixer->reg, enable);
return 1;
}
diff --git a/sound/soc/codecs/wcd939x.h b/sound/soc/codecs/wcd939x.h
index 6bd2366587a8..dab7ef108b48 100644
--- a/sound/soc/codecs/wcd939x.h
+++ b/sound/soc/codecs/wcd939x.h
@@ -899,7 +899,6 @@ struct wcd939x_sdw_priv {
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WCD939X_MAX_SWR_PORTS];
const struct wcd_sdw_ch_info *ch_info;
- bool port_enable[WCD939X_MAX_SWR_CH_IDS];
int active_ports;
bool is_tx;
struct wcd939x_priv *wcd939x;
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ASoC: codecs: wcd939x: read the SoundWire port switches per channel
2026-10-07 12:39 [PATCH] ASoC: codecs: wcd939x: read the SoundWire port switches per channel Joonhoe Kim
@ 2026-10-12 23:03 ` Mark Brown
0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2026-10-12 23:03 UTC (permalink / raw)
To: srini, lgirdwood, Joonhoe Kim
Cc: perex, tiwai, neil.armstrong, jonathan, linux-sound,
linux-arm-msm, linux-kernel
On Wed, 07 Oct 2026 21:39:54 +0900, Joonhoe Kim wrote:
> ASoC: codecs: wcd939x: read the SoundWire port switches per channel
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.4
Thanks!
[1/1] ASoC: codecs: wcd939x: read the SoundWire port switches per channel
https://git.kernel.org/broonie/misc/c/e7860dc5d8d4
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] 2+ messages in thread
end of thread, other threads:[~2026-10-13 14:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-07 12:39 [PATCH] ASoC: codecs: wcd939x: read the SoundWire port switches per channel Joonhoe Kim
2026-10-12 23:03 ` Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.