1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2023, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <compiler.h>
8 #include <drivers/gpio.h>
9 #include <drivers/regulator.h>
10 #include <dt-bindings/gpio/gpio.h>
11 #include <kernel/delay.h>
12 #include <libfdt.h>
13 #include <trace.h>
14
15 static_assert(GPIO_LEVEL_HIGH == 1 && GPIO_LEVEL_LOW == 0);
16
17 /*
18 * struct regulator_gpio - GPIO controlled regulator
19 * @regulator: Preallocated regulator instance
20 * @enable_gpio: GPIO for the enable state of the regulator or NULL if always on
21 * @enable_delay: Time (in microsecond) for the regulator to get enabled
22 * @voltage_gpio: GPIO for the voltage level selection
23 * @levels_desc: Supported voltage levels description
24 * @voltage_levels_uv: 2 cells array supported voltage levels, increasing order
25 * @voltage_level_high: True if higher voltage level relates to GPIO state 1
26 */
27 struct regulator_gpio {
28 struct regulator regulator;
29 struct gpio *enable_gpio;
30 unsigned int enable_delay;
31 struct gpio *voltage_gpio;
32 struct regulator_voltages_desc levels_desc;
33 int voltage_levels_uv[2];
34 bool voltage_level_high;
35 };
36
regulator_priv(struct regulator * regulator)37 static struct regulator_gpio *regulator_priv(struct regulator *regulator)
38 {
39 return container_of(regulator, struct regulator_gpio, regulator);
40 }
41
regulator_gpio_set_state(struct regulator * regulator,bool enabled)42 static TEE_Result regulator_gpio_set_state(struct regulator *regulator,
43 bool enabled)
44 {
45 struct regulator_gpio *regu = regulator_priv(regulator);
46
47 if (regu->enable_gpio) {
48 if (enabled) {
49 gpio_set_value(regu->enable_gpio, GPIO_LEVEL_HIGH);
50 if (regu->enable_delay)
51 udelay(regu->enable_delay);
52 } else {
53 gpio_set_value(regu->enable_gpio, GPIO_LEVEL_LOW);
54 }
55 }
56
57 return TEE_SUCCESS;
58 }
59
regulator_gpio_read_state(struct regulator * regulator,bool * enabled)60 static TEE_Result regulator_gpio_read_state(struct regulator *regulator,
61 bool *enabled)
62 {
63 struct regulator_gpio *regu = regulator_priv(regulator);
64
65 if (regu->enable_gpio)
66 *enabled = gpio_get_value(regu->enable_gpio);
67 else
68 *enabled = true;
69
70 return TEE_SUCCESS;
71 }
72
regulator_gpio_set_voltage(struct regulator * regulator,int level_uv)73 static TEE_Result regulator_gpio_set_voltage(struct regulator *regulator,
74 int level_uv)
75 {
76 struct regulator_gpio *regu = regulator_priv(regulator);
77 enum gpio_level value = GPIO_LEVEL_LOW;
78
79 if (level_uv == regu->voltage_levels_uv[0])
80 value = GPIO_LEVEL_LOW;
81 else if (level_uv == regu->voltage_levels_uv[1])
82 value = GPIO_LEVEL_HIGH;
83 else
84 return TEE_ERROR_BAD_PARAMETERS;
85
86 if (!regu->voltage_level_high)
87 value = !value;
88
89 gpio_set_value(regu->voltage_gpio, value);
90
91 return TEE_SUCCESS;
92 }
93
regulator_gpio_read_voltage(struct regulator * regulator,int * level_uv)94 static TEE_Result regulator_gpio_read_voltage(struct regulator *regulator,
95 int *level_uv)
96 {
97 struct regulator_gpio *regu = regulator_priv(regulator);
98 enum gpio_level value = gpio_get_value(regu->voltage_gpio);
99
100 if (!regu->voltage_level_high)
101 value = !value;
102
103 *level_uv = regu->voltage_levels_uv[value];
104
105 return TEE_SUCCESS;
106 }
107
regulator_gpio_voltages(struct regulator * regulator,struct regulator_voltages_desc ** desc,const int ** levels)108 static TEE_Result regulator_gpio_voltages(struct regulator *regulator,
109 struct regulator_voltages_desc **desc,
110 const int **levels)
111 {
112 struct regulator_gpio *regu = regulator_priv(regulator);
113
114 *desc = ®u->levels_desc;
115 *levels = regu->voltage_levels_uv;
116
117 return TEE_SUCCESS;
118 }
119
120 static const struct regulator_ops regulator_gpio_ops = {
121 .set_state = regulator_gpio_set_state,
122 .get_state = regulator_gpio_read_state,
123 .set_voltage = regulator_gpio_set_voltage,
124 .get_voltage = regulator_gpio_read_voltage,
125 .supported_voltages = regulator_gpio_voltages,
126 };
127
get_enable_gpio(const void * fdt,int node,struct regulator_gpio * regu)128 static TEE_Result get_enable_gpio(const void *fdt, int node,
129 struct regulator_gpio *regu)
130 {
131 TEE_Result res = TEE_ERROR_GENERIC;
132 const fdt32_t *cuint = NULL;
133 struct gpio *gpio = NULL;
134
135 res = gpio_dt_get_by_index(fdt, node, 0, "enable", &gpio);
136 if (res == TEE_ERROR_ITEM_NOT_FOUND) {
137 regu->enable_gpio = NULL;
138
139 return TEE_SUCCESS;
140 }
141 if (res)
142 return res;
143
144 /* Override active level phandle flag, as per DT bindings */
145 if (dt_have_prop(fdt, node, "enable-active-high"))
146 gpio->dt_flags &= ~GPIO_ACTIVE_LOW;
147 else
148 gpio->dt_flags |= GPIO_ACTIVE_LOW;
149
150 /* Override open drain/open source phandle flag, as per DT bindings */
151 if (dt_have_prop(fdt, node, "gpio-open-drain"))
152 gpio->dt_flags |= GPIO_LINE_OPEN_DRAIN;
153 else
154 gpio->dt_flags &= ~GPIO_LINE_OPEN_DRAIN;
155
156 cuint = fdt_getprop(fdt, node, "startup-delay-us", NULL);
157 if (cuint)
158 regu->enable_delay = fdt32_to_cpu(*cuint);
159
160 /* Low level initialisation with updated dt_flags */
161 res = gpio_configure(gpio, GPIO_ASIS);
162 if (res)
163 return res;
164
165 /* Configure output, don't change level */
166 gpio_set_direction(gpio, GPIO_DIR_OUT);
167
168 regu->enable_gpio = gpio;
169
170 return TEE_SUCCESS;
171 }
172
get_voltage_level_gpio(const void * fdt,int node,struct regulator_gpio * regu)173 static TEE_Result get_voltage_level_gpio(const void *fdt, int node,
174 struct regulator_gpio *regu)
175 {
176 TEE_Result res = TEE_ERROR_GENERIC;
177 const fdt32_t *cuint = NULL;
178 enum gpio_flags gpios_state = GPIO_OUT_HIGH;
179 struct gpio *gpio = NULL;
180 int level0 = 0;
181 int level1 = 0;
182 int len = 0;
183
184 cuint = fdt_getprop(fdt, node, "gpios-states", NULL);
185 if (cuint && *cuint == 0)
186 gpios_state = GPIO_OUT_LOW;
187
188 res = gpio_dt_cfg_by_index(fdt, node, 0, NULL, gpios_state, &gpio);
189 if (res)
190 return res;
191
192 /*
193 * DT bindings allows more than 1 GPIO to control more than
194 * 2 voltage levels. As it's not used so far in known platforms
195 * this implementation is simplified to support only 2 voltage
196 * levels controlled with a single GPIO.
197 */
198 if (gpio_dt_cfg_by_index(fdt, node, 1, NULL, GPIO_OUT_HIGH, &gpio) !=
199 TEE_ERROR_ITEM_NOT_FOUND) {
200 EMSG("Multiple GPIOs not supported for level control");
201 return TEE_ERROR_GENERIC;
202 }
203
204 cuint = fdt_getprop(fdt, node, "states", &len);
205 if (!cuint || len != 4 * sizeof(fdt32_t)) {
206 EMSG("Node %s expects 2 levels from property \"states\"",
207 fdt_get_name(fdt, node, NULL));
208 return TEE_ERROR_GENERIC;
209 }
210
211 if (fdt32_to_cpu(*(cuint + 1))) {
212 assert(!fdt32_to_cpu(*(cuint + 3)));
213 level1 = fdt32_to_cpu(*(cuint));
214 level0 = fdt32_to_cpu(*(cuint + 2));
215 } else {
216 assert(fdt32_to_cpu(*(cuint + 3)) == 1);
217 level0 = fdt32_to_cpu(*(cuint));
218 level1 = fdt32_to_cpu(*(cuint + 2));
219 }
220
221 /* Get the 2 supported levels in increasing order */
222 regu->levels_desc.type = VOLTAGE_TYPE_FULL_LIST;
223 regu->levels_desc.num_levels = 2;
224 if (level0 < level1) {
225 regu->voltage_levels_uv[0] = level0;
226 regu->voltage_levels_uv[1] = level1;
227 regu->voltage_level_high = true;
228 } else {
229 regu->voltage_levels_uv[0] = level1;
230 regu->voltage_levels_uv[1] = level0;
231 regu->voltage_level_high = false;
232 }
233
234 regu->voltage_gpio = gpio;
235
236 return TEE_SUCCESS;
237 }
238
regulator_gpio_probe(const void * fdt,int node,const void * compat_data __unused)239 static TEE_Result regulator_gpio_probe(const void *fdt, int node,
240 const void *compat_data __unused)
241 {
242 TEE_Result res = TEE_ERROR_GENERIC;
243 struct regulator_gpio *regu = NULL;
244 struct regu_dt_desc desc = { };
245 const char *supply_name = NULL;
246 const char *type = NULL;
247 char *regu_name = NULL;
248
249 regu_name = (char *)fdt_get_name(fdt, node, NULL);
250
251 type = fdt_getprop(fdt, node, "regulator-type", NULL);
252 if (type && strcmp(type, "voltage")) {
253 EMSG("Regulator node %s: type \"%s\" not supported",
254 regu_name, type);
255 res = TEE_ERROR_GENERIC;
256 goto err;
257 }
258
259 regu = calloc(1, sizeof(*regu));
260 if (!regu) {
261 res = TEE_ERROR_OUT_OF_MEMORY;
262 goto err;
263 }
264
265 res = get_enable_gpio(fdt, node, regu);
266 if (res)
267 goto err;
268
269 res = get_voltage_level_gpio(fdt, node, regu);
270 if (res)
271 goto err;
272
273 if (fdt_getprop(fdt, node, "vin-supply", NULL))
274 supply_name = "vin";
275
276 desc = (struct regu_dt_desc){
277 .name = regu_name,
278 .ops = ®ulator_gpio_ops,
279 .supply_name = supply_name,
280 .regulator = ®u->regulator,
281 };
282
283 res = regulator_dt_register(fdt, node, node, &desc);
284 if (res) {
285 EMSG("Can't register regulator %s: %#"PRIx32, regu_name, res);
286 goto err;
287 }
288
289 return TEE_SUCCESS;
290
291 err:
292 free(regu);
293
294 return res;
295 }
296
297 static const struct dt_device_match regulator_gpio_match_table[] = {
298 { .compatible = "regulator-gpio" },
299 { }
300 };
301
302 DEFINE_DT_DRIVER(regulator_gpio_dt_driver) = {
303 .name = "regulator-gpio",
304 .match_table = regulator_gpio_match_table,
305 .probe = regulator_gpio_probe,
306 };
307