ASoC: codecs:lpass-wsa-macro: Fix logic of enabling vi channels

Existing code only configures one of WSA_MACRO_TX0 or WSA_MACRO_TX1
paths eventhough we enable both of them. Fix this bug by adding proper
checks and rearranging some of the common code to able to allow setting
both TX0 and TX1 paths

Without this patch only one channel gets enabled in VI path instead of 2
channels. End result would be 1 channel recording instead of 2.

Fixes: 2c4066e5d428 ("ASoC: codecs: lpass-wsa-macro: add dapm widgets and route")
Cc: stable@vger.kernel.org
Co-developed-by: Manikantan R <quic_manrav@quicinc.com>
Signed-off-by: Manikantan R <quic_manrav@quicinc.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20250403160209.21613-3-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Srinivas Kandagatla 2025-04-03 17:02:09 +01:00 committed by Mark Brown
parent d7bff1415e
commit 7648beb656
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -1459,6 +1459,67 @@ static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
}
}
static void wsa_macro_enable_disable_vi_sense(struct snd_soc_component *component, bool enable,
u32 tx_reg0, u32 tx_reg1, u32 val)
{
if (enable) {
/* Enable V&I sensing */
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
val);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
val);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_NO_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_NO_RESET);
} else {
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
}
}
static void wsa_macro_enable_disable_vi_feedback(struct snd_soc_component *component,
bool enable, u32 rate)
{
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI]))
wsa_macro_enable_disable_vi_sense(component, enable,
CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
CDC_WSA_TX1_SPKR_PROT_PATH_CTL, rate);
if (test_bit(WSA_MACRO_TX1, &wsa->active_ch_mask[WSA_MACRO_AIF_VI]))
wsa_macro_enable_disable_vi_sense(component, enable,
CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
CDC_WSA_TX3_SPKR_PROT_PATH_CTL, rate);
}
static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@ -1475,7 +1536,6 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
u32 tx_reg0, tx_reg1;
u32 rate_val;
switch (wsa->pcm_rate_vi) {
@ -1499,56 +1559,14 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
break;
}
if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
tx_reg0 = CDC_WSA_TX0_SPKR_PROT_PATH_CTL;
tx_reg1 = CDC_WSA_TX1_SPKR_PROT_PATH_CTL;
} else if (test_bit(WSA_MACRO_TX1, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
tx_reg0 = CDC_WSA_TX2_SPKR_PROT_PATH_CTL;
tx_reg1 = CDC_WSA_TX3_SPKR_PROT_PATH_CTL;
}
switch (event) {
case SND_SOC_DAPM_POST_PMU:
/* Enable V&I sensing */
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
rate_val);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
rate_val);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_NO_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_NO_RESET);
wsa_macro_enable_disable_vi_feedback(component, true, rate_val);
break;
case SND_SOC_DAPM_POST_PMD:
/* Disable V&I sensing */
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_RESET_MASK,
CDC_WSA_TX_SPKR_PROT_RESET);
snd_soc_component_update_bits(component, tx_reg0,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
snd_soc_component_update_bits(component, tx_reg1,
CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
wsa_macro_enable_disable_vi_feedback(component, false, rate_val);
break;
}