1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-09-23 GuEe-GUI first version
9 */
10
11 #include <dt-bindings/pin/state.h>
12
13 #include "regulator_dm.h"
14
15 struct regulator_gpio_state
16 {
17 rt_uint32_t value;
18 rt_uint32_t gpios;
19 };
20
21 struct regulator_gpio_desc
22 {
23 rt_base_t pin;
24 rt_uint32_t flags;
25 };
26
27 struct regulator_gpio
28 {
29 struct rt_regulator_node parent;
30
31 rt_base_t enable_pin;
32
33 rt_size_t pins_nr;
34 struct regulator_gpio_desc *pins_desc;
35
36 int state;
37 rt_size_t states_nr;
38 struct regulator_gpio_state *states;
39
40 const char *input_supply;
41 rt_uint32_t startup_delay;
42 rt_uint32_t off_on_delay;
43 rt_bool_t enabled_at_boot;
44 struct rt_regulator_param param;
45 };
46
47 #define raw_to_regulator_gpio(raw) rt_container_of(raw, struct regulator_gpio, parent)
48
regulator_gpio_enable(struct rt_regulator_node * reg_np)49 static rt_err_t regulator_gpio_enable(struct rt_regulator_node *reg_np)
50 {
51 struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
52 struct rt_regulator_param *param = &rg->param;
53
54 if (param->always_on)
55 {
56 return RT_EOK;
57 }
58
59 if (rg->enable_pin >= 0)
60 {
61 rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT);
62 rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_HIGH : PIN_LOW);
63 }
64
65 return RT_EOK;
66 }
67
regulator_gpio_disable(struct rt_regulator_node * reg_np)68 static rt_err_t regulator_gpio_disable(struct rt_regulator_node *reg_np)
69 {
70 struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
71 struct rt_regulator_param *param = &rg->param;
72
73 if (param->always_on)
74 {
75 return RT_EOK;
76 }
77
78 if (rg->enable_pin >= 0)
79 {
80 rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT);
81 rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_LOW : PIN_HIGH);
82 }
83
84 return RT_EOK;
85 }
86
regulator_gpio_is_enabled(struct rt_regulator_node * reg_np)87 static rt_bool_t regulator_gpio_is_enabled(struct rt_regulator_node *reg_np)
88 {
89 struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
90 struct rt_regulator_param *param = &rg->param;
91
92 if (param->always_on)
93 {
94 return RT_TRUE;
95 }
96
97 if (rg->enable_pin >= 0)
98 {
99 rt_uint8_t active_val = param->enable_active_high ? PIN_LOW : PIN_HIGH;
100
101 rt_pin_mode(rg->enable_pin, PIN_MODE_INPUT);
102 return rt_pin_read(rg->enable_pin) == active_val;
103 }
104
105 return RT_TRUE;
106 }
107
regulator_gpio_set_voltage(struct rt_regulator_node * reg_np,int min_uvolt,int max_uvolt)108 static rt_err_t regulator_gpio_set_voltage(struct rt_regulator_node *reg_np,
109 int min_uvolt, int max_uvolt)
110 {
111 int target = 0, best_val = RT_REGULATOR_UVOLT_INVALID;
112 struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
113
114 for (int i = 0; i < rg->states_nr; ++i)
115 {
116 struct regulator_gpio_state *state = &rg->states[i];
117
118 if (state->value < best_val &&
119 state->value >= min_uvolt &&
120 state->value <= max_uvolt)
121 {
122 target = state->gpios;
123 best_val = state->value;
124 }
125 }
126
127 if (best_val == RT_REGULATOR_UVOLT_INVALID)
128 {
129 return -RT_EINVAL;
130 }
131
132 for (int i = 0; i < rg->pins_nr; ++i)
133 {
134 int state = (target >> i) & 1;
135 struct regulator_gpio_desc *gpiod = &rg->pins_desc[i];
136
137 rt_pin_mode(gpiod->pin, PIN_MODE_OUTPUT);
138 rt_pin_write(gpiod->pin, gpiod->flags == PIND_OUT_HIGH ? state : !state);
139 }
140
141 rg->state = target;
142
143 return RT_EOK;
144 }
145
regulator_gpio_get_voltage(struct rt_regulator_node * reg_np)146 static int regulator_gpio_get_voltage(struct rt_regulator_node *reg_np)
147 {
148 struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
149
150 for (int i = 0; i < rg->states_nr; ++i)
151 {
152 if (rg->states[i].gpios == rg->state)
153 {
154 return rg->states[i].value;
155 }
156 }
157
158 return -RT_EINVAL;
159 }
160
161 static const struct rt_regulator_ops regulator_gpio_ops =
162 {
163 .enable = regulator_gpio_enable,
164 .disable = regulator_gpio_disable,
165 .is_enabled = regulator_gpio_is_enabled,
166 .set_voltage = regulator_gpio_set_voltage,
167 .get_voltage = regulator_gpio_get_voltage,
168 };
169
regulator_gpio_probe(struct rt_platform_device * pdev)170 static rt_err_t regulator_gpio_probe(struct rt_platform_device *pdev)
171 {
172 rt_err_t err;
173 struct rt_device *dev = &pdev->parent;
174 struct regulator_gpio *rg = rt_calloc(1, sizeof(*rg));
175 struct rt_regulator_node *rgp;
176
177 if (!rg)
178 {
179 return -RT_ENOMEM;
180 }
181
182 regulator_ofw_parse(dev->ofw_node, &rg->param);
183
184 rgp = &rg->parent;
185 rgp->supply_name = rg->param.name;
186 rgp->ops = ®ulator_gpio_ops;
187 rgp->param = &rg->param;
188 rgp->dev = &pdev->parent;
189
190 rt_dm_dev_prop_read_u32(dev, "startup-delay-us", &rg->startup_delay);
191 rt_dm_dev_prop_read_u32(dev, "off-on-delay-us", &rg->off_on_delay);
192
193 /* GPIO flags are ignored, we check by enable-active-high */
194 rg->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL);
195
196 if (rg->enable_pin < 0 && rg->enable_pin != PIN_NONE)
197 {
198 err = rg->enable_pin;
199 goto _fail;
200 }
201
202 rg->pins_nr = rt_pin_get_named_pin_count(dev, "gpios");
203
204 if (rg->pins_nr > 0)
205 {
206 rg->pins_desc = rt_malloc(sizeof(*rg->pins_desc) * rg->pins_nr);
207
208 if (!rg->pins_desc)
209 {
210 err = -RT_ENOMEM;
211
212 goto _fail;
213 }
214
215 for (int i = 0; i < rg->pins_nr; ++i)
216 {
217 rt_uint32_t val;
218 struct regulator_gpio_desc *gpiod = &rg->pins_desc[i];
219
220 gpiod->pin = rt_pin_get_named_pin(dev, RT_NULL, i, RT_NULL, RT_NULL);
221
222 if (gpiod->pin < 0)
223 {
224 err = gpiod->pin;
225 goto _fail;
226 }
227
228 if (rt_dm_dev_prop_read_u32_index(dev, "gpios-states", i, &val) < 0)
229 {
230 gpiod->flags = PIND_OUT_HIGH;
231 }
232 else
233 {
234 gpiod->flags = val ? PIND_OUT_HIGH : PIND_OUT_LOW;
235 }
236
237 if (gpiod->flags == PIND_OUT_HIGH)
238 {
239 rg->state |= 1 << i;
240 }
241 }
242 }
243
244 rg->states_nr = rt_dm_dev_prop_count_of_u32(dev, "states") / 2;
245
246 if (rg->states_nr < 0)
247 {
248 err = -RT_EIO;
249
250 goto _fail;
251 }
252
253 rg->states = rt_malloc(sizeof(*rg->states) * rg->states_nr);
254
255 if (!rg->states)
256 {
257 err = -RT_ENOMEM;
258
259 goto _fail;
260 }
261
262 for (int i = 0; i < rg->states_nr; ++i)
263 {
264 rt_dm_dev_prop_read_u32_index(dev, "states", i * 2, &rg->states[i].value);
265 rt_dm_dev_prop_read_u32_index(dev, "states", i * 2 + 1, &rg->states[i].gpios);
266 }
267
268 if ((err = rt_regulator_register(rgp)))
269 {
270 goto _fail;
271 }
272
273 return RT_EOK;
274
275 _fail:
276 if (rg->pins_desc)
277 {
278 rt_free(rg->pins_desc);
279 }
280 if (rg->states)
281 {
282 rt_free(rg->states);
283 }
284 rt_free(rg);
285
286 return err;
287 }
288
289 static const struct rt_ofw_node_id regulator_gpio_ofw_ids[] =
290 {
291 { .compatible = "regulator-gpio" },
292 { /* sentinel */ }
293 };
294
295 static struct rt_platform_driver regulator_gpio_driver =
296 {
297 .name = "regulator-gpio",
298 .ids = regulator_gpio_ofw_ids,
299
300 .probe = regulator_gpio_probe,
301 };
302
regulator_gpio_register(void)303 static int regulator_gpio_register(void)
304 {
305 rt_platform_driver_register(®ulator_gpio_driver);
306
307 return 0;
308 }
309 INIT_SUBSYS_EXPORT(regulator_gpio_register);
310