ASoC: codecs:lpass-wsa-macro: Fix vi feedback rate
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Thu, 3 Apr 2025 16:02:08 +0000 (17:02 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Apr 2025 08:45:46 +0000 (10:45 +0200)
commit d7bff1415e85b889dc8908be6aedba8807ae5e37 upstream.

Currently the VI feedback rate is set to fixed 8K, fix this by getting
the correct rate from params_rate.

Without this patch incorrect rate will be set on the VI feedback
recording resulting in rate miss match and audio artifacts.

Fixes: 2c4066e5d428 ("ASoC: codecs: lpass-wsa-macro: add dapm widgets and route")
Cc: stable@vger.kernel.org
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-2-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
sound/soc/codecs/lpass-wsa-macro.c

index 6ce309980cd10e200dc62a1941b07f6f7728d3cd..ec9f0b5d6778aa853525e778e265c30965eb93ef 100644 (file)
 #define CDC_WSA_TX_SPKR_PROT_CLK_DISABLE       0
 #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK     GENMASK(3, 0)
 #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K       0
+#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_16K      1
+#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_24K      2
+#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_32K      3
+#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_48K      4
 #define CDC_WSA_TX0_SPKR_PROT_PATH_CFG0                (0x0248)
 #define CDC_WSA_TX1_SPKR_PROT_PATH_CTL         (0x0264)
 #define CDC_WSA_TX1_SPKR_PROT_PATH_CFG0                (0x0268)
@@ -347,6 +351,7 @@ struct wsa_macro {
        int ear_spkr_gain;
        int spkr_gain_offset;
        int spkr_mode;
+       u32 pcm_rate_vi;
        int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
        int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
        struct regmap *regmap;
@@ -974,6 +979,7 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
        struct snd_soc_component *component = dai->component;
+       struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (substream->stream) {
@@ -985,6 +991,11 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
                                __func__, params_rate(params));
                        return ret;
                }
+               break;
+       case SNDRV_PCM_STREAM_CAPTURE:
+               if (dai->id == WSA_MACRO_AIF_VI)
+                       wsa->pcm_rate_vi = params_rate(params);
+
                break;
        default:
                break;
@@ -1159,6 +1170,28 @@ 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) {
+       case 8000:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K;
+               break;
+       case 16000:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_16K;
+               break;
+       case 24000:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_24K;
+               break;
+       case 32000:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_32K;
+               break;
+       case 48000:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_48K;
+               break;
+       default:
+               rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K;
+               break;
+       }
 
        if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
                tx_reg0 = CDC_WSA_TX0_SPKR_PROT_PATH_CTL;
@@ -1170,7 +1203,7 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-                       /* Enable V&I sensing */
+               /* 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);
@@ -1179,10 +1212,10 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
                                              CDC_WSA_TX_SPKR_PROT_RESET);
                snd_soc_component_update_bits(component, tx_reg0,
                                              CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
-                                             CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);
+                                             rate_val);
                snd_soc_component_update_bits(component, tx_reg1,
                                              CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
-                                             CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);
+                                             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);