6363#define CDC_WSA_TX_SPKR_PROT_CLK_DISABLE 0
6464#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK GENMASK(3, 0)
6565#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K 0
66+ #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_16K 1
67+ #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_24K 2
68+ #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_32K 3
69+ #define CDC_WSA_TX_SPKR_PROT_PCM_RATE_48K 4
6670#define CDC_WSA_TX0_SPKR_PROT_PATH_CFG0 (0x0248)
6771#define CDC_WSA_TX1_SPKR_PROT_PATH_CTL (0x0264)
6872#define CDC_WSA_TX1_SPKR_PROT_PATH_CFG0 (0x0268)
@@ -407,6 +411,7 @@ struct wsa_macro {
407411 int ear_spkr_gain ;
408412 int spkr_gain_offset ;
409413 int spkr_mode ;
414+ u32 pcm_rate_vi ;
410415 int is_softclip_on [WSA_MACRO_SOFTCLIP_MAX ];
411416 int softclip_clk_users [WSA_MACRO_SOFTCLIP_MAX ];
412417 struct regmap * regmap ;
@@ -1280,6 +1285,7 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
12801285 struct snd_soc_dai * dai )
12811286{
12821287 struct snd_soc_component * component = dai -> component ;
1288+ struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
12831289 int ret ;
12841290
12851291 switch (substream -> stream ) {
@@ -1291,6 +1297,11 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
12911297 __func__ , params_rate (params ));
12921298 return ret ;
12931299 }
1300+ break ;
1301+ case SNDRV_PCM_STREAM_CAPTURE :
1302+ if (dai -> id == WSA_MACRO_AIF_VI )
1303+ wsa -> pcm_rate_vi = params_rate (params );
1304+
12941305 break ;
12951306 default :
12961307 break ;
@@ -1448,35 +1459,11 @@ static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
14481459 }
14491460}
14501461
1451- static int wsa_macro_mclk_event (struct snd_soc_dapm_widget * w ,
1452- struct snd_kcontrol * kcontrol , int event )
1462+ static void wsa_macro_enable_disable_vi_sense (struct snd_soc_component * component , bool enable ,
1463+ u32 tx_reg0 , u32 tx_reg1 , u32 val )
14531464{
1454- struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
1455- struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
1456-
1457- wsa_macro_mclk_enable (wsa , event == SND_SOC_DAPM_PRE_PMU );
1458- return 0 ;
1459- }
1460-
1461- static int wsa_macro_enable_vi_feedback (struct snd_soc_dapm_widget * w ,
1462- struct snd_kcontrol * kcontrol ,
1463- int event )
1464- {
1465- struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
1466- struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
1467- u32 tx_reg0 , tx_reg1 ;
1468-
1469- if (test_bit (WSA_MACRO_TX0 , & wsa -> active_ch_mask [WSA_MACRO_AIF_VI ])) {
1470- tx_reg0 = CDC_WSA_TX0_SPKR_PROT_PATH_CTL ;
1471- tx_reg1 = CDC_WSA_TX1_SPKR_PROT_PATH_CTL ;
1472- } else if (test_bit (WSA_MACRO_TX1 , & wsa -> active_ch_mask [WSA_MACRO_AIF_VI ])) {
1473- tx_reg0 = CDC_WSA_TX2_SPKR_PROT_PATH_CTL ;
1474- tx_reg1 = CDC_WSA_TX3_SPKR_PROT_PATH_CTL ;
1475- }
1476-
1477- switch (event ) {
1478- case SND_SOC_DAPM_POST_PMU :
1479- /* Enable V&I sensing */
1465+ if (enable ) {
1466+ /* Enable V&I sensing */
14801467 snd_soc_component_update_bits (component , tx_reg0 ,
14811468 CDC_WSA_TX_SPKR_PROT_RESET_MASK ,
14821469 CDC_WSA_TX_SPKR_PROT_RESET );
@@ -1485,10 +1472,10 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
14851472 CDC_WSA_TX_SPKR_PROT_RESET );
14861473 snd_soc_component_update_bits (component , tx_reg0 ,
14871474 CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK ,
1488- CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K );
1475+ val );
14891476 snd_soc_component_update_bits (component , tx_reg1 ,
14901477 CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK ,
1491- CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K );
1478+ val );
14921479 snd_soc_component_update_bits (component , tx_reg0 ,
14931480 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK ,
14941481 CDC_WSA_TX_SPKR_PROT_CLK_ENABLE );
@@ -1501,9 +1488,7 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
15011488 snd_soc_component_update_bits (component , tx_reg1 ,
15021489 CDC_WSA_TX_SPKR_PROT_RESET_MASK ,
15031490 CDC_WSA_TX_SPKR_PROT_NO_RESET );
1504- break ;
1505- case SND_SOC_DAPM_POST_PMD :
1506- /* Disable V&I sensing */
1491+ } else {
15071492 snd_soc_component_update_bits (component , tx_reg0 ,
15081493 CDC_WSA_TX_SPKR_PROT_RESET_MASK ,
15091494 CDC_WSA_TX_SPKR_PROT_RESET );
@@ -1516,6 +1501,72 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
15161501 snd_soc_component_update_bits (component , tx_reg1 ,
15171502 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK ,
15181503 CDC_WSA_TX_SPKR_PROT_CLK_DISABLE );
1504+ }
1505+ }
1506+
1507+ static void wsa_macro_enable_disable_vi_feedback (struct snd_soc_component * component ,
1508+ bool enable , u32 rate )
1509+ {
1510+ struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
1511+
1512+ if (test_bit (WSA_MACRO_TX0 , & wsa -> active_ch_mask [WSA_MACRO_AIF_VI ]))
1513+ wsa_macro_enable_disable_vi_sense (component , enable ,
1514+ CDC_WSA_TX0_SPKR_PROT_PATH_CTL ,
1515+ CDC_WSA_TX1_SPKR_PROT_PATH_CTL , rate );
1516+
1517+ if (test_bit (WSA_MACRO_TX1 , & wsa -> active_ch_mask [WSA_MACRO_AIF_VI ]))
1518+ wsa_macro_enable_disable_vi_sense (component , enable ,
1519+ CDC_WSA_TX2_SPKR_PROT_PATH_CTL ,
1520+ CDC_WSA_TX3_SPKR_PROT_PATH_CTL , rate );
1521+ }
1522+
1523+ static int wsa_macro_mclk_event (struct snd_soc_dapm_widget * w ,
1524+ struct snd_kcontrol * kcontrol , int event )
1525+ {
1526+ struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
1527+ struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
1528+
1529+ wsa_macro_mclk_enable (wsa , event == SND_SOC_DAPM_PRE_PMU );
1530+ return 0 ;
1531+ }
1532+
1533+ static int wsa_macro_enable_vi_feedback (struct snd_soc_dapm_widget * w ,
1534+ struct snd_kcontrol * kcontrol ,
1535+ int event )
1536+ {
1537+ struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
1538+ struct wsa_macro * wsa = snd_soc_component_get_drvdata (component );
1539+ u32 rate_val ;
1540+
1541+ switch (wsa -> pcm_rate_vi ) {
1542+ case 8000 :
1543+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K ;
1544+ break ;
1545+ case 16000 :
1546+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_16K ;
1547+ break ;
1548+ case 24000 :
1549+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_24K ;
1550+ break ;
1551+ case 32000 :
1552+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_32K ;
1553+ break ;
1554+ case 48000 :
1555+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_48K ;
1556+ break ;
1557+ default :
1558+ rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K ;
1559+ break ;
1560+ }
1561+
1562+ switch (event ) {
1563+ case SND_SOC_DAPM_POST_PMU :
1564+ /* Enable V&I sensing */
1565+ wsa_macro_enable_disable_vi_feedback (component , true, rate_val );
1566+ break ;
1567+ case SND_SOC_DAPM_POST_PMD :
1568+ /* Disable V&I sensing */
1569+ wsa_macro_enable_disable_vi_feedback (component , false, rate_val );
15191570 break ;
15201571 }
15211572
0 commit comments