1 /*-
2 * Copyright 2016 Michal Meloun <mmel@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_platform.h"
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 #include <sys/conf.h>
35 #include <sys/gpio.h>
36 #include <sys/kernel.h>
37 #include <sys/kobj.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
40
41 #ifdef FDT
42 #include <dev/fdt/fdt_common.h>
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45 #endif
46 #include <dev/gpio/gpiobusvar.h>
47 #include <dev/extres/regulator/regulator_fixed.h>
48
49 #ifdef FDT
50 #include "regdev_if.h"
51 #endif
52
53 MALLOC_DEFINE(M_FIXEDREGULATOR, "fixedregulator", "Fixed regulator");
54
55 /* GPIO list for shared pins. */
56 typedef TAILQ_HEAD(gpio_list, gpio_entry) gpio_list_t;
57 struct gpio_entry {
58 TAILQ_ENTRY(gpio_entry) link;
59 struct gpiobus_pin gpio_pin;
60 int use_cnt;
61 int enable_cnt;
62 bool always_on;
63 };
64 static gpio_list_t gpio_list = TAILQ_HEAD_INITIALIZER(gpio_list);
65 static struct mtx gpio_list_mtx;
66 MTX_SYSINIT(gpio_list_lock, &gpio_list_mtx, "Regulator GPIO lock", MTX_DEF);
67
68 struct regnode_fixed_sc {
69 struct regnode_std_param *param;
70 bool gpio_open_drain;
71 struct gpio_entry *gpio_entry;
72 };
73
74 static int regnode_fixed_init(struct regnode *regnode);
75 static int regnode_fixed_enable(struct regnode *regnode, bool enable,
76 int *udelay);
77 static int regnode_fixed_status(struct regnode *regnode, int *status);
78 static int regnode_fixed_stop(struct regnode *regnode, int *udelay);
79 static int regnode_fixed_get_voltage(struct regnode *regnode, int *uvolt);
80
81 static regnode_method_t regnode_fixed_methods[] = {
82 /* Regulator interface */
83 REGNODEMETHOD(regnode_init, regnode_fixed_init),
84 REGNODEMETHOD(regnode_enable, regnode_fixed_enable),
85 REGNODEMETHOD(regnode_status, regnode_fixed_status),
86 REGNODEMETHOD(regnode_stop, regnode_fixed_stop),
87 REGNODEMETHOD(regnode_get_voltage, regnode_fixed_get_voltage),
88 REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage),
89 REGNODEMETHOD_END
90 };
91 DEFINE_CLASS_1(regnode_fixed, regnode_fixed_class, regnode_fixed_methods,
92 sizeof(struct regnode_fixed_sc), regnode_class);
93
94 /*
95 * GPIO list functions.
96 * Two or more regulators can share single GPIO pins, so we must track all
97 * GPIOs in gpio_list.
98 * The GPIO pin is registerd and reseved for first consumer, all others share
99 * gpio_entry with it.
100 */
101 static struct gpio_entry *
102 regnode_get_gpio_entry(struct gpiobus_pin *gpio_pin)
103 {
104 struct gpio_entry *entry, *tmp;
105 device_t busdev;
106 int rv;
107
108 busdev = GPIO_GET_BUS(gpio_pin->dev);
109 if (busdev == NULL)
110 return (NULL);
111 entry = malloc(sizeof(struct gpio_entry), M_FIXEDREGULATOR,
112 M_WAITOK | M_ZERO);
113
114 mtx_lock(&gpio_list_mtx);
115
116 TAILQ_FOREACH(tmp, &gpio_list, link) {
117 if (tmp->gpio_pin.dev == gpio_pin->dev &&
118 tmp->gpio_pin.pin == gpio_pin->pin) {
119 tmp->use_cnt++;
120 mtx_unlock(&gpio_list_mtx);
121 free(entry, M_FIXEDREGULATOR);
122 return (tmp);
123 }
124 }
125
126 /* Reserve pin. */
127 /* XXX Can we call gpiobus_acquire_pin() with gpio_list_mtx held? */
128 rv = gpiobus_acquire_pin(busdev, gpio_pin->pin);
129 if (rv != 0) {
130 mtx_unlock(&gpio_list_mtx);
131 free(entry, M_FIXEDREGULATOR);
132 return (NULL);
133 }
134 /* Everything is OK, build new entry and insert it to list. */
135 entry->gpio_pin = *gpio_pin;
136 entry->use_cnt = 1;
137 TAILQ_INSERT_TAIL(&gpio_list, entry, link);
138
139 mtx_unlock(&gpio_list_mtx);
140 return (entry);
141 }
142
143
144 /*
145 * Regulator class implementation.
146 */
147 static int
148 regnode_fixed_init(struct regnode *regnode)
149 {
150 device_t dev;
151 struct regnode_fixed_sc *sc;
152 struct gpiobus_pin *pin;
153 uint32_t flags;
154 int rv;
155
156 sc = regnode_get_softc(regnode);
157 dev = regnode_get_device(regnode);
158 sc->param = regnode_get_stdparam(regnode);
159 if (sc->gpio_entry == NULL)
160 return (0);
161 pin = &sc->gpio_entry->gpio_pin;
162
163 flags = GPIO_PIN_OUTPUT;
164 if (sc->gpio_open_drain)
165 flags |= GPIO_PIN_OPENDRAIN;
166 if (sc->param->boot_on || sc->param->always_on) {
167 rv = GPIO_PIN_SET(pin->dev, pin->pin, sc->param->enable_active_high);
168 if (rv != 0) {
169 device_printf(dev, "Cannot set GPIO pin: %d\n",
170 pin->pin);
171 return (rv);
172 }
173 }
174
175 rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags);
176 if (rv != 0) {
177 device_printf(dev, "Cannot configure GPIO pin: %d\n", pin->pin);
178 return (rv);
179 }
180
181 return (0);
182 }
183
184 /*
185 * Enable/disable regulator.
186 * Take shared GPIO pins in account
187 */
188 static int
189 regnode_fixed_enable(struct regnode *regnode, bool enable, int *udelay)
190 {
191 device_t dev;
192 struct regnode_fixed_sc *sc;
193 struct gpiobus_pin *pin;
194 int rv;
195
196 sc = regnode_get_softc(regnode);
197 dev = regnode_get_device(regnode);
198
199 *udelay = 0;
200 if (sc->gpio_entry == NULL)
201 return (0);
202 pin = &sc->gpio_entry->gpio_pin;
203 if (enable) {
204 sc->gpio_entry->enable_cnt++;
205 if (sc->gpio_entry->enable_cnt > 1)
206 return (0);
207 } else {
208 KASSERT(sc->gpio_entry->enable_cnt > 0,
209 ("Invalid enable count"));
210 sc->gpio_entry->enable_cnt--;
211 if (sc->gpio_entry->enable_cnt >= 1)
212 return (0);
213 }
214 if (sc->gpio_entry->always_on && !enable)
215 return (0);
216 if (!sc->param->enable_active_high)
217 enable = !enable;
218 rv = GPIO_PIN_SET(pin->dev, pin->pin, enable);
219 if (rv != 0) {
220 device_printf(dev, "Cannot set GPIO pin: %d\n", pin->pin);
221 return (rv);
222 }
223 *udelay = sc->param->enable_delay;
224 return (0);
225 }
226
227 /*
228 * Stop (physicaly shutdown) regulator.
229 * Take shared GPIO pins in account
230 */
231 static int
232 regnode_fixed_stop(struct regnode *regnode, int *udelay)
233 {
234 device_t dev;
235 struct regnode_fixed_sc *sc;
236 struct gpiobus_pin *pin;
237 int rv;
238
239 sc = regnode_get_softc(regnode);
240 dev = regnode_get_device(regnode);
241
242 *udelay = 0;
243 if (sc->gpio_entry == NULL)
244 return (0);
245 if (sc->gpio_entry->always_on)
246 return (0);
247 pin = &sc->gpio_entry->gpio_pin;
248 if (sc->gpio_entry->enable_cnt > 0) {
249 /* Other regulator(s) are enabled. */
250 /* XXXX Any diagnostic message? Or error? */
251 return (0);
252 }
253 rv = GPIO_PIN_SET(pin->dev, pin->pin,
254 sc->param->enable_active_high ? false: true);
255 if (rv != 0) {
256 device_printf(dev, "Cannot set GPIO pin: %d\n", pin->pin);
257 return (rv);
258 }
259 *udelay = sc->param->enable_delay;
260 return (0);
261 }
262
263 static int
264 regnode_fixed_status(struct regnode *regnode, int *status)
265 {
266 struct regnode_fixed_sc *sc;
267 struct gpiobus_pin *pin;
268 uint32_t val;
269 int rv;
270
271 sc = regnode_get_softc(regnode);
272
273 *status = 0;
274 if (sc->gpio_entry == NULL) {
275 *status = REGULATOR_STATUS_ENABLED;
276 return (0);
277 }
278 pin = &sc->gpio_entry->gpio_pin;
279
280 rv = GPIO_PIN_GET(pin->dev, pin->pin, &val);
281 if (rv == 0) {
282 if (!sc->param->enable_active_high ^ (val != 0))
283 *status = REGULATOR_STATUS_ENABLED;
284 }
285 return (rv);
286 }
287
288 static int
289 regnode_fixed_get_voltage(struct regnode *regnode, int *uvolt)
290 {
291 struct regnode_fixed_sc *sc;
292
293 sc = regnode_get_softc(regnode);
294 *uvolt = sc->param->min_uvolt;
295 return (0);
296 }
297
298 int
299 regnode_fixed_register(device_t dev, struct regnode_fixed_init_def *init_def)
300 {
301 struct regnode *regnode;
302 struct regnode_fixed_sc *sc;
303
304 regnode = regnode_create(dev, ®node_fixed_class,
305 &init_def->reg_init_def);
306 if (regnode == NULL) {
307 device_printf(dev, "Cannot create regulator.\n");
308 return(ENXIO);
309 }
310 sc = regnode_get_softc(regnode);
311 sc->gpio_open_drain = init_def->gpio_open_drain;
312 if (init_def->gpio_pin != NULL) {
313 sc->gpio_entry = regnode_get_gpio_entry(init_def->gpio_pin);
314 if (sc->gpio_entry == NULL)
315 return(ENXIO);
316 }
317 regnode = regnode_register(regnode);
318 if (regnode == NULL) {
319 device_printf(dev, "Cannot register regulator.\n");
320 return(ENXIO);
321 }
322
323 if (sc->gpio_entry != NULL)
324 sc->gpio_entry->always_on |= sc->param->always_on;
325
326 return (0);
327 }
328
329 /*
330 * OFW Driver implementation.
331 */
332 #ifdef FDT
333
334 struct regfix_softc
335 {
336 device_t dev;
337 bool attach_done;
338 struct regnode_fixed_init_def init_def;
339 phandle_t gpio_prodxref;
340 pcell_t *gpio_cells;
341 int gpio_ncells;
342 struct gpiobus_pin gpio_pin;
343 };
344
345 static struct ofw_compat_data compat_data[] = {
346 {"regulator-fixed", 1},
347 {NULL, 0},
348 };
349
350 static int
351 regfix_get_gpio(struct regfix_softc * sc)
352 {
353 device_t busdev;
354 phandle_t node;
355
356 int rv;
357
358 if (sc->gpio_prodxref == 0)
359 return (0);
360
361 node = ofw_bus_get_node(sc->dev);
362
363 /* Test if controller exist. */
364 sc->gpio_pin.dev = OF_device_from_xref(sc->gpio_prodxref);
365 if (sc->gpio_pin.dev == NULL)
366 return (ENODEV);
367
368 /* Test if GPIO bus already exist. */
369 busdev = GPIO_GET_BUS(sc->gpio_pin.dev);
370 if (busdev == NULL)
371 return (ENODEV);
372
373 rv = gpio_map_gpios(sc->gpio_pin.dev, node,
374 OF_node_from_xref(sc->gpio_prodxref), sc->gpio_ncells,
375 sc->gpio_cells, &(sc->gpio_pin.pin), &(sc->gpio_pin.flags));
376 if (rv != 0) {
377 device_printf(sc->dev, "Cannot map the gpio property.\n");
378 return (ENXIO);
379 }
380 sc->init_def.gpio_pin = &sc->gpio_pin;
381 return (0);
382 }
383
384 static int
385 regfix_parse_fdt(struct regfix_softc * sc)
386 {
387 phandle_t node;
388 int rv;
389 struct regnode_init_def *init_def;
390
391 node = ofw_bus_get_node(sc->dev);
392 init_def = &sc->init_def.reg_init_def;
393
394 rv = regulator_parse_ofw_stdparam(sc->dev, node, init_def);
395 if (rv != 0) {
396 device_printf(sc->dev, "Cannot parse standard parameters.\n");
397 return(rv);
398 }
399
400 if (init_def->std_param.min_uvolt != init_def->std_param.max_uvolt) {
401 device_printf(sc->dev, "min_uvolt != max_uvolt\n");
402 return (ENXIO);
403 }
404 /* Fixed regulator uses 'startup-delay-us' property for enable_delay */
405 rv = OF_getencprop(node, "startup-delay-us",
406 &init_def->std_param.enable_delay,
407 sizeof(init_def->std_param.enable_delay));
408 if (rv <= 0)
409 init_def->std_param.enable_delay = 0;
410 /* GPIO pin */
411 if (OF_hasprop(node, "gpio-open-drain"))
412 sc->init_def.gpio_open_drain = true;
413
414 if (!OF_hasprop(node, "gpio"))
415 return (0);
416 rv = ofw_bus_parse_xref_list_alloc(node, "gpio", "#gpio-cells", 0,
417 &sc->gpio_prodxref, &sc->gpio_ncells, &sc->gpio_cells);
418 if (rv != 0) {
419 sc->gpio_prodxref = 0;
420 device_printf(sc->dev, "Malformed gpio property\n");
421 return (ENXIO);
422 }
423 return (0);
424 }
425
426 static void
427 regfix_new_pass(device_t dev)
428 {
429 struct regfix_softc * sc;
430 int rv;
431
432 sc = device_get_softc(dev);
433 bus_generic_new_pass(dev);
434
435 if (sc->attach_done)
436 return;
437
438 /* Try to get and configure GPIO. */
439 rv = regfix_get_gpio(sc);
440 if (rv != 0)
441 return;
442
443 /* Register regulator. */
444 regnode_fixed_register(sc->dev, &sc->init_def);
445 sc->attach_done = true;
446 }
447
448 static int
449 regfix_probe(device_t dev)
450 {
451
452 if (!ofw_bus_status_okay(dev))
453 return (ENXIO);
454
455 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
456 return (ENXIO);
457
458 device_set_desc(dev, "Fixed Regulator");
459 return (BUS_PROBE_DEFAULT);
460 }
461
462 static int
463 regfix_detach(device_t dev)
464 {
465
466 /* This device is always present. */
467 return (EBUSY);
468 }
469
470 static int
471 regfix_attach(device_t dev)
472 {
473 struct regfix_softc * sc;
474 int rv;
475
476 sc = device_get_softc(dev);
477 sc->dev = dev;
478
479 /* Parse FDT data. */
480 rv = regfix_parse_fdt(sc);
481 if (rv != 0)
482 return(ENXIO);
483
484 /* Fill reset of init. */
485 sc->init_def.reg_init_def.id = 1;
486 sc->init_def.reg_init_def.flags = REGULATOR_FLAGS_STATIC;
487
488 /* Try to get and configure GPIO. */
489 rv = regfix_get_gpio(sc);
490 if (rv != 0)
491 return (bus_generic_attach(dev));
492
493 /* Register regulator. */
494 regnode_fixed_register(sc->dev, &sc->init_def);
495 sc->attach_done = true;
496
497 return (bus_generic_attach(dev));
498 }
499
500 static device_method_t regfix_methods[] = {
501 /* Device interface */
502 DEVMETHOD(device_probe, regfix_probe),
503 DEVMETHOD(device_attach, regfix_attach),
504 DEVMETHOD(device_detach, regfix_detach),
505 /* Bus interface */
506 DEVMETHOD(bus_new_pass, regfix_new_pass),
507 /* Regdev interface */
508 DEVMETHOD(regdev_map, regdev_default_ofw_map),
509
510 DEVMETHOD_END
511 };
512
513 DEFINE_CLASS_0(regfix, regfix_driver, regfix_methods,
514 sizeof(struct regfix_softc));
515 EARLY_DRIVER_MODULE(regfix, simplebus, regfix_driver, 0, 0, BUS_PASS_BUS);
516
517 #endif /* FDT */
Cache object: 4f0ed2af284218c89054f97c3c29f5cc
|