mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
ASoC: codecs: lpass-rx-macro: fix mute_stream affecting all paths
The current mute_steam() implementation affects all paths instead of only those in use by the DAI. For example, playing to 2 DAIs simultaneously with mixing, stopping one will mute the other. Rework to use the same logic as hw_params() to mute only the relevant paths. (also, use "rx->main_clk_users[j] > 0" instead of dsm_reg, which is equivalent. I also don't think the clock enable should be in this function, but that's a change for another patch) Signed-off-by: Jonathan Marek <jonathan@marek.ca> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Link: https://patch.msgid.link/20251117051523.16462-9-jonathan@marek.ca Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
committed by
Mark Brown
parent
50c28498e9
commit
bdf96e9135
@@ -1905,52 +1905,48 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rx_macro *rx = snd_soc_component_get_drvdata(component);
|
||||
uint16_t j, reg, mix_reg, dsm_reg;
|
||||
u16 int_mux_cfg0, int_mux_cfg1;
|
||||
u32 port, j, reg, mix_reg, int_mux_cfg0, int_mux_cfg1;
|
||||
u32 mask, val;
|
||||
u8 int_mux_cfg0_val, int_mux_cfg1_val;
|
||||
|
||||
switch (dai->id) {
|
||||
case RX_MACRO_AIF1_PB:
|
||||
case RX_MACRO_AIF2_PB:
|
||||
case RX_MACRO_AIF3_PB:
|
||||
case RX_MACRO_AIF4_PB:
|
||||
for (j = 0; j < INTERP_MAX; j++) {
|
||||
reg = CDC_RX_RXn_RX_PATH_CTL(rx, j);
|
||||
mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(rx, j);
|
||||
dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, j);
|
||||
if (stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return 0;
|
||||
|
||||
if (mute) {
|
||||
snd_soc_component_update_bits(component, reg,
|
||||
CDC_RX_PATH_PGA_MUTE_MASK,
|
||||
CDC_RX_PATH_PGA_MUTE_ENABLE);
|
||||
snd_soc_component_update_bits(component, mix_reg,
|
||||
CDC_RX_PATH_PGA_MUTE_MASK,
|
||||
CDC_RX_PATH_PGA_MUTE_ENABLE);
|
||||
} else {
|
||||
snd_soc_component_update_bits(component, reg,
|
||||
CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
|
||||
snd_soc_component_update_bits(component, mix_reg,
|
||||
CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
|
||||
for (j = 0; j < INTERP_MAX; j++) {
|
||||
reg = CDC_RX_RXn_RX_PATH_CTL(rx, j);
|
||||
mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(rx, j);
|
||||
|
||||
mask = CDC_RX_PATH_PGA_MUTE_MASK;
|
||||
val = 0;
|
||||
if (mute)
|
||||
val |= CDC_RX_PATH_PGA_MUTE_ENABLE;
|
||||
if (rx->main_clk_users[j] > 0) {
|
||||
mask |= CDC_RX_PATH_CLK_EN_MASK;
|
||||
val |= CDC_RX_PATH_CLK_ENABLE;
|
||||
}
|
||||
|
||||
int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
|
||||
int_mux_cfg1 = int_mux_cfg0 + 4;
|
||||
int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
|
||||
int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1);
|
||||
|
||||
for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) {
|
||||
if (((int_mux_cfg0_val & 0x0f) == port + INTn_1_INP_SEL_RX0) ||
|
||||
((int_mux_cfg0_val >> 4) == port + INTn_1_INP_SEL_RX0) ||
|
||||
((int_mux_cfg1_val >> 4) == port + INTn_1_INP_SEL_RX0)) {
|
||||
snd_soc_component_update_bits(component, reg, mask, val);
|
||||
}
|
||||
|
||||
int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
|
||||
int_mux_cfg1 = int_mux_cfg0 + 4;
|
||||
int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
|
||||
int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1);
|
||||
|
||||
if (snd_soc_component_read(component, dsm_reg) & 0x01) {
|
||||
if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0))
|
||||
snd_soc_component_update_bits(component, reg, 0x20, 0x20);
|
||||
if (int_mux_cfg1_val & 0x0F) {
|
||||
snd_soc_component_update_bits(component, reg, 0x20, 0x20);
|
||||
snd_soc_component_update_bits(component, mix_reg, 0x20,
|
||||
0x20);
|
||||
if ((int_mux_cfg1_val & 0x0f) == port + INTn_2_INP_SEL_RX0) {
|
||||
snd_soc_component_update_bits(component, mix_reg, mask, val);
|
||||
/* main clock needs to be enabled for mix to be useful: */
|
||||
if (rx->main_clk_users[j] > 0) {
|
||||
snd_soc_component_update_bits(component, reg,
|
||||
CDC_RX_PATH_CLK_EN_MASK,
|
||||
CDC_RX_PATH_CLK_ENABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user