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 <andy.sinclair@nordicsemi.no>
This commit is contained in:
Andy Sinclair 2023-11-10 13:19:07 +00:00 committed by Fabio Baltieri
parent c19ba8ffe9
commit 04e18f093f
8 changed files with 36 additions and 45 deletions

View file

@ -3,8 +3,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/drivers/regulator.h>
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);
}
}

View file

@ -9,7 +9,6 @@
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/logging/log.h>
@ -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}), \
}; \
\

View file

@ -7,7 +7,6 @@
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/logging/log.h>
@ -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, \

View file

@ -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:

View file

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

View file

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

View file

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

View file

@ -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 = \