From bea183bb0e0d4e9008ae95d04aac65e7680178fc Mon Sep 17 00:00:00 2001 From: David Rhodes Date: Wed, 30 May 2018 12:22:00 -0500 Subject: [PATCH] ASoC: cs35l41: Interrupt Handling Fixes -- Use regmap_write instead of regmap_update_bits when clearing interrupt status (clear on write) -- Toggle BST_EN when clearing boost errors Change-Id: Ie14e9cd39e0170a8903e1d226abcf5cc4e5340cb Signed-off-by: David Rhodes Signed-off-by: Ravi Vembu Mot-CRs-Fixed: (CR) Reviewed-on: https://gerrit.mot.com/1202250 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Submit-Approved: Jira Key --- sound/soc/codecs/cs35l41.c | 66 +++++++++++++++++++++----------------- sound/soc/codecs/cs35l41.h | 3 ++ 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 457c17239f67..16db7b67ffd6 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -467,86 +467,92 @@ static irqreturn_t cs35l41_irq(int irq, void *data) */ if (status[0] & CS35L41_AMP_SHORT_ERR) { dev_crit(cs35l41->dev, "Amp short error\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_AMP_SHORT_ERR_RLS, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_AMP_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_AMP_SHORT_ERR_RLS, CS35L41_AMP_SHORT_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_AMP_SHORT_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_AMP_SHORT_ERR, - CS35L41_AMP_SHORT_ERR); } if (status[0] & CS35L41_TEMP_WARN) { dev_crit(cs35l41->dev, "Over temperature warning\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_TEMP_WARN_ERR_RLS, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_WARN); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_TEMP_WARN_ERR_RLS, CS35L41_TEMP_WARN_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_TEMP_WARN_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_TEMP_WARN, - CS35L41_TEMP_WARN); } if (status[0] & CS35L41_TEMP_ERR) { dev_crit(cs35l41->dev, "Over temperature error\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_TEMP_ERR_RLS, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_TEMP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_TEMP_ERR_RLS, CS35L41_TEMP_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_TEMP_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_TEMP_ERR, - CS35L41_TEMP_ERR); } if (status[0] & CS35L41_BST_OVP_ERR) { dev_crit(cs35l41->dev, "VBST Over Voltage error\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_BST_OVP_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_OVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_OVP_ERR_RLS, CS35L41_BST_OVP_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_OVP_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_BST_OVP_ERR, - CS35L41_BST_OVP_ERR); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << + CS35L41_BST_EN_SHIFT); } if (status[0] & CS35L41_BST_DCM_UVP_ERR) { dev_crit(cs35l41->dev, "DCM VBST Under Voltage Error\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_BST_UVP_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_DCM_UVP_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_UVP_ERR_RLS, CS35L41_BST_UVP_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_UVP_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_BST_DCM_UVP_ERR, - CS35L41_BST_DCM_UVP_ERR); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << + CS35L41_BST_EN_SHIFT); } if (status[0] & CS35L41_BST_SHORT_ERR) { dev_crit(cs35l41->dev, "LBST error: powering off!\n"); - regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, - CS35L41_BST_SHORT_ERR_RLS, 0); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, 0); + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, + CS35L41_BST_SHORT_ERR); + regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_SHORT_ERR_RLS, CS35L41_BST_SHORT_ERR_RLS); regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, CS35L41_BST_SHORT_ERR_RLS, 0); - regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_BST_SHORT_ERR, - CS35L41_BST_SHORT_ERR); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_BST_EN_MASK, + CS35L41_BST_EN_DEFAULT << + CS35L41_BST_EN_SHIFT); } if (status[3] & CS35L41_OTP_BOOT_DONE) { diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h index a51cf7d21c95..d7ce29ca1b3b 100644 --- a/sound/soc/codecs/cs35l41.h +++ b/sound/soc/codecs/cs35l41.h @@ -649,6 +649,9 @@ #define CS35L41_GLOBAL_EN_MASK 0x01 #define CS35L41_GLOBAL_EN_SHIFT 0 +#define CS35L41_BST_EN_MASK 0x0030 +#define CS35L41_BST_EN_SHIFT 4 +#define CS35L41_BST_EN_DEFAULT 0x2 #define CS35L41_PDN_DONE_MASK 0x00800000 #define CS35L41_PDN_DONE_SHIFT 23