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 <narmstr...@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 <narmstr...@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 <narmstr...@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 */