From 04e18f093fde6ed2671f52c3f373edf546259783 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 10 Nov 2023 13:19:07 +0000 Subject: [PATCH] drivers: regulator: Added startup and off/on delay to common driver A configurable delay during regulator switch on is currently only supported by the GPIO and fixed regulator drivers. This functionality has been moved to the common driver, so it can be easily added to any regulator driver. Signed-off-by: Andy Sinclair --- drivers/regulator/regulator_common.c | 22 ++++++++++++++----- drivers/regulator/regulator_fixed.c | 15 ------------- drivers/regulator/regulator_gpio.c | 11 ---------- .../regulator/nordic,npm1300-regulator.yaml | 2 ++ dts/bindings/regulator/regulator-fixed.yaml | 12 ++-------- dts/bindings/regulator/regulator-gpio.yaml | 5 +---- dts/bindings/regulator/regulator.yaml | 8 +++++++ include/zephyr/drivers/regulator.h | 6 +++++ 8 files changed, 36 insertions(+), 45 deletions(-) diff --git a/drivers/regulator/regulator_common.c b/drivers/regulator/regulator_common.c index adbacddac12..7f33040d2d9 100644 --- a/drivers/regulator/regulator_common.c +++ b/drivers/regulator/regulator_common.c @@ -3,8 +3,20 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include +static void regulator_delay(uint32_t delay_us) +{ + if (delay_us > 0U) { +#ifdef CONFIG_MULTITHREADING + k_sleep(K_USEC(delay_us)); +#else + k_busy_wait(delay_us); +#endif + } +} + void regulator_common_data_init(const struct device *dev) { struct regulator_common_data *data = dev->data; @@ -67,6 +79,7 @@ int regulator_common_init(const struct device *dev, bool is_enabled) return ret; } + regulator_delay(config->startup_delay_us); data->refcnt++; } @@ -94,12 +107,11 @@ int regulator_enable(const struct device *dev) (void)k_mutex_lock(&data->lock, K_FOREVER); #endif - data->refcnt++; - - if (data->refcnt == 1) { + if (data->refcnt == 0) { ret = api->enable(dev); - if (ret < 0) { - data->refcnt--; + if (ret == 0) { + data->refcnt++; + regulator_delay(config->off_on_delay_us); } } diff --git a/drivers/regulator/regulator_fixed.c b/drivers/regulator/regulator_fixed.c index 4526b6d2378..c0b58273987 100644 --- a/drivers/regulator/regulator_fixed.c +++ b/drivers/regulator/regulator_fixed.c @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -18,8 +17,6 @@ LOG_MODULE_REGISTER(regulator_fixed, CONFIG_REGULATOR_LOG_LEVEL); struct regulator_fixed_config { struct regulator_common_config common; - uint32_t startup_delay_us; - uint32_t off_on_delay_us; struct gpio_dt_spec enable; }; @@ -41,14 +38,6 @@ static int regulator_fixed_enable(const struct device *dev) return ret; } - if (cfg->off_on_delay_us > 0U) { -#ifdef CONFIG_MULTITHREADING - k_sleep(K_USEC(cfg->off_on_delay_us)); -#else - k_busy_wait(cfg->off_on_delay_us); -#endif - } - return 0; } @@ -113,8 +102,6 @@ static int regulator_fixed_init(const struct device *dev) if (ret < 0) { return ret; } - - k_busy_wait(cfg->startup_delay_us); } else { ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT_INACTIVE); if (ret < 0) { @@ -134,8 +121,6 @@ static int regulator_fixed_init(const struct device *dev) \ static const struct regulator_fixed_config config##inst = { \ .common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst), \ - .startup_delay_us = DT_INST_PROP(inst, startup_delay_us), \ - .off_on_delay_us = DT_INST_PROP(inst, off_on_delay_us), \ .enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}), \ }; \ \ diff --git a/drivers/regulator/regulator_gpio.c b/drivers/regulator/regulator_gpio.c index e752a9ad457..49d373897b3 100644 --- a/drivers/regulator/regulator_gpio.c +++ b/drivers/regulator/regulator_gpio.c @@ -7,7 +7,6 @@ #include -#include #include #include #include @@ -24,7 +23,6 @@ struct regulator_gpio_config { uint8_t states_cnt; const struct gpio_dt_spec enable; - int32_t startup_delay_us; }; struct regulator_gpio_data { @@ -73,14 +71,6 @@ static int regulator_gpio_enable(const struct device *dev) return ret; } - if (cfg->startup_delay_us > 0U) { -#ifdef CONFIG_MULTITHREADING - k_sleep(K_USEC(cfg->startup_delay_us)); -#else - k_busy_wait(cfg->startup_delay_us); -#endif - } - return 0; } @@ -233,7 +223,6 @@ static int regulator_gpio_init(const struct device *dev) .enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}), \ .states = ((const int[])DT_INST_PROP(inst, states)), \ .states_cnt = DT_INST_PROP_LEN(inst, states) / 2, \ - .startup_delay_us = DT_INST_PROP_OR(inst, startup_delay_us, 0), \ }; \ DEVICE_DT_INST_DEFINE(inst, regulator_gpio_init, NULL, &data##inst, &config##inst, \ POST_KERNEL, CONFIG_REGULATOR_GPIO_INIT_PRIORITY, \ diff --git a/dts/bindings/regulator/nordic,npm1300-regulator.yaml b/dts/bindings/regulator/nordic,npm1300-regulator.yaml index cbd62671f15..c5364a49fe0 100644 --- a/dts/bindings/regulator/nordic,npm1300-regulator.yaml +++ b/dts/bindings/regulator/nordic,npm1300-regulator.yaml @@ -60,6 +60,8 @@ child-binding: - regulator-initial-mode - regulator-min-microamp - regulator-max-microamp + - startup-delay-us + - off-on-delay-us properties: retention-microvolt: diff --git a/dts/bindings/regulator/regulator-fixed.yaml b/dts/bindings/regulator/regulator-fixed.yaml index 1033d333f08..4f3236d8c6c 100644 --- a/dts/bindings/regulator/regulator-fixed.yaml +++ b/dts/bindings/regulator/regulator-fixed.yaml @@ -13,6 +13,8 @@ include: - regulator-always-on - regulator-min-microvolt - regulator-max-microvolt + - startup-delay-us + - off-on-delay-us compatible: "regulator-fixed" @@ -29,13 +31,3 @@ properties: provide the GPIO polarity and open-drain status in the phandle selector. The Linux enable-active-high and gpio-open-drain properties are not valid for Zephyr devicetree files. - - startup-delay-us: - type: int - default: 0 - description: Startup time, in microseconds - - off-on-delay-us: - type: int - default: 0 - description: Off delay time, in microseconds diff --git a/dts/bindings/regulator/regulator-gpio.yaml b/dts/bindings/regulator/regulator-gpio.yaml index aa7aeb44eee..15c419a0043 100644 --- a/dts/bindings/regulator/regulator-gpio.yaml +++ b/dts/bindings/regulator/regulator-gpio.yaml @@ -34,6 +34,7 @@ include: - regulator-max-microvolt - regulator-always-on - regulator-boot-on + - startup-delay-us compatible: "regulator-gpio" @@ -70,7 +71,3 @@ properties: Example: enable-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; - - startup-delay-us: - type: int - description: startup time in microseconds diff --git a/dts/bindings/regulator/regulator.yaml b/dts/bindings/regulator/regulator.yaml index 067133aa97e..167355d9224 100644 --- a/dts/bindings/regulator/regulator.yaml +++ b/dts/bindings/regulator/regulator.yaml @@ -256,3 +256,11 @@ properties: description: | Maximum difference between current and target voltages that can be changed safely in a single step. + + startup-delay-us: + type: int + description: Startup time, in microseconds + + off-on-delay-us: + type: int + description: Off to on delay time, in microseconds diff --git a/include/zephyr/drivers/regulator.h b/include/zephyr/drivers/regulator.h index 77dd6d76b60..bad9de28239 100644 --- a/include/zephyr/drivers/regulator.h +++ b/include/zephyr/drivers/regulator.h @@ -140,6 +140,10 @@ struct regulator_common_config { int32_t min_ua; /** Maximum allowed current, in microamps. */ int32_t max_ua; + /** Startup delay, in microseconds. */ + uint32_t startup_delay_us; + /** Off to on delay, in microseconds. */ + uint32_t off_on_delay_us; /** Allowed modes */ const regulator_mode_t *allowed_modes; /** Number of allowed modes */ @@ -167,6 +171,8 @@ struct regulator_common_config { INT32_MIN), \ .max_ua = DT_PROP_OR(node_id, regulator_max_microamp, \ INT32_MAX), \ + .startup_delay_us = DT_PROP_OR(node_id, startup_delay_us, 0), \ + .off_on_delay_us = DT_PROP_OR(node_id, off_on_delay_us, 0), \ .allowed_modes = (const regulator_mode_t []) \ DT_PROP_OR(node_id, regulator_allowed_modes, {}), \ .allowed_modes_cnt = \