From patchwork Tue Oct 28 17:32:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 404307 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3D56514008B for ; Wed, 29 Oct 2014 04:33:06 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B18BA4B845; Tue, 28 Oct 2014 18:33:03 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6jrnex5zYw7e; Tue, 28 Oct 2014 18:33:03 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BDDE64B83E; Tue, 28 Oct 2014 18:33:02 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CB1454B83C for ; Tue, 28 Oct 2014 18:32:57 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id clEZsKsJINE6 for ; Tue, 28 Oct 2014 18:32:57 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from gagarine.paulk.fr (gagarine.paulk.fr [109.190.93.129]) by theia.denx.de (Postfix) with ESMTPS id 8B6C64B82F for ; Tue, 28 Oct 2014 18:32:53 +0100 (CET) Received: by gagarine.paulk.fr (Postfix, from userid 65534) id 12EFD43D00; Tue, 28 Oct 2014 18:32:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on gagarine.paulk.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable version=3.3.2 Received: from armstrong.paulk.fr (armstrong.paulk.fr [82.233.88.171]) by gagarine.paulk.fr (Postfix) with ESMTPS id 7701843D02 for ; Tue, 28 Oct 2014 18:32:43 +0100 (CET) Received: from aldrin.trisquel.info (aldrin [192.168.0.128]) by armstrong.paulk.fr (Postfix) with ESMTP id 1F1FC37647; Tue, 28 Oct 2014 18:32:41 +0100 (CET) From: Paul Kocialkowski To: u-boot@lists.denx.de Date: Tue, 28 Oct 2014 18:32:37 +0100 Message-Id: <1414517557-2457-1-git-send-email-contact@paulk.fr> X-Mailer: git-send-email 1.7.9.5 Subject: [U-Boot] [PATCH] power: LP8720 regulator support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This adds support for the LP8720 i2c regulator, as found in e.g. the LG Optimus Black (P970), codename sniper. This code supports setting up and enabling one of the 5 LDOs that the IC provides. Other more advanced features are unsupported. Signed-off-by: Paul Kocialkowski --- drivers/power/Makefile | 1 + drivers/power/lp8720.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ include/lp8720.h | 93 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 drivers/power/lp8720.c create mode 100644 include/lp8720.h diff --git a/drivers/power/Makefile b/drivers/power/Makefile index dc64e4d..65be5a0 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AXP152_POWER) += axp152.o obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o +obj-$(CONFIG_LP8720_POWER) += lp8720.o obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o obj-$(CONFIG_TWL4030_POWER) += twl4030.o obj-$(CONFIG_TWL6030_POWER) += twl6030.o diff --git a/drivers/power/lp8720.c b/drivers/power/lp8720.c new file mode 100644 index 0000000..ac7fc11 --- /dev/null +++ b/drivers/power/lp8720.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 Paul Kocialkowski + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static struct lp8720_info lp8720_info; + +static int lp8720_write(u8 reg, u8 val) +{ + return i2c_write(lp8720_info.chip_idsel, reg, 1, &val, 1); +} + +static int lp8720_read(u8 reg, u8 *val) +{ + return i2c_read(lp8720_info.chip_idsel, reg, 1, val, 1); +} + +int lp8720_init(int enable_gpio, int chip_idsel) +{ + int ret; + + if (enable_gpio) { + if (!gpio_is_valid(enable_gpio)) + return -1; + + ret = gpio_request(enable_gpio, "lp8720_en"); + if (ret) + return ret; + + ret = gpio_direction_output(enable_gpio, 0); + if (ret) + return ret; + } + + lp8720_info.enable_gpio = enable_gpio; + lp8720_info.chip_idsel = chip_idsel; + + return 0; +} + +int lp8720_enable(void) +{ + int ret; + + if (lp8720_info.enable_gpio) { + ret = gpio_set_value(lp8720_info.enable_gpio, 1); + if (ret) + return ret; + } + + return 0; +} + +int lp8720_is_enabled(void) +{ + if (lp8720_info.enable_gpio) + return gpio_get_value(lp8720_info.enable_gpio); + + /* Assume LP8720 enabled when there is no enable GPIO */ + return 1; +} + +int lp8720_ldo_enable(u8 ldo_enable) +{ + u8 val; + int ret; + + ret = lp8720_read(LP8720_ENABLE_BITS, &val); + if (ret) + return ret; + + val |= ldo_enable; + + ret = lp8720_write(LP8720_ENABLE_BITS, val); + if (ret) + return ret; + + /* Enable the IC */ + if (!lp8720_is_enabled()) + lp8720_enable(); + + return 0; +} + +int lp8720_ldo_voltage(u8 ldo_reg, u8 voltage, u8 delay) +{ + u8 val; + int ret; + + /* Register V field */ + val = voltage & 0x1F; + + /* Register T field */ + val |= (delay & 0x07) << 5; + + ret = lp8720_write(ldo_reg, val); + if (ret) + return ret; + + return 0; +} diff --git a/include/lp8720.h b/include/lp8720.h new file mode 100644 index 0000000..033f2c4 --- /dev/null +++ b/include/lp8720.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 Paul Kocialkowski + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef LP8720_H +#define LP8720_H + +#include + +/* + * Chip ID selection + */ + +#define LP8720_CHIP_IDSEL_VBATT 0x7F +#define LP8720_CHIP_IDSEL_HI_Z 0x7C +#define LP8720_CHIP_IDSEL_GND 0x7D + +/* + * Registers + */ + +#define LP8720_GENERAL_SETTINGS 0x00 +#define LP8720_LDO1_SETTINGS 0x01 +#define LP8720_LDO2_SETTINGS 0x02 +#define LP8720_LDO3_SETTINGS 0x03 +#define LP8720_LDO4_SETTINGS 0x04 +#define LP8720_LDO5_SETTINGS 0x05 +#define LP8720_BUCK_SETTINGS1 0x06 +#define LP8720_BUCK_SETTINGS2 0x07 +#define LP8720_ENABLE_BITS 0x08 +#define LP8720_PULLDOWN_BITS 0x09 +#define LP8720_STATUS_BITS 0x0A +#define LP8720_INTERRUPT_BITS 0x0B +#define LP8720_INTERRUPT_MASK 0x0C + +/* + * Values + */ + +/* LP8720_GENERAL_SETTINGS */ +#define LP8720_25_US_TIME_STEP (1 << 0) +#define LP8720_50_US_TIME_STEP (0 << 0) + +/* LP8720_LDO*_SETTINGS */ +#define LP8720_LDO1235_V_12 0x00 +#define LP8720_LDO1235_V_18 0x0C +#define LP8720_LDO1235_V_30 0x1D +#define LP8720_LDO1235_V_33 0x1F + +#define LP8720_LDO4_V_12 0x00 +#define LP8720_LDO4_V_14 0x09 +#define LP8720_LDO4_V_18 0x11 +#define LP8720_LDO4_V_28 0x1E + +#define LP8720_DELAY_0 0 +#define LP8720_DELAY_1_TS 1 +#define LP8720_DELAY_2_TS 2 +#define LP8720_DELAY_3_TS 3 +#define LP8720_DELAY_4_TS 4 +#define LP8720_DELAY_5_TS 5 +#define LP8720_DELAY_6_TS 6 +#define LP8720_DELAY_NO_START 7 + +/* LP8720_ENABLE_BITS */ +#define LP8720_LDO1_EN (1 << 0) +#define LP8720_LDO2_EN (1 << 1) +#define LP8720_LDO3_EN (1 << 2) +#define LP8720_LDO4_EN (1 << 3) +#define LP8720_LDO5_EN (1 << 4) +#define LP8720_BUCK_EN (1 << 5) + +/* + * Driver info + */ + +struct lp8720_info { + int enable_gpio; + int chip_idsel; +}; + +/* + * Declarations + */ + +int lp8720_init(int enable_gpio, int chip_idsel); +int lp8720_enable(void); +int lp8720_is_enabled(void); +int lp8720_ldo_enable(u8 ldo_enable); +int lp8720_ldo_voltage(u8 ldo_reg, u8 voltage, u8 delay); + +#endif