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 	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 = &regulator_gpio_ops,
273 		.supply_name = supply_name,
274 		.regulator = &regu->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