zephyr/drivers/regulator/regulator_fixed.c
Gerard Marull-Paretas 7fa4776948 drivers: regulator: fixed: refactor initialization code.
In some cases, the enable pin may be already enabled by a previous
stage, e.g. bootloader. Therefore, it is not desirable to disable
the pin, as it could cause malfunctioning of the device. Refactor init
procedure so that we pick the right GPIO flags during the first
configuration stage.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2023-04-28 20:38:17 +02:00

106 lines
2.9 KiB
C

/*
* Copyright 2019-2020 Peter Bigot Consulting, LLC
* Copyright 2022 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT regulator_fixed
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/logging/log.h>
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;
};
struct regulator_fixed_data {
struct regulator_common_data common;
};
static int regulator_fixed_enable(const struct device *dev)
{
const struct regulator_fixed_config *cfg = dev->config;
int ret;
ret = gpio_pin_set_dt(&cfg->enable, 1);
if (ret < 0) {
return ret;
}
if (cfg->off_on_delay_us > 0U) {
k_sleep(K_USEC(cfg->off_on_delay_us));
}
return 0;
}
static int regulator_fixed_disable(const struct device *dev)
{
const struct regulator_fixed_config *cfg = dev->config;
return gpio_pin_set_dt(&cfg->enable, 0);
}
static const struct regulator_driver_api regulator_fixed_api = {
.enable = regulator_fixed_enable,
.disable = regulator_fixed_disable,
};
static int regulator_fixed_init(const struct device *dev)
{
const struct regulator_fixed_config *cfg = dev->config;
bool init_enabled;
int ret;
regulator_common_data_init(dev);
if (!device_is_ready(cfg->enable.port)) {
LOG_ERR("GPIO port: %s not ready", cfg->enable.port->name);
return -ENODEV;
}
init_enabled = regulator_common_is_init_enabled(dev);
if (init_enabled) {
ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT_ACTIVE);
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) {
return ret;
}
}
return regulator_common_init(dev, init_enabled);
}
#define REGULATOR_FIXED_DEFINE(inst) \
static struct regulator_fixed_data data##inst; \
\
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(inst, enable_gpios), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, regulator_fixed_init, NULL, &data##inst, \
&config##inst, POST_KERNEL, \
CONFIG_REGULATOR_FIXED_INIT_PRIORITY, \
&regulator_fixed_api);
DT_INST_FOREACH_STATUS_OKAY(REGULATOR_FIXED_DEFINE)