| /* |
| * 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, \ |
| ®ulator_fixed_api); |
| |
| DT_INST_FOREACH_STATUS_OKAY(REGULATOR_FIXED_DEFINE) |