Message ID | 20220427112812.2991816-2-narmstrong@baylibre.com |
---|---|
State | Accepted |
Commit | b5cfa0c7ca4f793df26525cac0ab8e03ed433218 |
Delegated to: | Tom Rini |
Headers | show |
Series | Add support for TPS65219 PMIC on AM64X-SKEVM | expand |
On Wed, Apr 27, 2022 at 01:28:09PM +0200, Neil Armstrong wrote: > The TPS65219 I2S PMIC features 3 Buck converters and 4 linear regulators, > 2 GPOs, 1 GPIO, and 3 multi-function-pin. > > This adds the PMIC driver, loading the regulator sub-nodes. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Applied to u-boot/master, thanks!
On 4/27/22 20:28, Neil Armstrong wrote: > The TPS65219 I2S PMIC features 3 Buck converters and 4 linear regulators, > 2 GPOs, 1 GPIO, and 3 multi-function-pin. > > This adds the PMIC driver, loading the regulator sub-nodes. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> > --- > drivers/power/pmic/Kconfig | 6 +++ > drivers/power/pmic/Makefile | 1 + > drivers/power/pmic/tps65219.c | 88 +++++++++++++++++++++++++++++++++++ > include/power/tps65219.h | 46 ++++++++++++++++++ > 4 files changed, 141 insertions(+) > create mode 100644 drivers/power/pmic/tps65219.c > create mode 100644 include/power/tps65219.h > > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig > index 953c92e212..bb3960020d 100644 > --- a/drivers/power/pmic/Kconfig > +++ b/drivers/power/pmic/Kconfig > @@ -367,6 +367,12 @@ config PMIC_TPS65941 > The TPS65941 is a PMIC containing a bunch of SMPS & LDOs. > This driver binds the pmic children. > > +config PMIC_TPS65219 > + bool "Enable driver for Texas Instruments TPS65219 PMIC" > + depends on DM_PMIC > + help > + The TPS65219 is a PMIC containing a bunch of SMPS & LDOs. > + This driver binds the pmic children. > endif > > config PMIC_TPS65217 > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile > index 584d6e0e78..f73b326255 100644 > --- a/drivers/power/pmic/Makefile > +++ b/drivers/power/pmic/Makefile > @@ -43,3 +43,4 @@ obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o > obj-$(CONFIG_POWER_HI6553) += pmic_hi6553.o > obj-$(CONFIG_POWER_MC34VR500) += pmic_mc34vr500.o > obj-$(CONFIG_PMIC_TPS65941) += tps65941.o > +obj-$(CONFIG_PMIC_TPS65219) += tps65219.o > diff --git a/drivers/power/pmic/tps65219.c b/drivers/power/pmic/tps65219.c > new file mode 100644 > index 0000000000..9462afee77 > --- /dev/null > +++ b/drivers/power/pmic/tps65219.c > @@ -0,0 +1,88 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2022 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@baylibre.com> > + */ > + > +#include <common.h> > +#include <fdtdec.h> > +#include <errno.h> > +#include <dm.h> > +#include <i2c.h> > +#include <log.h> > +#include <power/pmic.h> > +#include <power/regulator.h> > +#include <power/tps65219.h> > +#include <dm/device.h> > + > +static const struct pmic_child_info pmic_children_info[] = { > + { .prefix = "ldo", .driver = TPS65219_LDO_DRIVER }, > + { .prefix = "buck", .driver = TPS65219_BUCK_DRIVER }, > + { }, > +}; > + > +static int tps65219_reg_count(struct udevice *dev) > +{ > + return 0x41; > +} > + > +static int tps65219_write(struct udevice *dev, uint reg, const uint8_t *buff, > + int len) > +{ > + if (dm_i2c_write(dev, reg, buff, len)) { > + pr_err("write error to device: %p register: %#x!\n", dev, reg); > + return -EIO; > + } > + > + return 0; > +} > + > +static int tps65219_read(struct udevice *dev, uint reg, uint8_t *buff, int len) > +{ > + if (dm_i2c_read(dev, reg, buff, len)) { > + pr_err("read error from device: %p register: %#x!\n", dev, reg); > + return -EIO; > + } > + > + return 0; > +} > + > +static int tps65219_bind(struct udevice *dev) > +{ > + ofnode regulators_node; > + int children; > + > + regulators_node = dev_read_subnode(dev, "regulators"); > + if (!ofnode_valid(regulators_node)) { > + debug("%s: %s regulators subnode not found!\n", __func__, > + dev->name); > + } > + > + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); Its sequence is strange. If ofnode_valid is not valid, it should be displayed.. "regulator subnode not found" "found regulator subnode" It can be confused. > + > + children = pmic_bind_children(dev, regulators_node, pmic_children_info); > + if (!children) > + printf("%s: %s - no child found\n", __func__, dev->name); Is there any reason to use "printf" ? Best Regards, Jaehoon Chung > + > + /* Probe all the child devices */ > + return dm_scan_fdt_dev(dev); > +} > + > +static struct dm_pmic_ops tps65219_ops = { > + .reg_count = tps65219_reg_count, > + .read = tps65219_read, > + .write = tps65219_write, > +}; > + > +static const struct udevice_id tps65219_ids[] = { > + { .compatible = "ti,tps65219" }, > + { } > +}; > + > +U_BOOT_DRIVER(pmic_tps65219) = { > + .name = "tps65219_pmic", > + .id = UCLASS_PMIC, > + .of_match = tps65219_ids, > + .bind = tps65219_bind, > + .ops = &tps65219_ops, > +}; > diff --git a/include/power/tps65219.h b/include/power/tps65219.h > new file mode 100644 > index 0000000000..aa81b92266 > --- /dev/null > +++ b/include/power/tps65219.h > @@ -0,0 +1,46 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * (C) Copyright 2022 BayLibre, SAS > + * Author: Neil Armstrong <narmstrong@baylibre.com> > + */ > + > +#ifndef TPS65219_H > +#define TPS65219_H > + > +/* I2C device address for pmic tps65219 */ > +#define TPS65219_I2C_ADDR 0x30 > +#define TPS65219_LDO_NUM 4 > +#define TPS65219_BUCK_NUM 3 > + > +/* Drivers name */ > +#define TPS65219_LDO_DRIVER "tps65219_ldo" > +#define TPS65219_BUCK_DRIVER "tps65219_buck" > + > +#define TPS65219_VOLT_MASK 0x3F > +#define TPS65219_BUCK_VOLT_MAX 3400000 > + > +#define TPS65219_ENABLE_CTRL_REG 0x2 > + > +#define TPS65219_BUCK1_VOUT_REG 0xa > +#define TPS65219_BUCK2_VOUT_REG 0x9 > +#define TPS65219_BUCK3_VOUT_REG 0x8 > + > +#define TPS65219_LDO1_VOUT_REG 0x7 > +#define TPS65219_LDO2_VOUT_REG 0x6 > + > +#define TPS65219_LDO12_BYP_CONFIG 6 > + > +#define TPS65219_LDO3_VOUT_REG 0x5 > +#define TPS65219_LDO4_VOUT_REG 0x4 > + > +#define TPS65219_LDO12_VOLT_BYP_MIN 1500000 > +#define TPS65219_LDO12_VOLT_MIN 600000 > +#define TPS65219_LDO12_VOLT_MAX 3400000 > +#define TPS65219_LDO12_VOLT_REG_MIN 0 > +#define TPS65219_LDO12_VOLT_REG_MAX 0x56 > +#define TPS65219_LDO34_VOLT_MIN 1200000 > +#define TPS65219_LDO34_VOLT_MAX 3300000 > +#define TPS65219_LDO34_VOLT_REG_MIN 0x12 > +#define TPS65219_LDO34_VOLT_REG_MAX 0x54 > + > +#endif /* TPS65219_H */
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 953c92e212..bb3960020d 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -367,6 +367,12 @@ config PMIC_TPS65941 The TPS65941 is a PMIC containing a bunch of SMPS & LDOs. This driver binds the pmic children. +config PMIC_TPS65219 + bool "Enable driver for Texas Instruments TPS65219 PMIC" + depends on DM_PMIC + help + The TPS65219 is a PMIC containing a bunch of SMPS & LDOs. + This driver binds the pmic children. endif config PMIC_TPS65217 diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 584d6e0e78..f73b326255 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -43,3 +43,4 @@ obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o obj-$(CONFIG_POWER_HI6553) += pmic_hi6553.o obj-$(CONFIG_POWER_MC34VR500) += pmic_mc34vr500.o obj-$(CONFIG_PMIC_TPS65941) += tps65941.o +obj-$(CONFIG_PMIC_TPS65219) += tps65219.o diff --git a/drivers/power/pmic/tps65219.c b/drivers/power/pmic/tps65219.c new file mode 100644 index 0000000000..9462afee77 --- /dev/null +++ b/drivers/power/pmic/tps65219.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/tps65219.h> +#include <dm/device.h> + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "ldo", .driver = TPS65219_LDO_DRIVER }, + { .prefix = "buck", .driver = TPS65219_BUCK_DRIVER }, + { }, +}; + +static int tps65219_reg_count(struct udevice *dev) +{ + return 0x41; +} + +static int tps65219_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + pr_err("write error to device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps65219_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + pr_err("read error from device: %p register: %#x!\n", dev, reg); + return -EIO; + } + + return 0; +} + +static int tps65219_bind(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!\n", __func__, + dev->name); + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + printf("%s: %s - no child found\n", __func__, dev->name); + + /* Probe all the child devices */ + return dm_scan_fdt_dev(dev); +} + +static struct dm_pmic_ops tps65219_ops = { + .reg_count = tps65219_reg_count, + .read = tps65219_read, + .write = tps65219_write, +}; + +static const struct udevice_id tps65219_ids[] = { + { .compatible = "ti,tps65219" }, + { } +}; + +U_BOOT_DRIVER(pmic_tps65219) = { + .name = "tps65219_pmic", + .id = UCLASS_PMIC, + .of_match = tps65219_ids, + .bind = tps65219_bind, + .ops = &tps65219_ops, +}; diff --git a/include/power/tps65219.h b/include/power/tps65219.h new file mode 100644 index 0000000000..aa81b92266 --- /dev/null +++ b/include/power/tps65219.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#ifndef TPS65219_H +#define TPS65219_H + +/* I2C device address for pmic tps65219 */ +#define TPS65219_I2C_ADDR 0x30 +#define TPS65219_LDO_NUM 4 +#define TPS65219_BUCK_NUM 3 + +/* Drivers name */ +#define TPS65219_LDO_DRIVER "tps65219_ldo" +#define TPS65219_BUCK_DRIVER "tps65219_buck" + +#define TPS65219_VOLT_MASK 0x3F +#define TPS65219_BUCK_VOLT_MAX 3400000 + +#define TPS65219_ENABLE_CTRL_REG 0x2 + +#define TPS65219_BUCK1_VOUT_REG 0xa +#define TPS65219_BUCK2_VOUT_REG 0x9 +#define TPS65219_BUCK3_VOUT_REG 0x8 + +#define TPS65219_LDO1_VOUT_REG 0x7 +#define TPS65219_LDO2_VOUT_REG 0x6 + +#define TPS65219_LDO12_BYP_CONFIG 6 + +#define TPS65219_LDO3_VOUT_REG 0x5 +#define TPS65219_LDO4_VOUT_REG 0x4 + +#define TPS65219_LDO12_VOLT_BYP_MIN 1500000 +#define TPS65219_LDO12_VOLT_MIN 600000 +#define TPS65219_LDO12_VOLT_MAX 3400000 +#define TPS65219_LDO12_VOLT_REG_MIN 0 +#define TPS65219_LDO12_VOLT_REG_MAX 0x56 +#define TPS65219_LDO34_VOLT_MIN 1200000 +#define TPS65219_LDO34_VOLT_MAX 3300000 +#define TPS65219_LDO34_VOLT_REG_MIN 0x12 +#define TPS65219_LDO34_VOLT_REG_MAX 0x54 + +#endif /* TPS65219_H */
The TPS65219 I2S PMIC features 3 Buck converters and 4 linear regulators, 2 GPOs, 1 GPIO, and 3 multi-function-pin. This adds the PMIC driver, loading the regulator sub-nodes. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/power/pmic/Kconfig | 6 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/tps65219.c | 88 +++++++++++++++++++++++++++++++++++ include/power/tps65219.h | 46 ++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 drivers/power/pmic/tps65219.c create mode 100644 include/power/tps65219.h