From 506dfc815a88f0d4a4444c669cbb3db4fcd32335 Mon Sep 17 00:00:00 2001 From: Audun Korneliussen Date: Fri, 20 Sep 2024 10:37:37 +0200 Subject: [PATCH] drivers: mfd: npm2100: Add npm2100 mfd driver Add mfd driver for the npm2100 pmic device. The driver contains basic initialization routines, and functionality not covered by other device driver APIs. Signed-off-by: Audun Korneliussen --- drivers/mfd/CMakeLists.txt | 1 + drivers/mfd/Kconfig | 1 + drivers/mfd/Kconfig.npm2100 | 10 + drivers/mfd/mfd_npm2100.c | 426 +++++++++++++++++++++++++++ dts/bindings/mfd/nordic,npm2100.yaml | 72 +++++ include/zephyr/drivers/mfd/npm2100.h | 129 ++++++++ 6 files changed, 639 insertions(+) create mode 100644 drivers/mfd/Kconfig.npm2100 create mode 100644 drivers/mfd/mfd_npm2100.c create mode 100644 dts/bindings/mfd/nordic,npm2100.yaml create mode 100644 include/zephyr/drivers/mfd/npm2100.h diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index bc4d37cbd22..a9886f0d0d6 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_library_sources_ifdef(CONFIG_MFD_ADP5585 mfd_adp5585.c) zephyr_library_sources_ifdef(CONFIG_MFD_MAX20335 mfd_max20335.c) zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c) +zephyr_library_sources_ifdef(CONFIG_MFD_NPM2100 mfd_npm2100.c) zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c) zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c) zephyr_library_sources_ifdef(CONFIG_MFD_AD559X mfd_ad559x.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 13c1dff795c..f9705c8bd8c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -26,6 +26,7 @@ source "drivers/mfd/Kconfig.max20335" source "drivers/mfd/Kconfig.max31790" source "drivers/mfd/Kconfig.nct38xx" source "drivers/mfd/Kconfig.npm1300" +source "drivers/mfd/Kconfig.npm2100" source "drivers/mfd/Kconfig.npm6001" source "drivers/mfd/Kconfig.lpflexcomm" source "drivers/mfd/Kconfig.tle9104" diff --git a/drivers/mfd/Kconfig.npm2100 b/drivers/mfd/Kconfig.npm2100 new file mode 100644 index 00000000000..aed9829b921 --- /dev/null +++ b/drivers/mfd/Kconfig.npm2100 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config MFD_NPM2100 + bool "nPM2100 PMIC multi-function device driver" + default y + depends on DT_HAS_NORDIC_NPM2100_ENABLED + select I2C + help + Enable the Nordic nPM2100 PMIC multi-function device driver diff --git a/drivers/mfd/mfd_npm2100.c b/drivers/mfd/mfd_npm2100.c new file mode 100644 index 00000000000..316687da1e9 --- /dev/null +++ b/drivers/mfd/mfd_npm2100.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_npm2100 + +#include + +#include +#include +#include +#include +#include +#include + +#define EVENTS_SET 0x00U +#define EVENTS_CLR 0x05U +#define INTEN_SET 0x0AU +#define GPIO_CONFIG 0x80U +#define GPIO_USAGE 0x83U +#define TIMER_TASKS_START 0xB0U +#define TIMER_CONFIG 0xB3U +#define TIMER_TARGET 0xB4U +#define TIMER_STATUS 0xB7U +#define SHPHLD_WAKEUP 0xC1U +#define SHPHLD_SHPHLD 0xC2U +#define HIBERNATE_TASKS_HIBER 0xC8U +#define RESET_TASKS_RESET 0xD0U +#define RESET_BUTTON 0xD2U +#define RESET_PIN 0xD3U +#define RESET_WRITESTICKY 0xDBU +#define RESET_STROBESTICKY 0xDCU + +#define SHPHLD_RESISTOR_MASK 0x03U +#define SHPHLD_RESISTOR_PULLUP 0x00U +#define SHPHLD_RESISTOR_NONE 0x01U +#define SHPHLD_RESISTOR_PULLDOWN 0x02U +#define SHPHLD_CURR_MASK 0x0CU +#define SHPHLD_PULL_ENABLE 0x10U + +#define WAKEUP_EDGE_FALLING 0x00U +#define WAKEUP_EDGE_RISING 0x01U +#define WAKEUP_HIBERNATE_PIN 0x00U +#define WAKEUP_HIBERNATE_NOPIN 0x02U + +#define TIMER_CONFIG_WKUP 3U + +#define TIMER_STATUS_IDLE 0U + +#define TIMER_PRESCALER_MUL 64ULL +#define TIMER_PRESCALER_DIV 1000ULL +#define TIMER_MAX 0xFFFFFFU + +#define EVENTS_SIZE 5U + +#define GPIO_USAGE_INTLO 0x01U +#define GPIO_USAGE_INTHI 0x02U +#define GPIO_CONFIG_OUTPUT 0x02U + +#define RESET_STICKY_PWRBUT 0x04U + +#define SHPHLD_LONGPRESS_SHIP 0 +#define SHPHLD_LONGPRESS_DISABLE 1 +#define SHPHLD_LONGPRESS_RESET 2 + +struct mfd_npm2100_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec host_int_gpios; + gpio_flags_t host_int_flags; + gpio_pin_t pmic_int_pin; + gpio_flags_t pmic_int_flags; + gpio_flags_t shiphold_flags; + uint8_t shiphold_longpress; + uint8_t shiphold_current; + uint8_t shiphold_hibernate_wakeup; +}; + +struct mfd_npm2100_data { + const struct device *dev; + struct gpio_callback gpio_cb; + struct k_work work; + sys_slist_t callbacks; +}; + +struct event_reg_t { + uint8_t offset; + uint8_t mask; +}; + +static const struct event_reg_t event_reg[NPM2100_EVENT_MAX] = { + [NPM2100_EVENT_SYS_DIETEMP_WARN] = {0x00U, 0x01U}, + [NPM2100_EVENT_SYS_SHIPHOLD_FALL] = {0x00U, 0x02U}, + [NPM2100_EVENT_SYS_SHIPHOLD_RISE] = {0x00U, 0x04U}, + [NPM2100_EVENT_SYS_PGRESET_FALL] = {0x00U, 0x08U}, + [NPM2100_EVENT_SYS_PGRESET_RISE] = {0x00U, 0x10U}, + [NPM2100_EVENT_SYS_TIMER_EXPIRY] = {0x00U, 0x20U}, + [NPM2100_EVENT_ADC_VBAT_READY] = {0x01U, 0x01U}, + [NPM2100_EVENT_ADC_DIETEMP_READY] = {0x01U, 0x02U}, + [NPM2100_EVENT_ADC_DROOP_DETECT] = {0x01U, 0x04U}, + [NPM2100_EVENT_ADC_VOUT_READY] = {0x01U, 0x08U}, + [NPM2100_EVENT_GPIO0_FALL] = {0x02U, 0x01U}, + [NPM2100_EVENT_GPIO0_RISE] = {0x02U, 0x02U}, + [NPM2100_EVENT_GPIO1_FALL] = {0x02U, 0x04U}, + [NPM2100_EVENT_GPIO1_RISE] = {0x02U, 0x08U}, + [NPM2100_EVENT_BOOST_VBAT_WARN] = {0x03U, 0x01U}, + [NPM2100_EVENT_BOOST_VOUT_MIN] = {0x03U, 0x02U}, + [NPM2100_EVENT_BOOST_VOUT_WARN] = {0x03U, 0x04U}, + [NPM2100_EVENT_BOOST_VOUT_DPS] = {0x03U, 0x08U}, + [NPM2100_EVENT_BOOST_VOUT_OK] = {0x03U, 0x10U}, + [NPM2100_EVENT_LDOSW_OCP] = {0x04U, 0x01U}, + [NPM2100_EVENT_LDOSW_VINTFAIL] = {0x04U, 0x02U}, +}; + +static void gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct mfd_npm2100_data *data = CONTAINER_OF(cb, struct mfd_npm2100_data, gpio_cb); + const struct mfd_npm2100_config *config = data->dev->config; + + if (config->host_int_flags & GPIO_INT_LEVEL_ACTIVE) { + /* When using level irq, disable until it can be cleared in the work callback */ + gpio_pin_interrupt_configure_dt(&config->host_int_gpios, GPIO_INT_DISABLE); + } + + k_work_submit(&data->work); +} + +static void work_callback(struct k_work *work) +{ + struct mfd_npm2100_data *data = CONTAINER_OF(work, struct mfd_npm2100_data, work); + const struct mfd_npm2100_config *config = data->dev->config; + uint8_t buf[EVENTS_SIZE + 1U] = {EVENTS_SET}; + int ret; + + /* Read MAIN SET registers into buffer, leaving space for register address */ + ret = i2c_write_read_dt(&config->i2c, &buf[0], 1U, &buf[1], EVENTS_SIZE); + if (ret < 0) { + k_work_submit(&data->work); + goto enable_irq; + } + + for (int i = 0; i < NPM2100_EVENT_MAX; i++) { + if ((buf[event_reg[i].offset + 1U] & event_reg[i].mask) != 0U) { + gpio_fire_callbacks(&data->callbacks, data->dev, BIT(i)); + } + } + + /* Write read buffer back to clear registers to clear all processed events */ + buf[0] = EVENTS_CLR; + ret = i2c_write_dt(&config->i2c, buf, EVENTS_SIZE + 1U); + if (ret < 0) { + k_work_submit(&data->work); + goto enable_irq; + } + + /* Resubmit handler to queue if interrupt is still active */ + if (gpio_pin_get_dt(&config->host_int_gpios) != 0) { + k_work_submit(&data->work); + } + +enable_irq: + + if (config->host_int_flags & GPIO_INT_LEVEL_ACTIVE) { + /* Re-enable irq */ + gpio_pin_interrupt_configure_dt(&config->host_int_gpios, config->host_int_flags); + } +} + +static int config_pmic_int(const struct device *dev) +{ + const struct mfd_npm2100_config *config = dev->config; + uint8_t usage = GPIO_USAGE_INTHI; + + if (config->pmic_int_flags & GPIO_ACTIVE_LOW) { + usage = GPIO_USAGE_INTLO; + } + + /* Set specified PMIC pin to be interrupt output */ + int ret = i2c_reg_write_byte_dt(&config->i2c, GPIO_USAGE + config->pmic_int_pin, usage); + + if (ret < 0) { + return ret; + } + + /* Configure PMIC output pin */ + return i2c_reg_write_byte_dt(&config->i2c, GPIO_CONFIG + config->pmic_int_pin, + GPIO_CONFIG_OUTPUT); +} + +static int config_shphold(const struct device *dev) +{ + const struct mfd_npm2100_config *config = dev->config; + uint8_t reg; + int ret; + + if (config->shiphold_longpress != SHPHLD_LONGPRESS_SHIP) { + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_WRITESTICKY, RESET_STICKY_PWRBUT); + if (ret < 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_STROBESTICKY, 1U); + if (ret < 0) { + return ret; + } + + if (config->shiphold_longpress == SHPHLD_LONGPRESS_RESET) { + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_BUTTON, 0U); + if (ret < 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_PIN, 1U); + if (ret < 0) { + return ret; + } + } + } + + reg = config->shiphold_hibernate_wakeup ? WAKEUP_HIBERNATE_PIN : WAKEUP_HIBERNATE_NOPIN; + if ((config->shiphold_flags & GPIO_ACTIVE_HIGH) != 0U) { + reg |= WAKEUP_EDGE_RISING; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, SHPHLD_WAKEUP, reg); + if (ret < 0) { + return ret; + } + + if ((config->shiphold_flags & GPIO_PULL_UP) != 0U) { + reg = SHPHLD_RESISTOR_PULLUP; + } else if ((config->shiphold_flags & GPIO_PULL_DOWN) != 0U) { + reg = SHPHLD_RESISTOR_PULLDOWN; + } else { + reg = SHPHLD_RESISTOR_NONE; + } + if (config->shiphold_current != 0U) { + reg |= FIELD_PREP(SHPHLD_CURR_MASK, (config->shiphold_current - 1U)); + reg |= SHPHLD_PULL_ENABLE; + } + + return i2c_reg_write_byte_dt(&config->i2c, SHPHLD_SHPHLD, reg); +} + +static int mfd_npm2100_init(const struct device *dev) +{ + const struct mfd_npm2100_config *config = dev->config; + struct mfd_npm2100_data *mfd_data = dev->data; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + + mfd_data->dev = dev; + + ret = config_shphold(dev); + if (ret < 0) { + return ret; + } + + if (config->host_int_gpios.port == NULL) { + return 0; + } + + ret = config_pmic_int(dev); + if (ret < 0) { + return ret; + } + + /* Configure host interrupt GPIO */ + if (!gpio_is_ready_dt(&config->host_int_gpios)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->host_int_gpios, GPIO_INPUT); + if (ret < 0) { + return ret; + } + + gpio_init_callback(&mfd_data->gpio_cb, gpio_callback, BIT(config->host_int_gpios.pin)); + + ret = gpio_add_callback_dt(&config->host_int_gpios, &mfd_data->gpio_cb); + if (ret < 0) { + return ret; + } + + mfd_data->work.handler = work_callback; + + return gpio_pin_interrupt_configure_dt(&config->host_int_gpios, config->host_int_flags); +} + +int mfd_npm2100_set_timer(const struct device *dev, uint32_t time_ms, + enum mfd_npm2100_timer_mode mode) +{ + const struct mfd_npm2100_config *config = dev->config; + uint8_t buff[4] = {TIMER_TARGET}; + uint32_t ticks = (uint32_t)DIV_ROUND_CLOSEST(((uint64_t)time_ms * TIMER_PRESCALER_MUL), + TIMER_PRESCALER_DIV); + uint8_t timer_status; + int ret; + + if (ticks > TIMER_MAX) { + return -EINVAL; + } + + ret = i2c_reg_read_byte_dt(&config->i2c, TIMER_STATUS, &timer_status); + if (ret < 0) { + return ret; + } + + if (timer_status != TIMER_STATUS_IDLE) { + return -EBUSY; + } + + sys_put_be24(ticks, &buff[1]); + + ret = i2c_write_dt(&config->i2c, buff, sizeof(buff)); + if (ret < 0) { + return ret; + } + + return i2c_reg_write_byte_dt(&config->i2c, TIMER_CONFIG, mode); +} + +int mfd_npm2100_start_timer(const struct device *dev) +{ + const struct mfd_npm2100_config *config = dev->config; + + return i2c_reg_write_byte_dt(&config->i2c, TIMER_TASKS_START, 1U); +} + +int mfd_npm2100_reset(const struct device *dev) +{ + const struct mfd_npm2100_config *config = dev->config; + + return i2c_reg_write_byte_dt(&config->i2c, RESET_TASKS_RESET, 1U); +} + +int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms) +{ + const struct mfd_npm2100_config *config = dev->config; + int ret; + + if (time_ms > 0) { + ret = mfd_npm2100_set_timer(dev, time_ms, NPM2100_TIMER_MODE_WAKEUP); + if (ret < 0) { + return ret; + } + + ret = mfd_npm2100_start_timer(dev); + if (ret < 0) { + return ret; + } + } + + /* Ensure shiphold button is enabled so that wakeup will work */ + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_WRITESTICKY, 0); + if (ret < 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, RESET_STROBESTICKY, 1U); + if (ret < 0) { + return ret; + } + + return i2c_reg_write_byte_dt(&config->i2c, HIBERNATE_TASKS_HIBER, 1U); +} + +int mfd_npm2100_add_callback(const struct device *dev, struct gpio_callback *callback) +{ + const struct mfd_npm2100_config *config = dev->config; + struct mfd_npm2100_data *data = dev->data; + + /* Enable interrupts for specified events */ + for (int i = 0; i < NPM2100_EVENT_MAX; i++) { + if ((callback->pin_mask & BIT(i)) != 0U) { + /* Clear pending interrupt */ + int ret = i2c_reg_write_byte_dt( + &config->i2c, event_reg[i].offset + EVENTS_CLR, event_reg[i].mask); + + if (ret < 0) { + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->i2c, event_reg[i].offset + INTEN_SET, + event_reg[i].mask); + if (ret < 0) { + return ret; + } + } + } + + return gpio_manage_callback(&data->callbacks, callback, true); +} + +int mfd_npm2100_remove_callback(const struct device *dev, struct gpio_callback *callback) +{ + struct mfd_npm2100_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, false); +} + +#define MFD_NPM2100_DEFINE(inst) \ + static struct mfd_npm2100_data data##inst; \ + \ + static const struct mfd_npm2100_config config##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .host_int_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, host_int_gpios, {0}), \ + .host_int_flags = DT_INST_ENUM_IDX_OR(inst, host_int_type, 0) == 0 \ + ? GPIO_INT_EDGE_TO_ACTIVE \ + : GPIO_INT_LEVEL_ACTIVE, \ + .pmic_int_pin = DT_INST_PROP_OR(inst, pmic_int_pin, 0), \ + .pmic_int_flags = DT_INST_PROP_OR(inst, pmic_int_flags, 0), \ + .shiphold_flags = \ + DT_INST_PROP_OR(inst, shiphold_flags, (GPIO_ACTIVE_LOW | GPIO_PULL_UP)), \ + .shiphold_longpress = DT_INST_ENUM_IDX_OR(inst, shiphold_longpress, 0), \ + .shiphold_current = DT_INST_ENUM_IDX_OR(inst, shiphold_current, 0), \ + .shiphold_hibernate_wakeup = DT_INST_PROP_OR(inst, shiphold_hibernate_wakeup, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfd_npm2100_init, NULL, &data##inst, &config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_NPM2100_DEFINE) diff --git a/dts/bindings/mfd/nordic,npm2100.yaml b/dts/bindings/mfd/nordic,npm2100.yaml new file mode 100644 index 00000000000..e73399cf14b --- /dev/null +++ b/dts/bindings/mfd/nordic,npm2100.yaml @@ -0,0 +1,72 @@ +# Copyright (c) 2024, Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nPM2100 + +compatible: "nordic,npm2100" + +include: i2c-device.yaml + +properties: + reg: + required: true + + host-int-gpios: + type: phandle-array + description: Host pin for interrupt input + + host-int-type: + type: string + enum: + - "edge" + - "level" + default: "edge" + description: | + Using interrupt level triggering instead of edge triggering + can reduce power consumption on some platforms at the expense of irq latency. + + pmic-int-pin: + type: int + enum: + - 0 + - 1 + description: Pmic pin number for interrupt output + + pmic-int-flags: + type: int + description: | + GPIO flags for PMIC interrupt output + + shiphold-flags: + type: int + description: | + GPIO flags for shiphold button. + Defaults to active low with pull-up enabled. + + shiphold-hibernate-wakeup: + type: boolean + description: | + Enable shiphold button to trigger wakeup from hibernate state + + shiphold-longpress: + type: string + enum: + - "ship" + - "disable" + - "reset" + description: | + Configure behaviour of shiphold button. + ship: Enter ship mode if SHPHLD is pressed for 2 seconds + disable: SHPHLD button press has no effect + reset: Reset PMIC if SHPHLD is pressed for 10 seconds + + shiphold-current: + type: string + enum: + - "disable" + - "weak" + - "low" + - "moderate" + - "high" + description: | + Configure behaviour of shiphold pull-up current diff --git a/include/zephyr/drivers/mfd/npm2100.h b/include/zephyr/drivers/mfd/npm2100.h new file mode 100644 index 00000000000..8a45925af99 --- /dev/null +++ b/include/zephyr/drivers/mfd/npm2100.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_NPM2100_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_NPM2100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup mdf_interface_npm2100 MFD NPM2100 Interface + * @ingroup mfd_interfaces + * @{ + */ + +#include +#include + +#include +#include + +enum mfd_npm2100_event { + NPM2100_EVENT_SYS_DIETEMP_WARN, + NPM2100_EVENT_SYS_SHIPHOLD_FALL, + NPM2100_EVENT_SYS_SHIPHOLD_RISE, + NPM2100_EVENT_SYS_PGRESET_FALL, + NPM2100_EVENT_SYS_PGRESET_RISE, + NPM2100_EVENT_SYS_TIMER_EXPIRY, + NPM2100_EVENT_ADC_VBAT_READY, + NPM2100_EVENT_ADC_DIETEMP_READY, + NPM2100_EVENT_ADC_DROOP_DETECT, + NPM2100_EVENT_ADC_VOUT_READY, + NPM2100_EVENT_GPIO0_FALL, + NPM2100_EVENT_GPIO0_RISE, + NPM2100_EVENT_GPIO1_FALL, + NPM2100_EVENT_GPIO1_RISE, + NPM2100_EVENT_BOOST_VBAT_WARN, + NPM2100_EVENT_BOOST_VOUT_MIN, + NPM2100_EVENT_BOOST_VOUT_WARN, + NPM2100_EVENT_BOOST_VOUT_DPS, + NPM2100_EVENT_BOOST_VOUT_OK, + NPM2100_EVENT_LDOSW_OCP, + NPM2100_EVENT_LDOSW_VINTFAIL, + NPM2100_EVENT_MAX +}; + +enum mfd_npm2100_timer_mode { + NPM2100_TIMER_MODE_GENERAL_PURPOSE, + NPM2100_TIMER_MODE_WDT_RESET, + NPM2100_TIMER_MODE_WDT_POWER_CYCLE, + NPM2100_TIMER_MODE_WAKEUP, +}; + +/** + * @brief Write npm2100 timer register + * + * The timer tick resolution is 1/64 seconds. + * This function does not start the timer (see mfd_npm2100_start_timer()). + * + * @param dev npm2100 mfd device + * @param time_ms timer value in ms + * @param mode timer mode + * @retval 0 If successful + * @retval -EINVAL if time value is too large + * @retval -errno In case of any bus error (see i2c_write_dt()) + */ +int mfd_npm2100_set_timer(const struct device *dev, uint32_t time_ms, + enum mfd_npm2100_timer_mode mode); + +/** + * @brief Start npm2100 timer + * + * @param dev npm2100 mfd device + * @retval 0 If successful + * @retval -errno In case of any bus error (see i2c_write_dt()) + */ +int mfd_npm2100_start_timer(const struct device *dev); + +/** + * @brief npm2100 full power reset + * + * @param dev npm2100 mfd device + * @retval 0 If successful + * @retval -errno In case of any bus error (see i2c_write_dt()) + */ +int mfd_npm2100_reset(const struct device *dev); + +/** + * @brief npm2100 hibernate + * + * Enters low power state, and wakes after specified time or "shphld" pin signal. + * + * @param dev npm2100 mfd device + * @param time_ms timer value in ms. Set to 0 to disable timer. + * @retval 0 If successful + * @retval -EINVAL if time value is too large + * @retval -EBUSY if the timer is already in use. + * @retval -errno In case of any bus error (see i2c_write_dt()) + */ +int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms); + +/** + * @brief Add npm2100 event callback + * + * @param dev npm2100 mfd device + * @param callback callback + * @return 0 on success, -errno on failure + */ +int mfd_npm2100_add_callback(const struct device *dev, struct gpio_callback *callback); + +/** + * @brief Remove npm2100 event callback + * + * @param dev npm2100 mfd device + * @param callback callback + * @return 0 on success, -errno on failure + */ +int mfd_npm2100_remove_callback(const struct device *dev, struct gpio_callback *callback); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_NPM2100_H_ */