xref: /openbsd-src/sys/dev/ofw/ofw_regulator.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: ofw_regulator.c,v 1.1 2016/08/13 10:52:21 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2016 Mark Kettenis
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 #include <sys/systm.h>
20 #include <sys/malloc.h>
21 
22 #include <dev/ofw/openfirm.h>
23 #include <dev/ofw/ofw_gpio.h>
24 #include <dev/ofw/ofw_pinctrl.h>
25 #include <dev/ofw/ofw_regulator.h>
26 
27 int
28 regulator_set(uint32_t phandle, int enable)
29 {
30 	uint32_t *gpio;
31 	uint32_t startup_delay;
32 	int active;
33 	int node;
34 	int len;
35 
36 	node = OF_getnodebyphandle(phandle);
37 	if (node == 0)
38 		return -1;
39 
40 	if (!OF_is_compatible(node, "regulator-fixed"))
41 		return -1;
42 
43 	pinctrl_byname(node, "default");
44 
45 	if (OF_getproplen(node, "enable-active-high") == 0)
46 		active = 1;
47 	else
48 		active = 0;
49 
50 	/* The "gpio" property is optional. */
51 	len = OF_getproplen(node, "gpio");
52 	if (len < 0)
53 		return 0;
54 
55 	gpio = malloc(len, M_TEMP, M_WAITOK);
56 	OF_getpropintarray(node, "gpio", gpio, len);
57 	gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
58 	if (enable)
59 		gpio_controller_set_pin(gpio, active);
60 	else
61 		gpio_controller_set_pin(gpio, !active);
62 	free(gpio, M_TEMP, len);
63 
64 	startup_delay = OF_getpropint(node, "startup-delay-us", 0);
65 	if (enable && startup_delay > 0)
66 		delay(startup_delay);
67 
68 	return 0;
69 }
70 
71 int
72 regulator_enable(uint32_t phandle)
73 {
74 	return regulator_set(phandle, 1);
75 }
76 
77 int
78 regulator_disable(uint32_t phandle)
79 {
80 	return regulator_set(phandle, 0);
81 }
82