xref: /freebsd/sys/dev/gpio/gpioregulator.c (revision 95ee2897)
1 /*-
2  * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
20  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 /*
27  * GPIO controlled regulators
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36 #include <sys/rman.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/gpio.h>
40 
41 #include <dev/ofw/ofw_bus.h>
42 #include <dev/ofw/ofw_bus_subr.h>
43 
44 #include <dev/gpio/gpiobusvar.h>
45 
46 #include <dev/extres/regulator/regulator.h>
47 
48 #include "regdev_if.h"
49 
50 struct gpioregulator_state {
51 	int			val;
52 	uint32_t		mask;
53 };
54 
55 struct gpioregulator_init_def {
56 	struct regnode_init_def		reg_init_def;
57 	struct gpiobus_pin		*enable_pin;
58 	int				enable_pin_valid;
59 	int				startup_delay_us;
60 	int				nstates;
61 	struct gpioregulator_state	*states;
62 	int				npins;
63 	struct gpiobus_pin		**pins;
64 };
65 
66 struct gpioregulator_reg_sc {
67 	struct regnode			*regnode;
68 	device_t			base_dev;
69 	struct regnode_std_param	*param;
70 	struct gpioregulator_init_def	*def;
71 };
72 
73 struct gpioregulator_softc {
74 	device_t			dev;
75 	struct gpioregulator_reg_sc	*reg_sc;
76 	struct gpioregulator_init_def	init_def;
77 };
78 
79 static int
80 gpioregulator_regnode_init(struct regnode *regnode)
81 {
82 	struct gpioregulator_reg_sc *sc;
83 	int error, n;
84 
85 	sc = regnode_get_softc(regnode);
86 
87 	if (sc->def->enable_pin_valid == 1) {
88 		error = gpio_pin_setflags(sc->def->enable_pin, GPIO_PIN_OUTPUT);
89 		if (error != 0)
90 			return (error);
91 	}
92 
93 	for (n = 0; n < sc->def->npins; n++) {
94 		error = gpio_pin_setflags(sc->def->pins[n], GPIO_PIN_OUTPUT);
95 		if (error != 0)
96 			return (error);
97 	}
98 
99 	return (0);
100 }
101 
102 static int
103 gpioregulator_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
104 {
105 	struct gpioregulator_reg_sc *sc;
106 	bool active;
107 	int error;
108 
109 	sc = regnode_get_softc(regnode);
110 
111 	if (sc->def->enable_pin_valid == 1) {
112 		active = enable;
113 		if (!sc->param->enable_active_high)
114 			active = !active;
115 		error = gpio_pin_set_active(sc->def->enable_pin, active);
116 		if (error != 0)
117 			return (error);
118 	}
119 
120 	*udelay = sc->def->startup_delay_us;
121 
122 	return (0);
123 }
124 
125 static int
126 gpioregulator_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
127     int max_uvolt, int *udelay)
128 {
129 	struct gpioregulator_reg_sc *sc;
130 	const struct gpioregulator_state *state;
131 	int error, n;
132 
133 	sc = regnode_get_softc(regnode);
134 	state = NULL;
135 
136 	for (n = 0; n < sc->def->nstates; n++) {
137 		if (sc->def->states[n].val >= min_uvolt &&
138 		    sc->def->states[n].val <= max_uvolt) {
139 			state = &sc->def->states[n];
140 			break;
141 		}
142 	}
143 	if (state == NULL)
144 		return (EINVAL);
145 
146 	for (n = 0; n < sc->def->npins; n++) {
147 		error = gpio_pin_set_active(sc->def->pins[n],
148 		    (state->mask >> n) & 1);
149 		if (error != 0)
150 			return (error);
151 	}
152 
153 	*udelay = sc->def->startup_delay_us;
154 
155 	return (0);
156 }
157 
158 static int
159 gpioregulator_regnode_get_voltage(struct regnode *regnode, int *uvolt)
160 {
161 	struct gpioregulator_reg_sc *sc;
162 	uint32_t mask;
163 	int error, n;
164 	bool active;
165 
166 	sc = regnode_get_softc(regnode);
167 	mask = 0;
168 
169 	for (n = 0; n < sc->def->npins; n++) {
170 		error = gpio_pin_is_active(sc->def->pins[n], &active);
171 		if (error != 0)
172 			return (error);
173 		mask |= (active << n);
174 	}
175 
176 	for (n = 0; n < sc->def->nstates; n++) {
177 		if (sc->def->states[n].mask == mask) {
178 			*uvolt = sc->def->states[n].val;
179 			return (0);
180 		}
181 	}
182 
183 	return (EIO);
184 }
185 
186 static regnode_method_t gpioregulator_regnode_methods[] = {
187 	/* Regulator interface */
188 	REGNODEMETHOD(regnode_init,	gpioregulator_regnode_init),
189 	REGNODEMETHOD(regnode_enable,	gpioregulator_regnode_enable),
190 	REGNODEMETHOD(regnode_set_voltage, gpioregulator_regnode_set_voltage),
191 	REGNODEMETHOD(regnode_get_voltage, gpioregulator_regnode_get_voltage),
192 	REGNODEMETHOD_END
193 };
194 DEFINE_CLASS_1(gpioregulator_regnode, gpioregulator_regnode_class,
195     gpioregulator_regnode_methods, sizeof(struct gpioregulator_reg_sc),
196     regnode_class);
197 
198 static int
199 gpioregulator_parse_fdt(struct gpioregulator_softc *sc)
200 {
201 	uint32_t *pstates, mask;
202 	phandle_t node;
203 	ssize_t len;
204 	int error, n;
205 
206 	node = ofw_bus_get_node(sc->dev);
207 	pstates = NULL;
208 	mask = 0;
209 
210 	error = regulator_parse_ofw_stdparam(sc->dev, node,
211 	    &sc->init_def.reg_init_def);
212 	if (error != 0)
213 		return (error);
214 
215 	/* "states" property (required) */
216 	len = OF_getencprop_alloc_multi(node, "states", sizeof(*pstates),
217 	    (void **)&pstates);
218 	if (len < 2) {
219 		device_printf(sc->dev, "invalid 'states' property\n");
220 		error = EINVAL;
221 		goto done;
222 	}
223 	sc->init_def.nstates = len / 2;
224 	sc->init_def.states = malloc(sc->init_def.nstates *
225 	    sizeof(*sc->init_def.states), M_DEVBUF, M_WAITOK);
226 	for (n = 0; n < sc->init_def.nstates; n++) {
227 		sc->init_def.states[n].val = pstates[n * 2 + 0];
228 		sc->init_def.states[n].mask = pstates[n * 2 + 1];
229 		mask |= sc->init_def.states[n].mask;
230 	}
231 
232 	/* "startup-delay-us" property (optional) */
233 	len = OF_getencprop(node, "startup-delay-us",
234 	    &sc->init_def.startup_delay_us,
235 	    sizeof(sc->init_def.startup_delay_us));
236 	if (len <= 0)
237 		sc->init_def.startup_delay_us = 0;
238 
239 	/* "enable-gpio" property (optional) */
240 	error = gpio_pin_get_by_ofw_property(sc->dev, node, "enable-gpio",
241 	    &sc->init_def.enable_pin);
242 	if (error == 0)
243 		sc->init_def.enable_pin_valid = 1;
244 
245 	/* "gpios" property */
246 	sc->init_def.npins = 32 - __builtin_clz(mask);
247 	sc->init_def.pins = malloc(sc->init_def.npins *
248 	    sizeof(sc->init_def.pins), M_DEVBUF, M_WAITOK | M_ZERO);
249 	for (n = 0; n < sc->init_def.npins; n++) {
250 		error = gpio_pin_get_by_ofw_idx(sc->dev, node, n,
251 		    &sc->init_def.pins[n]);
252 		if (error != 0) {
253 			device_printf(sc->dev, "cannot get pin %d\n", n);
254 			goto done;
255 		}
256 	}
257 
258 done:
259 	if (error != 0) {
260 		for (n = 0; n < sc->init_def.npins; n++) {
261 			if (sc->init_def.pins[n] != NULL)
262 				gpio_pin_release(sc->init_def.pins[n]);
263 		}
264 
265 		free(sc->init_def.states, M_DEVBUF);
266 		free(sc->init_def.pins, M_DEVBUF);
267 
268 	}
269 	OF_prop_free(pstates);
270 
271 	return (error);
272 }
273 
274 static int
275 gpioregulator_probe(device_t dev)
276 {
277 
278 	if (!ofw_bus_is_compatible(dev, "regulator-gpio"))
279 		return (ENXIO);
280 
281 	device_set_desc(dev, "GPIO controlled regulator");
282 	return (BUS_PROBE_GENERIC);
283 }
284 
285 static int
286 gpioregulator_attach(device_t dev)
287 {
288 	struct gpioregulator_softc *sc;
289 	struct regnode *regnode;
290 	phandle_t node;
291 	int error;
292 
293 	sc = device_get_softc(dev);
294 	sc->dev = dev;
295 	node = ofw_bus_get_node(dev);
296 
297 	error = gpioregulator_parse_fdt(sc);
298 	if (error != 0) {
299 		device_printf(dev, "cannot parse parameters\n");
300 		return (ENXIO);
301 	}
302 	sc->init_def.reg_init_def.id = 1;
303 	sc->init_def.reg_init_def.ofw_node = node;
304 
305 	regnode = regnode_create(dev, &gpioregulator_regnode_class,
306 	    &sc->init_def.reg_init_def);
307 	if (regnode == NULL) {
308 		device_printf(dev, "cannot create regulator\n");
309 		return (ENXIO);
310 	}
311 
312 	sc->reg_sc = regnode_get_softc(regnode);
313 	sc->reg_sc->regnode = regnode;
314 	sc->reg_sc->base_dev = dev;
315 	sc->reg_sc->param = regnode_get_stdparam(regnode);
316 	sc->reg_sc->def = &sc->init_def;
317 
318 	regnode_register(regnode);
319 
320 	return (0);
321 }
322 
323 
324 static device_method_t gpioregulator_methods[] = {
325 	/* Device interface */
326 	DEVMETHOD(device_probe,		gpioregulator_probe),
327 	DEVMETHOD(device_attach,	gpioregulator_attach),
328 
329 	/* Regdev interface */
330 	DEVMETHOD(regdev_map,		regdev_default_ofw_map),
331 
332 	DEVMETHOD_END
333 };
334 
335 static driver_t gpioregulator_driver = {
336 	"gpioregulator",
337 	gpioregulator_methods,
338 	sizeof(struct gpioregulator_softc),
339 };
340 
341 EARLY_DRIVER_MODULE(gpioregulator, simplebus, gpioregulator_driver, 0, 0,
342     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
343 MODULE_VERSION(gpioregulator, 1);
344