1 /*
2 * Copyright 2019-2020 Peter Bigot Consulting, LLC
3 * Copyright 2022 Nordic Semiconductor ASA
4 * Copyright 2023 EPAM Systems
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT regulator_fixed
9
10 #include <stdint.h>
11
12 #include <zephyr/drivers/regulator.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/logging/log.h>
15
16 LOG_MODULE_REGISTER(regulator_fixed, CONFIG_REGULATOR_LOG_LEVEL);
17
18 struct regulator_fixed_config {
19 struct regulator_common_config common;
20 struct gpio_dt_spec enable;
21 };
22
23 struct regulator_fixed_data {
24 struct regulator_common_data common;
25 };
26
regulator_fixed_enable(const struct device * dev)27 static int regulator_fixed_enable(const struct device *dev)
28 {
29 const struct regulator_fixed_config *cfg = dev->config;
30 int ret;
31
32 if (!cfg->enable.port) {
33 return -ENOTSUP;
34 }
35
36 ret = gpio_pin_set_dt(&cfg->enable, 1);
37 if (ret < 0) {
38 return ret;
39 }
40
41 return 0;
42 }
43
regulator_fixed_disable(const struct device * dev)44 static int regulator_fixed_disable(const struct device *dev)
45 {
46 const struct regulator_fixed_config *cfg = dev->config;
47
48 if (!cfg->enable.port) {
49 return -ENOTSUP;
50 }
51
52 return gpio_pin_set_dt(&cfg->enable, 0);
53 }
54
regulator_fixed_count_voltages(const struct device * dev)55 static unsigned int regulator_fixed_count_voltages(const struct device *dev)
56 {
57 int32_t min_uv;
58
59 return (regulator_common_get_min_voltage(dev, &min_uv) < 0) ? 0U : 1U;
60 }
61
regulator_fixed_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)62 static int regulator_fixed_list_voltage(const struct device *dev,
63 unsigned int idx,
64 int32_t *volt_uv)
65 {
66 if (idx != 0) {
67 return -EINVAL;
68 }
69
70 if (regulator_common_get_min_voltage(dev, volt_uv) < 0) {
71 return -EINVAL;
72 }
73
74 return 0;
75 }
76
77 static const struct regulator_driver_api regulator_fixed_api = {
78 .enable = regulator_fixed_enable,
79 .disable = regulator_fixed_disable,
80 .count_voltages = regulator_fixed_count_voltages,
81 .list_voltage = regulator_fixed_list_voltage,
82 };
83
regulator_fixed_init(const struct device * dev)84 static int regulator_fixed_init(const struct device *dev)
85 {
86 const struct regulator_fixed_config *cfg = dev->config;
87
88 regulator_common_data_init(dev);
89
90 if (cfg->enable.port != NULL) {
91 if (!gpio_is_ready_dt(&cfg->enable)) {
92 LOG_ERR("GPIO port: %s not ready", cfg->enable.port->name);
93 return -ENODEV;
94 }
95
96 int ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT);
97
98 if (ret < 0) {
99 return ret;
100 }
101 }
102
103 return regulator_common_init(dev, false);
104 }
105
106 #define REGULATOR_FIXED_DEFINE(inst) \
107 BUILD_ASSERT(DT_INST_PROP_OR(inst, regulator_min_microvolt, 0) == \
108 DT_INST_PROP_OR(inst, regulator_max_microvolt, 0), \
109 "Regulator requires fixed voltages"); \
110 static struct regulator_fixed_data data##inst; \
111 \
112 static const struct regulator_fixed_config config##inst = { \
113 .common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst), \
114 .enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}), \
115 }; \
116 \
117 DEVICE_DT_INST_DEFINE(inst, regulator_fixed_init, NULL, &data##inst, \
118 &config##inst, POST_KERNEL, \
119 CONFIG_REGULATOR_FIXED_INIT_PRIORITY, \
120 ®ulator_fixed_api);
121
122 DT_INST_FOREACH_STATUS_OKAY(REGULATOR_FIXED_DEFINE)
123