[PATCH v4 3/6] sysreset: implement MAX77663 sysreset functions

Svyatoslav Ryhel clamor95 at gmail.com
Tue Oct 24 09:49:05 CEST 2023


MAX77663 PMIC has embedded poweroff function used by some
device to initiane device power off. Implement it as sysreset
driver.

Signed-off-by: Svyatoslav Ryhel <clamor95 at gmail.com>
---
 drivers/power/pmic/max77663.c        | 12 ++++++-
 drivers/sysreset/Kconfig             |  7 ++++
 drivers/sysreset/Makefile            |  1 +
 drivers/sysreset/sysreset_max77663.c | 53 ++++++++++++++++++++++++++++
 include/power/max77663.h             |  5 +++
 5 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 drivers/sysreset/sysreset_max77663.c

diff --git a/drivers/power/pmic/max77663.c b/drivers/power/pmic/max77663.c
index 4070235d3c..e333c8dcf5 100644
--- a/drivers/power/pmic/max77663.c
+++ b/drivers/power/pmic/max77663.c
@@ -9,6 +9,7 @@
 #include <dm.h>
 #include <i2c.h>
 #include <log.h>
+#include <dm/lists.h>
 #include <power/pmic.h>
 #include <power/regulator.h>
 #include <power/max77663.h>
@@ -49,7 +50,16 @@ static int max77663_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 static int max77663_bind(struct udevice *dev)
 {
 	ofnode regulators_node;
-	int children;
+	int children, ret;
+
+	if (IS_ENABLED(CONFIG_SYSRESET_MAX77663)) {
+		ret = device_bind_driver(dev, MAX77663_RST_DRIVER,
+					 "sysreset", NULL);
+		if (ret) {
+			log_err("cannot bind SYSRESET (ret = %d)\n", ret);
+			return ret;
+		}
+	}
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index eab556c349..bc35896101 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -74,6 +74,13 @@ config SYSRESET_GPIO
 	  example on Microblaze where reset logic can be controlled via GPIO
 	  pin which triggers cpu reset.
 
+config SYSRESET_MAX77663
+	bool "Enable support for MAX77663 PMIC System Reset"
+	depends on DM_PMIC_MAX77663
+	select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
+	help
+	  Enable system power management functions found in MAX77663 PMIC.
+
 config SYSRESET_MICROBLAZE
 	bool "Enable support for Microblaze soft reset"
 	depends on MICROBLAZE
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index a9ac123754..c31f51c581 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_POWEROFF_GPIO) += poweroff_gpio.o
 obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
+obj-$(CONFIG_$(SPL_TPL_)SYSRESET_MAX77663) += sysreset_max77663.o
 obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o
 obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
 obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o
diff --git a/drivers/sysreset/sysreset_max77663.c b/drivers/sysreset/sysreset_max77663.c
new file mode 100644
index 0000000000..4a2a2275df
--- /dev/null
+++ b/drivers/sysreset/sysreset_max77663.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright(C) 2023 Svyatoslav Ryhel <clamor95 at gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <power/pmic.h>
+#include <power/max77663.h>
+
+static int max77663_sysreset_request(struct udevice *dev,
+				     enum sysreset_t type)
+{
+	int val;
+
+	val = pmic_reg_read(dev->parent, MAX77663_REG_ONOFF_CFG1);
+	if (val < 0)
+		return val;
+
+	/* clear both bits */
+	val &= ~ONOFF_SFT_RST;
+	val &= ~ONOFF_PWR_OFF;
+
+	switch (type) {
+	case SYSRESET_POWER:
+		/* MAX77663: SFT_RST > ONOFF_CFG1 */
+		pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1,
+			       val | ONOFF_SFT_RST);
+		break;
+	case SYSRESET_POWER_OFF:
+		/* MAX77663: PWR_OFF > ONOFF_CFG1 */
+		pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1,
+			       val | ONOFF_PWR_OFF);
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops max77663_sysreset = {
+	.request = max77663_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_max77663) = {
+	.id	= UCLASS_SYSRESET,
+	.name	= MAX77663_RST_DRIVER,
+	.ops	= &max77663_sysreset,
+};
diff --git a/include/power/max77663.h b/include/power/max77663.h
index 0f764bcbcc..b3ae3dabf4 100644
--- a/include/power/max77663.h
+++ b/include/power/max77663.h
@@ -12,6 +12,7 @@
 /* Drivers name */
 #define MAX77663_LDO_DRIVER		"max77663_ldo"
 #define MAX77663_SD_DRIVER		"max77663_sd"
+#define MAX77663_RST_DRIVER		"max77663_rst"
 
 /* Step-Down (SD) Regulator calculations */
 #define SD_STATUS_MASK			0x30
@@ -39,4 +40,8 @@
 
 #define LDO_VOLT_BASE			800000
 
+#define MAX77663_REG_ONOFF_CFG1		0x41
+#define   ONOFF_SFT_RST			BIT(7)
+#define   ONOFF_PWR_OFF			BIT(1)
+
 #endif /* _MAX77663_H_ */
-- 
2.39.2



More information about the U-Boot mailing list