From 17a7fb3f4d0b382405920bba461ee123971af9a6 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Tue, 10 Jan 2023 18:25:44 +0530 Subject: [PATCH] asoc: Add support for 11P2896MHz RX clk config 1. Update RX CLK config for 11P2896MHz. 2. Add condition to update Droop sel coeffs for 11P28MHz and 9P6MHz RX CLK. 3. Upate SWR port config for 44.1Khz sample rate usecase. 4. Unselect RX_TOP.SWR_CTRL(0x6AC0008) for RX CLK 11P28MHz. 5. Update HD2_CTL L/R registers as per latest seq version. Change-Id: Ifac2c03e3d1bf522fe2a4d942341d9071a1e6239 Signed-off-by: Prasad Kumpatla --- asoc/codecs/lpass-cdc/internal.h | 2 + asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c | 5 +- asoc/codecs/lpass-cdc/lpass-cdc.c | 32 ++++++++++++- asoc/codecs/lpass-cdc/lpass-cdc.h | 6 +++ asoc/codecs/wcd939x/internal.h | 7 +++ asoc/codecs/wcd939x/wcd939x.c | 53 +++++++++++++++++----- asoc/pineapple-port-config.h | 2 +- 7 files changed, 91 insertions(+), 16 deletions(-) diff --git a/asoc/codecs/lpass-cdc/internal.h b/asoc/codecs/lpass-cdc/internal.h index 001a8db7d3..a47fc418bd 100644 --- a/asoc/codecs/lpass-cdc/internal.h +++ b/asoc/codecs/lpass-cdc/internal.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _LPASS_CDC_INTERNAL_H @@ -17,6 +18,7 @@ enum { LPASS_CDC_WCD_EVT_SSR_UP, LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK, LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB, + LPASS_CDC_WCD_EVT_CLK_NOTIFY, }; enum { diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c index 9d80341236..286d7c9cfc 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c @@ -2794,12 +2794,13 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon lpass_cdc_rx_macro_config_classh(component, rx_priv, interp_idx, event); /*select PCM path and swr clk is 9.6MHz*/ - if (rx_priv->is_pcm_enabled) { + if (rx_priv->is_pcm_enabled && !rx_priv->is_native_on) { if (rx_priv->pcm_select_users == 0) snd_soc_component_update_bits(component, LPASS_CDC_RX_TOP_SWR_CTRL, 0x02, 0x02); ++rx_priv->pcm_select_users; } + lpass_cdc_notify_wcd_rx_clk(rx_dev, rx_priv->is_native_on); } rx_priv->main_clk_users[interp_idx]++; } @@ -2812,7 +2813,7 @@ static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *compon snd_soc_component_update_bits(component, main_reg, 0x10, 0x10); /*Unselect PCM path*/ - if (rx_priv->is_pcm_enabled) { + if (rx_priv->is_pcm_enabled && !rx_priv->is_native_on) { if (rx_priv->pcm_select_users == 1) snd_soc_component_update_bits(component, LPASS_CDC_RX_TOP_SWR_CTRL, 0x02, 0x00); diff --git a/asoc/codecs/lpass-cdc/lpass-cdc.c b/asoc/codecs/lpass-cdc/lpass-cdc.c index 5805033a14..7390c67b5f 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -740,6 +740,36 @@ void lpass_cdc_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(lpass_cdc_unregister_macro); +void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on) +{ + struct lpass_cdc_priv *priv; + u32 val; + + if (!dev) { + pr_err_ratelimited("%s: dev is null\n", __func__); + return; + } + if (!lpass_cdc_is_valid_child_dev(dev)) { + dev_err_ratelimited(dev, "%s: not a valid child dev\n", + __func__); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err_ratelimited(dev, "%s: priv is null\n", __func__); + return; + } + if (is_native_on) + val = 0x2; /* 11.2896M */ + else + val = 0x0; /* 9.6M */ + + lpass_cdc_notifier_call(priv, + ((val << 16) | LPASS_CDC_WCD_EVT_CLK_NOTIFY)); + +} +EXPORT_SYMBOL(lpass_cdc_notify_wcd_rx_clk); + void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb) { struct lpass_cdc_priv *priv; diff --git a/asoc/codecs/lpass-cdc/lpass-cdc.h b/asoc/codecs/lpass-cdc/lpass-cdc.h index 844aed0449..6bf45501d3 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc.h +++ b/asoc/codecs/lpass-cdc/lpass-cdc.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef LPASS_CDC_H @@ -273,6 +274,7 @@ int lpass_cdc_set_port_map(struct snd_soc_component *component, u32 size, void * int lpass_cdc_register_event_listener(struct snd_soc_component *component, bool enable); void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb); +void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on); bool lpass_cdc_check_core_votes(struct device *dev); int lpass_cdc_tx_mclk_enable(struct snd_soc_component *c, bool enable); int lpass_cdc_get_version(struct device *dev); @@ -357,6 +359,10 @@ static void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb) { } +static void lpass_cdc_notify_wcd_rx_clk(struct device *dev, bool is_native_on) +{ +} + static inline bool lpass_cdc_check_core_votes(struct device *dev) { return false; diff --git a/asoc/codecs/wcd939x/internal.h b/asoc/codecs/wcd939x/internal.h index bbd845fc95..971b09801a 100644 --- a/asoc/codecs/wcd939x/internal.h +++ b/asoc/codecs/wcd939x/internal.h @@ -25,6 +25,12 @@ #define TX_ADC_MAX 4 #define SWR_NUM_PORTS 4 +enum { + RX_CLK_9P6MHZ, + RX_CLK_12P288MHZ, + RX_CLK_11P2896MHZ, +}; + enum { WCD939X_HPHL, WCD939X_HPHR, @@ -128,6 +134,7 @@ struct wcd939x_priv { bool dev_up; u8 tx_master_ch_map[WCD939X_MAX_SLAVE_CH_TYPES]; bool usbc_hs_status; + u8 rx_clk_config; /* wcd to swr dmic notification */ bool notify_swr_dmic; struct blocking_notifier_head notifier; diff --git a/asoc/codecs/wcd939x/wcd939x.c b/asoc/codecs/wcd939x/wcd939x.c index 64e56bfd1b..4503989015 100644 --- a/asoc/codecs/wcd939x/wcd939x.c +++ b/asoc/codecs/wcd939x/wcd939x.c @@ -919,9 +919,14 @@ static int wcd939x_enable_hph_pcm_index(struct snd_soc_component *component, switch (event) { case SND_SOC_DAPM_POST_PMU: if (hph == WCD939X_HPHL) { - snd_soc_component_update_bits(component, - REG_FIELD_VALUE(HPHL_RX_PATH_CFG1, - RX_DC_DROOP_COEFF_SEL, 0x3)); + if (wcd939x->rx_clk_config == RX_CLK_11P2896MHZ) + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(HPHL_RX_PATH_CFG1, + RX_DC_DROOP_COEFF_SEL, 0x2)); + else if (wcd939x->rx_clk_config == RX_CLK_9P6MHZ) + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(HPHL_RX_PATH_CFG1, + RX_DC_DROOP_COEFF_SEL, 0x3)); snd_soc_component_update_bits(component, REG_FIELD_VALUE(HPHL_RX_PATH_CFG0, DLY_ZN_EN, 0x1)); @@ -929,9 +934,14 @@ static int wcd939x_enable_hph_pcm_index(struct snd_soc_component *component, REG_FIELD_VALUE(HPHL_RX_PATH_CFG0, INT_EN, 0x3)); } else if (hph == WCD939X_HPHR) { - snd_soc_component_update_bits(component, - REG_FIELD_VALUE(HPHR_RX_PATH_CFG1, - RX_DC_DROOP_COEFF_SEL, 0x3)); + if (wcd939x->rx_clk_config == RX_CLK_11P2896MHZ) + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(HPHR_RX_PATH_CFG1, + RX_DC_DROOP_COEFF_SEL, 0x2)); + else if (wcd939x->rx_clk_config == RX_CLK_9P6MHZ) + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(HPHR_RX_PATH_CFG1, + RX_DC_DROOP_COEFF_SEL, 0x3)); snd_soc_component_update_bits(component, REG_FIELD_VALUE(HPHR_RX_PATH_CFG0, DLY_ZN_EN, 0x1)); @@ -1010,6 +1020,8 @@ static int wcd939x_config_compander(struct snd_soc_component *component, if (wcd939x->hph_mode == HPH_HIFI || wcd939x->hph_mode == HPH_LOHIFI || wcd939x->hph_mode == HPH_LP) hph_mode = 1; + else if (wcd939x->hph_mode == HPH_ULP) + hph_mode = 0; wcd939x_load_compander_coeff(component, comp_coeff_lsb_reg, comp_coeff_msb_reg, comp_coeff_table[hph_mode], @@ -1139,9 +1151,9 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHL_RX_EN, 0x01)); break; case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x1D)); if (!wcd939x->hph_pcm_enabled) { - snd_soc_component_update_bits(component, - REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x0f)); if (wcd939x->comp1_enable) { snd_soc_component_update_bits(component, REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHL_COMP_EN, 0x01)); @@ -1159,9 +1171,11 @@ static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, REG_FIELD_VALUE(L_EN, GAIN_SOURCE_SEL, 0x01)); } } + if (wcd939x->hph_pcm_enabled) + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(HPH_TIMER1, AUTOCHOP_TIMER_CTL_EN, 0x00)); break; case SND_SOC_DAPM_POST_PMD: - if (!wcd939x->hph_pcm_enabled) snd_soc_component_update_bits(component, REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x01)); snd_soc_component_update_bits(component, @@ -1191,9 +1205,9 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, REG_FIELD_VALUE(CDC_HPH_GAIN_CTL, HPHR_RX_EN, 0x01)); break; case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x1D)); if (!wcd939x->hph_pcm_enabled) { - snd_soc_component_update_bits(component, - REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x02)); if (wcd939x->comp1_enable) { snd_soc_component_update_bits(component, REG_FIELD_VALUE(CDC_COMP_CTL_0, HPHR_COMP_EN, 0x01)); @@ -1213,7 +1227,6 @@ static int wcd939x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_POST_PMD: - if (!wcd939x->hph_pcm_enabled) snd_soc_component_update_bits(component, REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x01)); snd_soc_component_update_bits(component, @@ -2534,6 +2547,7 @@ static int wcd939x_event_notify(struct notifier_block *block, { u16 event = (val & 0xffff); int ret = 0; + int rx_clk_type; struct wcd939x_priv *wcd939x = dev_get_drvdata((struct device *)data); struct snd_soc_component *component = wcd939x->component; struct wcd_mbhc *mbhc; @@ -2619,6 +2633,21 @@ static int wcd939x_event_notify(struct notifier_block *block, snd_soc_component_update_bits(component, WCD939X_TOP_CLK_CFG, 0x06, ((val >> 0x10) << 0x01)); + + rx_clk_type = (val >> 0x10); + + switch(rx_clk_type) { + case RX_CLK_12P288MHZ: + wcd939x->rx_clk_config = RX_CLK_12P288MHZ; + break; + case RX_CLK_11P2896MHZ: + wcd939x->rx_clk_config = RX_CLK_11P2896MHZ; + break; + default: + wcd939x->rx_clk_config = RX_CLK_9P6MHZ; + break; + } + dev_dbg(component->dev, "%s: rx clk config %d\n", __func__, wcd939x->rx_clk_config); break; default: dev_dbg(component->dev, "%s: invalid event %d\n", __func__, event); diff --git a/asoc/pineapple-port-config.h b/asoc/pineapple-port-config.h index 03c0bf42e8..f9421169e8 100644 --- a/asoc/pineapple-port-config.h +++ b/asoc/pineapple-port-config.h @@ -89,7 +89,7 @@ static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = { {0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* GPPO */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HAPT */ - {49, 0, 0, 0, 15, 24, 1, 0, 1, 0x00, 0x01}, /* HIFI */ + {63, 0, 0, 0, 15, 31, 1, 0, 1, 0x00, 0x01}, /* HIFI */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* HPHT */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* CMPT */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* IPCM */