[PATCH v2 6/9] power: pmic: add the base TPS80031 PMIC support
Svyatoslav Ryhel
clamor95 at gmail.com
Thu Jul 20 10:48:01 CEST 2023
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 <clamor95 at gmail.com>
---
doc/device-tree-bindings/pmic/tps80031.txt | 76 +++++++++++++++++
drivers/power/pmic/Kconfig | 6 ++
drivers/power/pmic/Makefile | 1 +
drivers/power/pmic/tps80031.c | 97 ++++++++++++++++++++++
include/power/tps80031.h | 45 ++++++++++
5 files changed, 225 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
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 at 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.
+
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..bce01c6276
--- /dev/null
+++ b/drivers/power/pmic/tps80031.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright(C) 2023 Svyatoslav Ryhel <clamor95 at gmail.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/tps80031.h>
+#include <dm/device.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,
+ 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_poweroff(struct udevice *dev)
+{
+ return pmic_reg_write(dev, TPS80031_PHOENIX_DEV_ON, DEVOFF);
+}
+
+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 int tps80031_probe(struct udevice *dev)
+{
+ struct uc_pmic_priv *priv = dev_get_uclass_priv(dev);
+
+ priv->sys_pow_ctrl = dev_read_bool(dev, "ti,system-power-controller");
+ return 0;
+}
+
+static struct dm_pmic_ops tps80031_ops = {
+ .poweroff = tps80031_poweroff,
+ .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,
+ .probe = tps80031_probe,
+ .ops = &tps80031_ops,
+};
diff --git a/include/power/tps80031.h b/include/power/tps80031.h
new file mode 100644
index 0000000000..3d61ac54be
--- /dev/null
+++ b/include/power/tps80031.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright(C) 2023 Svyatoslav Ryhel <clamor95 at gmail.com>
+ */
+
+#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
+
+#define TPS80031_PHOENIX_DEV_ON 0x25
+#define DEVOFF BIT(0)
+
+/* register groups */
+enum {
+ CTRL,
+ VOLT,
+ OFFSET,
+};
+
+#endif /* _TPS80031_H_ */
--
2.39.2
More information about the U-Boot
mailing list