From 4fab68674166dfbaa6095d1fa12d827c2942dbdb Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 23 Mar 2017 12:38:25 +0530 Subject: [PATCH] ASoC: wcd934x: Fix sequence for efuse sensing Fix sequence for efuse sensing on WCD934x codec to avoid codec register access failures. CRs-Fixed: 2021132 Change-Id: I5da8c4c6b9f9822563b95c7a270fd11449456b29 Signed-off-by: Sudheer Papothi --- drivers/mfd/wcd934x-regmap.c | 15 ++++++++++++++- sound/soc/codecs/wcd934x/wcd934x.c | 18 +++++++++++++++--- sound/soc/codecs/wcd9xxx-resmgr-v2.c | 8 +++----- sound/soc/codecs/wcd9xxx-resmgr-v2.h | 5 ++++- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/wcd934x-regmap.c b/drivers/mfd/wcd934x-regmap.c index fbaf05e58aff..e8ba1495de2b 100644 --- a/drivers/mfd/wcd934x-regmap.c +++ b/drivers/mfd/wcd934x-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1926,6 +1926,19 @@ static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg) case WCD934X_ANA_MBHC_ELECT: case WCD934X_ANA_MBHC_ZDET: case WCD934X_ANA_MICB2: + case WCD934X_CODEC_RPM_CLK_MCLK_CFG: + case WCD934X_CLK_SYS_MCLK_PRG: + case WCD934X_CHIP_TIER_CTRL_EFUSE_CTL: + case WCD934X_ANA_BIAS: + case WCD934X_ANA_BUCK_CTL: + case WCD934X_ANA_RCO: + case WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL: + case WCD934X_CODEC_RPM_CLK_GATE: + case WCD934X_BIAS_VBG_FINE_ADJ: + case WCD934X_CODEC_CPR_SVS_CX_VDD: + case WCD934X_CODEC_CPR_SVS2_CX_VDD: + case WCD934X_CDC_TOP_TOP_CFG1: + case WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: return true; } diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 192d9291a8f3..cc8e45d77fcd 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -798,11 +798,13 @@ int wcd934x_bringup(struct wcd9xxx *wcd9xxx) regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x01); regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x19); regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_D_STARTUP, 0x15); + /* Add 1msec delay for VOUT to settle */ + usleep_range(1000, 1100); regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); - regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x3); regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x7); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); return 0; } @@ -8277,6 +8279,9 @@ static int __tavil_cdc_mclk_enable(struct tavil_priv *tavil, WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); ret = __tavil_cdc_mclk_enable_locked(tavil, enable); + if (enable) + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); return ret; @@ -8415,6 +8420,8 @@ static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, __func__, ret); goto done; } + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); ret = wcd_resmgr_enable_clk_block(tavil->resmgr, WCD_CLK_RCO); ret |= tavil_cdc_req_mclk_enable(tavil, false); @@ -9816,18 +9823,23 @@ static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil) { int val, rc; - __tavil_cdc_mclk_enable(tavil, true); + WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); + __tavil_cdc_mclk_enable_locked(tavil, true); regmap_update_bits(tavil->wcd9xxx->regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x10); regmap_update_bits(tavil->wcd9xxx->regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); - /* * 5ms sleep required after enabling efuse control * before checking the status. */ usleep_range(5000, 5500); + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); + + WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); + rc = regmap_read(tavil->wcd9xxx->regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS, &val); if (rc || (!(val & 0x01))) diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.c b/sound/soc/codecs/wcd9xxx-resmgr-v2.c index bd92ccc9e009..f16fc05a5eaa 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.c +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.c @@ -25,8 +25,7 @@ #define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 #define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 -static void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, - int sido_src); + static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type) { if (clk_type == WCD_CLK_OFF) @@ -267,8 +266,6 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) 0x01, 0x01); wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00); - wcd_resmgr_set_sido_input_src(resmgr, - SIDO_SOURCE_RCO_BG); } else { wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, @@ -515,7 +512,7 @@ int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, return ret; } -static void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, +void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, int sido_src) { if (!resmgr) @@ -553,6 +550,7 @@ static void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, pr_debug("%s: sido input src to external\n", __func__); } } +EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src); /* * wcd_resmgr_set_sido_input_src_locked: diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.h b/sound/soc/codecs/wcd9xxx-resmgr-v2.h index f605a249a620..e831ba61e9c2 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.h +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -87,4 +87,7 @@ int wcd_resmgr_get_clk_type(struct wcd9xxx_resmgr_v2 *resmgr); void wcd_resmgr_post_ssr_v2(struct wcd9xxx_resmgr_v2 *resmgr); void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr, int sido_src); +void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, + int sido_src); + #endif