xref: /optee_os/core/drivers/regulator/regulator_gpio.c (revision 39d1e320ec639a05e1c04b4fe1729904a0399f2b)
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 = &regu->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 = &regulator_gpio_ops,
279 		.supply_name = supply_name,
280 		.regulator = &regu->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