Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932168AbbDQIvR (ORCPT ); Fri, 17 Apr 2015 04:51:17 -0400 Received: from opensource.wolfsonmicro.com ([80.75.67.52]:39092 "EHLO opensource.wolfsonmicro.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753232AbbDQIsz (ORCPT ); Fri, 17 Apr 2015 04:48:55 -0400 From: Charles Keepax To: lee.jones@linaro.org Cc: broonie@kernel.org, sameo@linux.intel.com, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, patches@opensource.wolfsonmicro.com Subject: [PATCH v2 3/9] mfd: wm5102: Ensure we always boot the device fully Date: Fri, 17 Apr 2015 09:42:20 +0100 Message-Id: <1429260146-16694-4-git-send-email-ckeepax@opensource.wolfsonmicro.com> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1429260146-16694-1-git-send-email-ckeepax@opensource.wolfsonmicro.com> References: <1429260146-16694-1-git-send-email-ckeepax@opensource.wolfsonmicro.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2792 Lines: 96 The wm5102 uses a custom boot sequence and the standard boot sequence is disabled. However, the standard boot sequence must be run at least once after a cold boot (caused by either a hard reset or removal of AVDD). Unfortunately the register WRITE_SEQUENCER_CTRL_3 is not affected by the hardware reset. This means if the device has been previously booted but the AVDD supply has never been removed, arizona_dev_init will reset the chip but the boot sequence will not run, which can cause numerous problems. The solution is to manually clear this register and then boot the chip again, which is what this patch does. Signed-off-by: Charles Keepax --- drivers/mfd/arizona-core.c | 50 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c0e8a96..73418bd 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -344,6 +344,33 @@ err_fll: return err; } +static int wm5102_clear_write_sequencer(struct arizona *arizona) +{ + int ret; + + ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3, + 0x0); + if (ret) { + dev_err(arizona->dev, + "Failed to clear write sequencer state: %d\n", ret); + return ret; + } + + arizona_enable_reset(arizona); + regulator_disable(arizona->dcvdd); + + msleep(20); + + ret = regulator_enable(arizona->dcvdd); + if (ret) { + dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret); + return ret; + } + arizona_disable_reset(arizona); + + return 0; +} + #ifdef CONFIG_PM static int arizona_runtime_resume(struct device *dev) { @@ -810,21 +837,24 @@ int arizona_dev_init(struct arizona *arizona) case WM5102: ret = regmap_read(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3, &val); - if (ret != 0) + if (ret) { dev_err(dev, "Failed to check write sequencer state: %d\n", ret); - else if (val & 0x01) - break; - /* Fall through */ - default: - ret = arizona_wait_for_boot(arizona); - if (ret != 0) { - dev_err(arizona->dev, - "Device failed initial boot: %d\n", ret); - goto err_reset; + } else if (val & 0x01) { + ret = wm5102_clear_write_sequencer(arizona); + if (ret) + return ret; } break; + default: + break; + } + + ret = arizona_wait_for_boot(arizona); + if (ret) { + dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); + goto err_reset; } /* Read the device ID information & do device specific stuff */ -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/