Hi Svyatoslav, On Sun, 23 Jul 2023 at 06:28, Svyatoslav Ryhel <[email protected]> wrote: > > Add support to bind the regulators/child nodes with the pmic. > Also adds the pmic i2c based read/write functions to access pmic > registers. > > Signed-off-by: Svyatoslav Ryhel <[email protected]> > --- > doc/device-tree-bindings/pmic/tps80031.txt | 76 ++++++++++++++++++++ > drivers/power/pmic/Kconfig | 6 ++ > drivers/power/pmic/Makefile | 1 + > drivers/power/pmic/tps80031.c | 82 ++++++++++++++++++++++ > include/power/tps80031.h | 42 +++++++++++ > 5 files changed, 207 insertions(+) > create mode 100644 doc/device-tree-bindings/pmic/tps80031.txt > create mode 100644 drivers/power/pmic/tps80031.c > create mode 100644 include/power/tps80031.h >
Reviewed-by: Simon Glass <[email protected]> > diff --git a/doc/device-tree-bindings/pmic/tps80031.txt > b/doc/device-tree-bindings/pmic/tps80031.txt > new file mode 100644 > index 0000000000..577e6de1c1 > --- /dev/null > +++ b/doc/device-tree-bindings/pmic/tps80031.txt > @@ -0,0 +1,76 @@ > +Texas Instruments, TPS80031/TPS80032 PMIC > + > +This device uses two drivers: > +- drivers/power/pmic/tps80031.c (for parent device) > +- drivers/power/regulator/tps80031_regulator.c (for child regulators) > + > +This chapter describes the binding info for the PMIC driver and regulators. > + > +Required properties for PMIC: > +- compatible: "ti,tps80031" or "ti,tps80032" > +- reg: 0x48 > + > +With those two properties, the pmic device can be used for read/write only. > +To bind each regulator, the optional regulators subnode should exists. > + > +Optional subnode: > +- name: regulators (subnode list of each device's regulator) > + > +Regulators subnode contains set on supported regulators. > + > +Required properties: > +- regulator-name: used for regulator uclass platform data '.name', > + > +List of supported regulator nodes names for tps80031/tps80032: > +- smps1, smps2, smps3, smps4, smps5 > +- ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldoln, ldousb > + > +SMPS5 in Linux 3.1.10 is referred as vio, but datasheet clearly names it > SMPS5. > + > +Optional: > +- regulator-min-microvolt: minimum allowed Voltage to set > +- regulator-max-microvolt: minimum allowed Voltage to set > +- regulator-always-on: regulator should be never disabled > +- regulator-boot-on: regulator should be enabled by the bootloader > + > +Example: > + > +tps80032@48 { > + compatible = "ti,tps80032"; > + reg = <0x48>; > + > + regulators { > + smps1 { > + regulator-name = "vdd_cpu"; > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <1250000>; > + regulator-always-on; > + regulator-boot-on; > + }; > + > + ... > + > + smps5 { > + regulator-name = "vdd_1v8_gen"; > + regulator-min-microvolt = <1800000>; > + regulator-max-microvolt = <1800000>; > + regulator-always-on; > + regulator-boot-on; > + }; > + > + ldo1 { > + regulator-name = "avdd_dsi_csi"; > + regulator-min-microvolt = <1200000>; > + regulator-max-microvolt = <1200000>; > + regulator-boot-on; > + }; > + > + ... > + > + ldousb { > + regulator-name = "avdd_usb"; > + regulator-min-microvolt = <3300000>; > + regulator-max-microvolt = <3300000>; > + }; > + }; > +}; > diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig > index abea0fe4ed..d25fe1ce0d 100644 > --- a/drivers/power/pmic/Kconfig > +++ b/drivers/power/pmic/Kconfig > @@ -347,6 +347,12 @@ config DM_PMIC_TPS65910 > DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO > pmic children. > > +config DM_PMIC_TPS80031 > + bool "Enable driver for Texas Instruments TPS80031/TPS80032 PMIC" > + ---help--- > + The TPS80031/TPS80032 are PMIC's containing several LDOs, SMPS. > + This driver binds the pmic children. SMPs ? What is that? Perhaps add a little more detail? > + > config PMIC_STPMIC1 > bool "Enable support for STMicroelectronics STPMIC1 PMIC" > depends on DM_I2C > diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile > index 414a9d8225..55ee614364 100644 > --- a/drivers/power/pmic/Makefile > +++ b/drivers/power/pmic/Makefile > @@ -27,6 +27,7 @@ obj-$(CONFIG_$(SPL_)PMIC_RN5T567) += rn5t567.o > obj-$(CONFIG_PMIC_TPS65090) += tps65090.o > obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o > obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o > +obj-$(CONFIG_$(SPL_)DM_PMIC_TPS80031) += tps80031.o > obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o > obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o > obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o > diff --git a/drivers/power/pmic/tps80031.c b/drivers/power/pmic/tps80031.c > new file mode 100644 > index 0000000000..24c8a2c613 > --- /dev/null > +++ b/drivers/power/pmic/tps80031.c > @@ -0,0 +1,82 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright(C) 2023 Svyatoslav Ryhel <[email protected]> > + */ > + > +#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/tps80031.h> > +#include <dm/device.h> That should be included by dm.h > + > +static const struct pmic_child_info pmic_children_info[] = { > + { .prefix = "ldo", .driver = TPS80031_LDO_DRIVER }, > + { .prefix = "smps", .driver = TPS80031_SMPS_DRIVER }, > + { }, > +}; > + > +static int tps80031_write(struct udevice *dev, uint reg, const uint8_t *buff, u8 > + int len) > +{ > + if (dm_i2c_write(dev, reg, buff, len)) { > + log_err("write error to device: %p register: %#x!\n", dev, > reg); > + return -EIO; > + } > + > + return 0; > +} > + > +static int tps80031_read(struct udevice *dev, uint reg, uint8_t *buff, int > len) > +{ > + if (dm_i2c_read(dev, reg, buff, len)) { > + log_err("read error from device: %p register: %#x!\n", dev, > reg); > + return -EIO; > + } > + > + return 0; > +} > + > +static int tps80031_bind(struct udevice *dev) > +{ > + ofnode regulators_node; > + int children; > + > + regulators_node = dev_read_subnode(dev, "regulators"); > + if (!ofnode_valid(regulators_node)) { > + log_err("%s regulators subnode not found!\n", dev->name); > + return -ENXIO; > + } > + > + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); > + > + children = pmic_bind_children(dev, regulators_node, > pmic_children_info); > + if (!children) > + log_err("%s - no child found\n", dev->name); > + > + /* Always return success for this device */ > + return 0; > +} > + > +static struct dm_pmic_ops tps80031_ops = { > + .read = tps80031_read, > + .write = tps80031_write, > +}; > + > +static const struct udevice_id tps80031_ids[] = { > + { .compatible = "ti,tps80031" }, > + { .compatible = "ti,tps80032" }, > + { } > +}; > + > +U_BOOT_DRIVER(pmic_tps80031) = { > + .name = "tps80031_pmic", > + .id = UCLASS_PMIC, > + .of_match = tps80031_ids, > + .bind = tps80031_bind, > + .ops = &tps80031_ops, > +}; > diff --git a/include/power/tps80031.h b/include/power/tps80031.h > new file mode 100644 > index 0000000000..f514db910b > --- /dev/null > +++ b/include/power/tps80031.h > @@ -0,0 +1,42 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright(C) 2023 Svyatoslav Ryhel <[email protected]> > + */ > + > +#ifndef _TPS80031_H_ > +#define _TPS80031_H_ > + > +#define TPS80031_LDO_NUM 9 > +#define TPS80031_SMPS_NUM 5 > + > +/* Drivers name */ > +#define TPS80031_LDO_DRIVER "tps80031_ldo" > +#define TPS80031_SMPS_DRIVER "tps80031_smps" > + > +#define TPS80031_SMPS_OFFSET 0xE0 > +#define TPS80031_OFFSET_FLAG BIT(3) > + > +#define TPS80031_REGULATOR_STATUS_MASK 0x3 > +#define TPS80031_REGULATOR_MODE_ON 0x1 > + > +#define TPS80031_SMPS_VOLT_MASK 0x3F > +#define TPS80031_SMPS_VOLT_MAX_HEX 0x39 > +#define TPS80031_SMPS_VOLT_MAX 1400000 > +#define TPS80031_SMPS_VOLT_BASE 600000 > +#define TPS80031_SMPS_VOLT_BASE_OFFSET 700000 > + > +#define TPS80031_LDO_VOLT_MASK 0x3F > +#define TPS80031_LDO_VOLT_MAX_HEX 0x18 > +#define TPS80031_LDO_VOLT_MIN_HEX 0x01 > +#define TPS80031_LDO_VOLT_MAX 3360000 > +#define TPS80031_LDO_VOLT_MIN 1018000 > +#define TPS80031_LDO_VOLT_BASE 916000 Similar point about the TPS80031_ prefix > + > +/* register groups */ > +enum { > + CTRL, > + VOLT, > + OFFSET, > +}; > + > +#endif /* _TPS80031_H_ */ > -- > 2.39.2 > Regards, Simon

