
Le mardi 28 octobre 2014 à 18:32 +0100, Paul Kocialkowski a écrit :
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 contact@paulk.fr
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 contact@paulk.fr
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <i2c.h> +#include <asm/gpio.h> +#include <lp8720.h>
+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);
+}
Should I ifdef for I2C and GPIO support? It seems that GPIO support only has board-sepcific config options, so this may be hard. There is CONFIG_DM_GPIO for driver model, but it is apparently not always used, especially not on SPL.
+int lp8720_init(int enable_gpio, int chip_idsel) +{
- int ret;
- if (enable_gpio) {
I'm guessing that in the case of a provided negative GPIO, this will return -1, which is not appropriate behavior (the regulator can still be used without an enable GPIO). I should probbaly directly go with gpio_is_valid.
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 contact@paulk.fr
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef LP8720_H +#define LP8720_H
+#include <common.h>
+/*
- 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