xref: /freebsd/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c (revision 1323ec571215a77ddd21294f0871979d5ad6b992)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/systm.h>
34 #include <sys/clock.h>
35 
36 #include <dev/ofw/ofw_bus.h>
37 #include <dev/ofw/ofw_bus_subr.h>
38 
39 #include <dev/extres/regulator/regulator.h>
40 
41 #include <dev/iicbus/pmic/rockchip/rk8xx.h>
42 
43 #include "regdev_if.h"
44 
45 static int rk8xx_regnode_status(struct regnode *regnode, int *status);
46 static int rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
47     int max_uvolt, int *udelay);
48 static int rk8xx_regnode_get_voltage(struct regnode *regnode, int *uvolt);
49 
50 /* #define	dprintf(sc, format, arg...)	device_printf(sc->base_dev, "%s: " format, __func__, arg) */
51 #define	dprintf(sc, format, arg...) (sc = sc)
52 
53 static int
54 rk8xx_regnode_init(struct regnode *regnode)
55 {
56 	struct rk8xx_reg_sc *sc;
57 	struct regnode_std_param *param;
58 	int rv, udelay, uvolt, status;
59 
60 	sc = regnode_get_softc(regnode);
61 	dprintf(sc, "Regulator %s init called\n", sc->def->name);
62 	param = regnode_get_stdparam(regnode);
63 	if (param->min_uvolt == 0)
64 		return (0);
65 
66 	/* Check that the regulator is preset to the correct voltage */
67 	rv  = rk8xx_regnode_get_voltage(regnode, &uvolt);
68 	if (rv != 0)
69 		return(rv);
70 
71 	if (uvolt >= param->min_uvolt && uvolt <= param->max_uvolt)
72 		return(0);
73 	/*
74 	 * Set the regulator at the correct voltage if it is not enabled.
75 	 * Do not enable it, this is will be done either by a
76 	 * consumer or by regnode_set_constraint if boot_on is true
77 	 */
78 	rv = rk8xx_regnode_status(regnode, &status);
79 	if (rv != 0 || status == REGULATOR_STATUS_ENABLED)
80 		return (rv);
81 
82 	rv = rk8xx_regnode_set_voltage(regnode, param->min_uvolt,
83 	    param->max_uvolt, &udelay);
84 	if (udelay != 0)
85 		DELAY(udelay);
86 
87 	return (rv);
88 }
89 
90 static int
91 rk8xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
92 {
93 	struct rk8xx_reg_sc *sc;
94 	uint8_t val;
95 
96 	sc = regnode_get_softc(regnode);
97 
98 	dprintf(sc, "%sabling regulator %s\n",
99 	    enable ? "En" : "Dis",
100 	    sc->def->name);
101 	rk8xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
102 	if (enable)
103 		val |= sc->def->enable_mask;
104 	else
105 		val &= ~sc->def->enable_mask;
106 	rk8xx_write(sc->base_dev, sc->def->enable_reg, &val, 1);
107 
108 	*udelay = 0;
109 
110 	return (0);
111 }
112 
113 static void
114 rk8xx_regnode_reg_to_voltage(struct rk8xx_reg_sc *sc, uint8_t val, int *uv)
115 {
116 	if (val < sc->def->voltage_nstep)
117 		*uv = sc->def->voltage_min + val * sc->def->voltage_step;
118 	else
119 		*uv = sc->def->voltage_min +
120 		       (sc->def->voltage_nstep * sc->def->voltage_step);
121 }
122 
123 static int
124 rk8xx_regnode_voltage_to_reg(struct rk8xx_reg_sc *sc, int min_uvolt,
125     int max_uvolt, uint8_t *val)
126 {
127 	uint8_t nval;
128 	int nstep, uvolt;
129 
130 	nval = 0;
131 	uvolt = sc->def->voltage_min;
132 
133 	for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
134 	     nstep++) {
135 		++nval;
136 		uvolt += sc->def->voltage_step;
137 	}
138 	if (uvolt > max_uvolt)
139 		return (EINVAL);
140 
141 	*val = nval;
142 	return (0);
143 }
144 
145 static int
146 rk8xx_regnode_status(struct regnode *regnode, int *status)
147 {
148 	struct rk8xx_reg_sc *sc;
149 	uint8_t val;
150 
151 	sc = regnode_get_softc(regnode);
152 
153 	*status = 0;
154 	rk8xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
155 	if (val & sc->def->enable_mask)
156 		*status = REGULATOR_STATUS_ENABLED;
157 
158 	return (0);
159 }
160 
161 static int
162 rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
163     int max_uvolt, int *udelay)
164 {
165 	struct rk8xx_reg_sc *sc;
166 	uint8_t val;
167 	int uvolt;
168 
169 	sc = regnode_get_softc(regnode);
170 
171 	if (!sc->def->voltage_step)
172 		return (ENXIO);
173 
174 	dprintf(sc, "Setting %s to %d<->%d uvolts\n",
175 	    sc->def->name,
176 	    min_uvolt,
177 	    max_uvolt);
178 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
179 	if (rk8xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
180 		return (ERANGE);
181 
182 	rk8xx_write(sc->base_dev, sc->def->voltage_reg, &val, 1);
183 
184 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
185 
186 	*udelay = 0;
187 
188 	rk8xx_regnode_reg_to_voltage(sc, val, &uvolt);
189 	dprintf(sc, "Regulator %s set to %d uvolt\n",
190 	  sc->def->name,
191 	  uvolt);
192 
193 	return (0);
194 }
195 
196 static int
197 rk8xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
198 {
199 	struct rk8xx_reg_sc *sc;
200 	uint8_t val;
201 
202 	sc = regnode_get_softc(regnode);
203 
204 	if (sc->def->voltage_min ==  sc->def->voltage_max) {
205 		*uvolt = sc->def->voltage_min;
206 		return (0);
207 	}
208 
209 	if (!sc->def->voltage_step)
210 		return (ENXIO);
211 
212 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
213 	rk8xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
214 
215 	dprintf(sc, "Regulator %s is at %d uvolt\n",
216 	  sc->def->name,
217 	  *uvolt);
218 
219 	return (0);
220 }
221 
222 static regnode_method_t rk8xx_regnode_methods[] = {
223 	/* Regulator interface */
224 	REGNODEMETHOD(regnode_init,		rk8xx_regnode_init),
225 	REGNODEMETHOD(regnode_enable,		rk8xx_regnode_enable),
226 	REGNODEMETHOD(regnode_status,		rk8xx_regnode_status),
227 	REGNODEMETHOD(regnode_set_voltage,	rk8xx_regnode_set_voltage),
228 	REGNODEMETHOD(regnode_get_voltage,	rk8xx_regnode_get_voltage),
229 	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
230 	REGNODEMETHOD_END
231 };
232 DEFINE_CLASS_1(rk8xx_regnode, rk8xx_regnode_class, rk8xx_regnode_methods,
233     sizeof(struct rk8xx_reg_sc), regnode_class);
234 
235 static struct rk8xx_reg_sc *
236 rk8xx_reg_attach(device_t dev, phandle_t node,
237     struct rk8xx_regdef *def)
238 {
239 	struct rk8xx_reg_sc *reg_sc;
240 	struct regnode_init_def initdef;
241 	struct regnode *regnode;
242 
243 	memset(&initdef, 0, sizeof(initdef));
244 	if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
245 		device_printf(dev, "cannot create regulator\n");
246 		return (NULL);
247 	}
248 	if (initdef.std_param.min_uvolt == 0)
249 		initdef.std_param.min_uvolt = def->voltage_min;
250 	if (initdef.std_param.max_uvolt == 0)
251 		initdef.std_param.max_uvolt = def->voltage_max;
252 	initdef.id = def->id;
253 	initdef.ofw_node = node;
254 
255 	regnode = regnode_create(dev, &rk8xx_regnode_class, &initdef);
256 	if (regnode == NULL) {
257 		device_printf(dev, "cannot create regulator\n");
258 		return (NULL);
259 	}
260 
261 	reg_sc = regnode_get_softc(regnode);
262 	reg_sc->regnode = regnode;
263 	reg_sc->base_dev = dev;
264 	reg_sc->def = def;
265 	reg_sc->xref = OF_xref_from_node(node);
266 	reg_sc->param = regnode_get_stdparam(regnode);
267 
268 	regnode_register(regnode);
269 
270 	return (reg_sc);
271 }
272 
273 void
274 rk8xx_attach_regulators(struct rk8xx_softc *sc)
275 {
276 	struct rk8xx_reg_sc *reg;
277 	struct reg_list *regp;
278 	phandle_t rnode, child;
279 	int i;
280 
281 	TAILQ_INIT(&sc->regs);
282 
283 	rnode = ofw_bus_find_child(ofw_bus_get_node(sc->dev), "regulators");
284 	if (rnode > 0) {
285 		for (i = 0; i < sc->nregs; i++) {
286 			child = ofw_bus_find_child(rnode,
287 			    sc->regdefs[i].name);
288 			if (child == 0)
289 				continue;
290 			if (OF_hasprop(child, "regulator-name") != 1)
291 				continue;
292 			reg = rk8xx_reg_attach(sc->dev, child, &sc->regdefs[i]);
293 			if (reg == NULL) {
294 				device_printf(sc->dev,
295 				    "cannot attach regulator %s\n",
296 				    sc->regdefs[i].name);
297 				continue;
298 			}
299 			regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK | M_ZERO);
300 			regp->reg = reg;
301 			TAILQ_INSERT_TAIL(&sc->regs, regp, next);
302 			if (bootverbose)
303 				device_printf(sc->dev, "Regulator %s attached\n",
304 				    sc->regdefs[i].name);
305 		}
306 	}
307 }
308 
309 int
310 rk8xx_map(device_t dev, phandle_t xref, int ncells,
311     pcell_t *cells, intptr_t *id)
312 {
313 	struct rk8xx_softc *sc;
314 	struct reg_list *regp;
315 
316 	sc = device_get_softc(dev);
317 
318 	TAILQ_FOREACH(regp, &sc->regs, next) {
319 		if (regp->reg->xref == xref) {
320 			*id = regp->reg->def->id;
321 			return (0);
322 		}
323 	}
324 
325 	return (ERANGE);
326 }
327