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 gpio_set_direction(gpio, GPIO_DIR_OUT);
161
162 regu->enable_gpio = gpio;
163
164 return TEE_SUCCESS;
165 }
166
get_voltage_level_gpio(const void * fdt,int node,struct regulator_gpio * regu)167 static TEE_Result get_voltage_level_gpio(const void *fdt, int node,
168 struct regulator_gpio *regu)
169 {
170 TEE_Result res = TEE_ERROR_GENERIC;
171 const fdt32_t *cuint = NULL;
172 struct gpio *gpio = NULL;
173 void *gpio_ref = &gpio;
174 int level0 = 0;
175 int level1 = 0;
176 int len = 0;
177
178 res = dt_driver_device_from_node_idx_prop("gpios", fdt, node, 0,
179 DT_DRIVER_GPIO, gpio_ref);
180 if (res)
181 return res;
182
183 /*
184 * DT bindings allows more than 1 GPIO to control more than
185 * 2 voltage levels. As it's not used so far in known platforms
186 * this implementation is simplified to support only 2 voltage
187 * levels controlled with a single GPIO.
188 */
189 if (dt_driver_device_from_node_idx_prop("gpios", fdt, node, 1,
190 DT_DRIVER_GPIO, gpio_ref) !=
191 TEE_ERROR_ITEM_NOT_FOUND) {
192 EMSG("Multiple GPIOs not supported for level control");
193 return TEE_ERROR_GENERIC;
194 }
195
196 cuint = fdt_getprop(fdt, node, "states", &len);
197 if (!cuint || len != 4 * sizeof(fdt32_t)) {
198 EMSG("Node %s expects 2 levels from property \"states\"",
199 fdt_get_name(fdt, node, NULL));
200 return TEE_ERROR_GENERIC;
201 }
202
203 if (fdt32_to_cpu(*(cuint + 1))) {
204 assert(!fdt32_to_cpu(*(cuint + 3)));
205 level1 = fdt32_to_cpu(*(cuint));
206 level0 = fdt32_to_cpu(*(cuint + 2));
207 } else {
208 assert(fdt32_to_cpu(*(cuint + 3)) == 1);
209 level0 = fdt32_to_cpu(*(cuint));
210 level1 = fdt32_to_cpu(*(cuint + 2));
211 }
212
213 /* Get the 2 supported levels in increasing order */
214 regu->levels_desc.type = VOLTAGE_TYPE_FULL_LIST;
215 regu->levels_desc.num_levels = 2;
216 if (level0 < level1) {
217 regu->voltage_levels_uv[0] = level0;
218 regu->voltage_levels_uv[1] = level1;
219 regu->voltage_level_high = true;
220 } else {
221 regu->voltage_levels_uv[0] = level1;
222 regu->voltage_levels_uv[1] = level0;
223 regu->voltage_level_high = false;
224 }
225
226 gpio_set_direction(gpio, GPIO_DIR_OUT);
227
228 regu->voltage_gpio = gpio;
229
230 return TEE_SUCCESS;
231 }
232
regulator_gpio_probe(const void * fdt,int node,const void * compat_data __unused)233 static TEE_Result regulator_gpio_probe(const void *fdt, int node,
234 const void *compat_data __unused)
235 {
236 TEE_Result res = TEE_ERROR_GENERIC;
237 struct regulator_gpio *regu = NULL;
238 struct regu_dt_desc desc = { };
239 const char *supply_name = NULL;
240 const char *type = NULL;
241 char *regu_name = NULL;
242
243 regu_name = (char *)fdt_get_name(fdt, node, NULL);
244
245 type = fdt_getprop(fdt, node, "regulator-type", NULL);
246 if (type && strcmp(type, "voltage")) {
247 EMSG("Regulator node %s: type \"%s\" not supported",
248 regu_name, type);
249 res = TEE_ERROR_GENERIC;
250 goto err;
251 }
252
253 regu = calloc(1, sizeof(*regu));
254 if (!regu) {
255 res = TEE_ERROR_OUT_OF_MEMORY;
256 goto err;
257 }
258
259 res = get_enable_gpio(fdt, node, regu);
260 if (res)
261 goto err;
262
263 res = get_voltage_level_gpio(fdt, node, regu);
264 if (res)
265 goto err;
266
267 if (fdt_getprop(fdt, node, "vin-supply", NULL))
268 supply_name = "vin";
269
270 desc = (struct regu_dt_desc){
271 .name = regu_name,
272 .ops = ®ulator_gpio_ops,
273 .supply_name = supply_name,
274 .regulator = ®u->regulator,
275 };
276
277 res = regulator_dt_register(fdt, node, node, &desc);
278 if (res) {
279 EMSG("Can't register regulator %s: %#"PRIx32, regu_name, res);
280 goto err;
281 }
282
283 return TEE_SUCCESS;
284
285 err:
286 free(regu);
287
288 return res;
289 }
290
291 static const struct dt_device_match regulator_gpio_match_table[] = {
292 { .compatible = "regulator-gpio" },
293 { }
294 };
295
296 DEFINE_DT_DRIVER(regulator_gpio_dt_driver) = {
297 .name = "regulator-gpio",
298 .match_table = regulator_gpio_match_table,
299 .probe = regulator_gpio_probe,
300 };
301