sysreset: implement MAX77663 sysreset functions

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@gmail.com>
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index eab556c..bc35896 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -74,6 +74,13 @@
 	  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 a9ac123..c31f51c 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -9,6 +9,7 @@
 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 0000000..8febcf8
--- /dev/null
+++ b/drivers/sysreset/sysreset_max77663.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
+ */
+
+#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,
+};