From 1d5cec79a5bc383b39e9221905025cd317077c96 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Tue, 28 Oct 2014 18:28:16 +0100 Subject: power: LP8720 regulator support 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 a2d3c047db8..12ca7663ec6 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_AXP221_POWER) += axp221.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 00000000000..ac7fc1167e7 --- /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 00000000000..033f2c46055 --- /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 -- cgit v1.2.3