From 8c73db666c3b9dfbdf88c90f3c0379ffadc22f76 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 12 Jan 2023 11:02:06 +0100 Subject: [PATCH] drivers: regulator: npm1100: add initial support While nPM1100 is to be operated in fixed configuration for some applications, it has some degree of configuration via GPIOs. For example, mode (auto/PWM) can be configured via MODE pin. VBUS current can also be adjusted using ISET pin, even though there is no API yet to limit the PMIC input current. This patch adds a new regulator class driver for nPM1100 PMIC, so that it can be used with the standard regulator API when needed. Signed-off-by: Gerard Marull-Paretas --- drivers/regulator/CMakeLists.txt | 1 + drivers/regulator/Kconfig | 1 + drivers/regulator/Kconfig.npm1100 | 16 ++ drivers/regulator/regulator_npm1100.c | 137 ++++++++++++++++++ dts/bindings/regulator/nordic,npm1100.yaml | 41 ++++++ .../zephyr/dt-bindings/regulator/npm1100.h | 28 ++++ 6 files changed, 224 insertions(+) create mode 100644 drivers/regulator/Kconfig.npm1100 create mode 100644 drivers/regulator/regulator_npm1100.c create mode 100644 dts/bindings/regulator/nordic,npm1100.yaml create mode 100644 include/zephyr/dt-bindings/regulator/npm1100.h diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 8e9f3e7ef29..170fff41e72 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library() zephyr_library_sources(regulator_common.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FAKE regulator_fake.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FIXED regulator_fixed.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1100 regulator_npm1100.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 64d325c831a..d6aea0ef216 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -23,6 +23,7 @@ source "subsys/logging/Kconfig.template.log_config" source "drivers/regulator/Kconfig.fake" source "drivers/regulator/Kconfig.fixed" +source "drivers/regulator/Kconfig.npm1100" source "drivers/regulator/Kconfig.npm6001" source "drivers/regulator/Kconfig.pca9420" diff --git a/drivers/regulator/Kconfig.npm1100 b/drivers/regulator/Kconfig.npm1100 new file mode 100644 index 00000000000..56301a7beca --- /dev/null +++ b/drivers/regulator/Kconfig.npm1100 @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX -License-Identifier: Apache-2.0 + +config REGULATOR_NPM1100 + bool "nPM1100 PMIC regulator driver" + default y + depends on DT_HAS_NORDIC_NPM1100_ENABLED + help + Enable the Nordic nPM1100 PMIC regulator driver + +config REGULATOR_NPM1100_INIT_PRIORITY + int "nPM1100 regulator driver init priority" + default KERNEL_INIT_PRIORITY_DEVICE + depends on REGULATOR_NPM1100 + help + Init priority for the Nordic nPM1100 regulator driver. diff --git a/drivers/regulator/regulator_npm1100.c b/drivers/regulator/regulator_npm1100.c new file mode 100644 index 00000000000..52e92906cf5 --- /dev/null +++ b/drivers/regulator/regulator_npm1100.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_npm1100 + +#include + +#include +#include +#include + +struct regulator_npm1100_pconfig { + struct gpio_dt_spec iset; +}; + +struct regulator_npm1100_config { + struct regulator_common_config common; + struct gpio_dt_spec mode; +}; + +struct regulator_npm1100_data { + struct regulator_common_data data; +}; + +static int regulator_npm1100_set_mode(const struct device *dev, + regulator_mode_t mode) +{ + const struct regulator_npm1100_config *config = dev->config; + + if ((config->mode.port == NULL) || (mode > NPM1100_MODE_PWM)) { + return -ENOTSUP; + } + + return gpio_pin_set_dt(&config->mode, + mode == NPM1100_MODE_AUTO ? 0 : 1); +} + +static int regulator_npm1100_get_mode(const struct device *dev, + regulator_mode_t *mode) +{ + const struct regulator_npm1100_config *config = dev->config; + int ret; + + if (config->mode.port == NULL) { + return -ENOTSUP; + } + + ret = gpio_pin_get_dt(&config->mode); + if (ret < 0) { + return ret; + } + + *mode = (ret == 0) ? NPM1100_MODE_AUTO : NPM1100_MODE_PWM; + + return 0; +} + +static int regulator_npm1100_init(const struct device *dev) +{ + const struct regulator_npm1100_config *config = dev->config; + int ret; + + if (config->mode.port != NULL) { + if (!gpio_is_ready_dt(&config->mode)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->mode, + GPIO_INPUT | GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + } + + regulator_common_data_init(dev); + + return regulator_common_init(dev, true); +} + +static int regulator_npm1100_common_init(const struct device *dev) +{ + const struct regulator_npm1100_pconfig *config = dev->config; + + if (config->iset.port != NULL) { + int ret; + + if (!gpio_is_ready_dt(&config->iset)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->iset, + GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +static const struct regulator_driver_api api = { + .set_mode = regulator_npm1100_set_mode, + .get_mode = regulator_npm1100_get_mode, +}; + +#define REGULATOR_NPM1100_DEFINE_BUCK(node_id, id) \ + static struct regulator_npm1100_data data_##id; \ + \ + static const struct regulator_npm1100_config config_##id = { \ + .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ + .mode = GPIO_DT_SPEC_GET_OR(node_id, nordic_mode_gpios, {}), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, regulator_npm1100_init, NULL, &data_##id, \ + &config_##id, POST_KERNEL, \ + CONFIG_REGULATOR_NPM1100_INIT_PRIORITY, &api); + +#define REGULATOR_NPM1100_DEFINE_BUCK_COND(inst) \ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, buck)), \ + (REGULATOR_NPM1100_DEFINE_BUCK(DT_INST_CHILD(inst, buck), \ + buck##inst)), \ + ()) + +#define REGULATOR_NPM1100_DEFINE_ALL(inst) \ + static const struct regulator_npm1100_pconfig config_##inst = { \ + .iset = GPIO_DT_SPEC_INST_GET_OR(inst, nordic_iset_gpios, {}), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, regulator_npm1100_common_init, NULL, NULL, \ + &config_##inst, POST_KERNEL, \ + CONFIG_REGULATOR_NPM1100_INIT_PRIORITY, NULL); \ + \ + REGULATOR_NPM1100_DEFINE_BUCK_COND(inst) + +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NPM1100_DEFINE_ALL) diff --git a/dts/bindings/regulator/nordic,npm1100.yaml b/dts/bindings/regulator/nordic,npm1100.yaml new file mode 100644 index 00000000000..b70523cfadd --- /dev/null +++ b/dts/bindings/regulator/nordic,npm1100.yaml @@ -0,0 +1,41 @@ +# Copyright (c), 2023 Nordic Semiconductor ASA +# SPDX -License-Identifier: Apache-2.0 + +description: | + Nordic nPM1100 PMIC + + The PMIC has one buck converter. It needs to be defined as a child node, + strictly following the BUCK node name. For example: + + pmic { + compatible = "nordic,npm1100"; + + BUCK { + /* all properties for BUCK */ + }; + }; + + Note that only mode can be controlled (via GPIO pin MODE). + +compatible: "nordic,npm1100" + +include: base.yaml + +properties: + nordic,iset-gpios: + type: phandle-array + description: | + ISET control pin. + +child-binding: + properties: + nordic,mode-gpios: + type: phandle-array + description: | + MODE control pin. + + include: + - name: regulator.yaml + property-allowlist: + - regulator-allowed-modes + - regulator-initial-mode diff --git a/include/zephyr/dt-bindings/regulator/npm1100.h b/include/zephyr/dt-bindings/regulator/npm1100.h new file mode 100644 index 00000000000..3b0c02a4c0b --- /dev/null +++ b/include/zephyr/dt-bindings/regulator/npm1100.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NPM1100_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NPM1100_H_ + +/** + * @defgroup regulator_npm1100 NPM1100 Devicetree helpers. + * @ingroup regulator_interface + * @{ + */ + +/** + * @name NPM1100 Regulator modes + * @{ + */ +/** Automatic mode */ +#define NPM1100_MODE_AUTO 0 +/** PWM mode */ +#define NPM1100_MODE_PWM 1 +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_NPM1100_H_*/