MAX8907 PMIC has embedded poweroff function used by some device to initiane device power off. Implement it as optional sysreset driver guarded by kconfig option and system-power-controller device tree property.
Tested-by: Ion Agorria <i...@agorria.com> Signed-off-by: Svyatoslav Ryhel <clamo...@gmail.com> --- drivers/power/pmic/max8907.c | 14 ++++++++++- drivers/sysreset/Kconfig | 7 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_max8907.c | 37 +++++++++++++++++++++++++++++ include/power/max8907.h | 4 ++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 drivers/sysreset/sysreset_max8907.c diff --git a/drivers/power/pmic/max8907.c b/drivers/power/pmic/max8907.c index 5d35957bf40..a7ef70177de 100644 --- a/drivers/power/pmic/max8907.c +++ b/drivers/power/pmic/max8907.c @@ -45,7 +45,19 @@ static int max8907_read(struct udevice *dev, uint reg, uint8_t *buff, int len) static int max8907_bind(struct udevice *dev) { ofnode regulators_node; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_MAX8907) && + dev_read_bool(dev, "maxim,system-power-controller")) { + ret = device_bind_driver_to_node(dev, MAX8907_RST_DRIVER, + "sysreset", dev_ofnode(dev), + NULL); + if (ret) { + log_debug("%s: cannot bind SYSRESET (ret = %d)\n", + __func__, 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 4972905482a..aa83073c96a 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -131,6 +131,13 @@ config SYSRESET_MAX77663 help Enable system power management functions found in MAX77663 PMIC. +config SYSRESET_MAX8907 + bool "Enable support for MAX8907 PMIC System Reset" + depends on DM_PMIC_MAX8907 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in MAX8907 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 ded91a4d325..f5c78b25896 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SYSRESET_CV1800B) += sysreset_cv1800b.o obj-$(CONFIG_$(PHASE_)POWEROFF_GPIO) += poweroff_gpio.o obj-$(CONFIG_$(PHASE_)SYSRESET_GPIO) += sysreset_gpio.o obj-$(CONFIG_$(PHASE_)SYSRESET_MAX77663) += sysreset_max77663.o +obj-$(CONFIG_$(PHASE_)SYSRESET_MAX8907) += sysreset_max8907.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_max8907.c b/drivers/sysreset/sysreset_max8907.c new file mode 100644 index 00000000000..6f62af9bffe --- /dev/null +++ b/drivers/sysreset/sysreset_max8907.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2024 Svyatoslav Ryhel <clamo...@gmail.com> + */ + +#include <dm.h> +#include <i2c.h> +#include <errno.h> +#include <sysreset.h> +#include <power/pmic.h> +#include <power/max8907.h> + +static int max8907_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + switch (type) { + case SYSRESET_POWER: + case SYSRESET_POWER_OFF: + /* MAX8907: PWR_OFF > RESET_CNFG */ + pmic_clrsetbits(dev->parent, MAX8907_REG_RESET_CNFG, + MASK_POWER_OFF, MASK_POWER_OFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops max8907_sysreset = { + .request = max8907_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_max8907) = { + .id = UCLASS_SYSRESET, + .name = MAX8907_RST_DRIVER, + .ops = &max8907_sysreset, +}; diff --git a/include/power/max8907.h b/include/power/max8907.h index a19b25f44c0..a6e558e582c 100644 --- a/include/power/max8907.h +++ b/include/power/max8907.h @@ -12,6 +12,7 @@ /* Drivers name */ #define MAX8907_LDO_DRIVER "max8907_ldo" #define MAX8907_SD_DRIVER "max8907_sd" +#define MAX8907_RST_DRIVER "max8907_rst" /* MAX8907 register map */ #define MAX8907_REG_SDCTL1 0x04 @@ -39,6 +40,9 @@ #define MAX8907_REG_LDOCTL18 0x72 #define MAX8907_REG_LDOCTL20 0x9C +#define MAX8907_REG_RESET_CNFG 0x0F +#define MASK_POWER_OFF BIT(6) + /* MAX8907 configuration values */ #define MAX8907_CTL 0 #define MAX8907_SEQCNT 1 -- 2.43.0