mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ASoC: codecs: wcd939x: read the SoundWire port switches per channel
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: 10f514bd17 ("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>
Link: https://patch.msgid.link/20261007123954.1709-1-26rote@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
4f173a0fee
commit
e7860dc5d8
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user