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 <clamo...@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 <clamo...@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