xref: /freebsd/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
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 	struct rk8xx_softc *sc1;
117 
118 	sc1 = device_get_softc(sc->base_dev);
119 	if (sc1->type == RK809 || sc1->type == RK817) {
120 		if (sc->def->voltage_step2) {
121 			int change;
122 
123 			change =
124 			    ((sc->def->voltage_min2 - sc->def->voltage_min) /
125 			    sc->def->voltage_step);
126 			if (val > change) {
127 				if (val < sc->def->voltage_nstep) {
128 					*uv = sc->def->voltage_min2 +
129 					    (val - change) *
130 					    sc->def->voltage_step2;
131 				} else
132 					*uv = sc->def->voltage_max2;
133 				return;
134 			}
135 		}
136 		if (val < sc->def->voltage_nstep)
137 			*uv = sc->def->voltage_min + val * sc->def->voltage_step;
138 		else
139 			*uv = sc->def->voltage_max;
140 
141 	} else {
142 		if (val < sc->def->voltage_nstep)
143 			*uv = sc->def->voltage_min + val * sc->def->voltage_step;
144 		else
145 			*uv = sc->def->voltage_min +
146 			    (sc->def->voltage_nstep * sc->def->voltage_step);
147 	}
148 }
149 
150 static int
151 rk8xx_regnode_voltage_to_reg(struct rk8xx_reg_sc *sc, int min_uvolt,
152     int max_uvolt, uint8_t *val)
153 {
154 	uint8_t nval;
155 	int nstep, uvolt;
156 	struct rk8xx_softc *sc1;
157 
158 	sc1 = device_get_softc(sc->base_dev);
159 	nval = 0;
160 	uvolt = sc->def->voltage_min;
161 
162 	for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
163 	     nstep++) {
164 		++nval;
165 		if (sc1->type == RK809 || sc1->type == RK817) {
166 			if (sc->def->voltage_step2) {
167 				if (uvolt < sc->def->voltage_min2)
168 					uvolt += sc->def->voltage_step;
169 				else
170 					uvolt += sc->def->voltage_step2;
171 			} else
172 				uvolt += sc->def->voltage_step;
173 		} else
174 			uvolt += sc->def->voltage_step;
175 	}
176 	if (uvolt > max_uvolt)
177 		return (EINVAL);
178 
179 	*val = nval;
180 	return (0);
181 }
182 
183 static int
184 rk8xx_regnode_status(struct regnode *regnode, int *status)
185 {
186 	struct rk8xx_reg_sc *sc;
187 	uint8_t val;
188 
189 	sc = regnode_get_softc(regnode);
190 
191 	*status = 0;
192 	rk8xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
193 	if (val & sc->def->enable_mask)
194 		*status = REGULATOR_STATUS_ENABLED;
195 
196 	return (0);
197 }
198 
199 static int
200 rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
201     int max_uvolt, int *udelay)
202 {
203 	struct rk8xx_reg_sc *sc;
204 	uint8_t val, old;
205 	int uvolt;
206 	struct rk8xx_softc *sc1;
207 
208 	sc = regnode_get_softc(regnode);
209 	sc1 = device_get_softc(sc->base_dev);
210 
211 	if (!sc->def->voltage_step)
212 		return (ENXIO);
213 
214 	dprintf(sc, "Setting %s to %d<->%d uvolts\n",
215 	    sc->def->name,
216 	    min_uvolt,
217 	    max_uvolt);
218 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
219 	old = val;
220 	if (rk8xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
221 		return (ERANGE);
222 
223 	if (sc1->type == RK809 || sc1->type == RK817)
224 		val |= (old &= ~sc->def->voltage_mask);
225 
226 	rk8xx_write(sc->base_dev, sc->def->voltage_reg, &val, 1);
227 
228 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
229 
230 	*udelay = 0;
231 
232 	rk8xx_regnode_reg_to_voltage(sc, val, &uvolt);
233 	dprintf(sc, "Regulator %s set to %d uvolt\n",
234 	  sc->def->name,
235 	  uvolt);
236 
237 	return (0);
238 }
239 
240 static int
241 rk8xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
242 {
243 	struct rk8xx_reg_sc *sc;
244 	uint8_t val;
245 
246 	sc = regnode_get_softc(regnode);
247 
248 	if (sc->def->voltage_min ==  sc->def->voltage_max) {
249 		*uvolt = sc->def->voltage_min;
250 		return (0);
251 	}
252 
253 	if (!sc->def->voltage_step)
254 		return (ENXIO);
255 
256 	rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
257 	rk8xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
258 
259 	dprintf(sc, "Regulator %s is at %d uvolt\n",
260 	  sc->def->name,
261 	  *uvolt);
262 
263 	return (0);
264 }
265 
266 static regnode_method_t rk8xx_regnode_methods[] = {
267 	/* Regulator interface */
268 	REGNODEMETHOD(regnode_init,		rk8xx_regnode_init),
269 	REGNODEMETHOD(regnode_enable,		rk8xx_regnode_enable),
270 	REGNODEMETHOD(regnode_status,		rk8xx_regnode_status),
271 	REGNODEMETHOD(regnode_set_voltage,	rk8xx_regnode_set_voltage),
272 	REGNODEMETHOD(regnode_get_voltage,	rk8xx_regnode_get_voltage),
273 	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
274 	REGNODEMETHOD_END
275 };
276 DEFINE_CLASS_1(rk8xx_regnode, rk8xx_regnode_class, rk8xx_regnode_methods,
277     sizeof(struct rk8xx_reg_sc), regnode_class);
278 
279 static struct rk8xx_reg_sc *
280 rk8xx_reg_attach(device_t dev, phandle_t node,
281     struct rk8xx_regdef *def)
282 {
283 	struct rk8xx_reg_sc *reg_sc;
284 	struct regnode_init_def initdef;
285 	struct regnode *regnode;
286 
287 	memset(&initdef, 0, sizeof(initdef));
288 	if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
289 		device_printf(dev, "cannot create regulator\n");
290 		return (NULL);
291 	}
292 	if (initdef.std_param.min_uvolt == 0)
293 		initdef.std_param.min_uvolt = def->voltage_min;
294 	if (initdef.std_param.max_uvolt == 0)
295 		initdef.std_param.max_uvolt = def->voltage_max;
296 	initdef.id = def->id;
297 	initdef.ofw_node = node;
298 
299 	regnode = regnode_create(dev, &rk8xx_regnode_class, &initdef);
300 	if (regnode == NULL) {
301 		device_printf(dev, "cannot create regulator\n");
302 		return (NULL);
303 	}
304 
305 	reg_sc = regnode_get_softc(regnode);
306 	reg_sc->regnode = regnode;
307 	reg_sc->base_dev = dev;
308 	reg_sc->def = def;
309 	reg_sc->xref = OF_xref_from_node(node);
310 	reg_sc->param = regnode_get_stdparam(regnode);
311 
312 	regnode_register(regnode);
313 
314 	return (reg_sc);
315 }
316 
317 void
318 rk8xx_attach_regulators(struct rk8xx_softc *sc)
319 {
320 	struct rk8xx_reg_sc *reg;
321 	struct reg_list *regp;
322 	phandle_t rnode, child;
323 	int i;
324 
325 	TAILQ_INIT(&sc->regs);
326 
327 	rnode = ofw_bus_find_child(ofw_bus_get_node(sc->dev), "regulators");
328 	if (rnode > 0) {
329 		for (i = 0; i < sc->nregs; i++) {
330 			child = ofw_bus_find_child(rnode,
331 			    sc->regdefs[i].name);
332 			if (child == 0)
333 				continue;
334 			if (OF_hasprop(child, "regulator-name") != 1)
335 				continue;
336 			reg = rk8xx_reg_attach(sc->dev, child, &sc->regdefs[i]);
337 			if (reg == NULL) {
338 				device_printf(sc->dev,
339 				    "cannot attach regulator %s\n",
340 				    sc->regdefs[i].name);
341 				continue;
342 			}
343 			regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK | M_ZERO);
344 			regp->reg = reg;
345 			TAILQ_INSERT_TAIL(&sc->regs, regp, next);
346 			if (bootverbose)
347 				device_printf(sc->dev, "Regulator %s attached\n",
348 				    sc->regdefs[i].name);
349 		}
350 	}
351 }
352 
353 int
354 rk8xx_map(device_t dev, phandle_t xref, int ncells,
355     pcell_t *cells, intptr_t *id)
356 {
357 	struct rk8xx_softc *sc;
358 	struct reg_list *regp;
359 
360 	sc = device_get_softc(dev);
361 
362 	TAILQ_FOREACH(regp, &sc->regs, next) {
363 		if (regp->reg->xref == xref) {
364 			*id = regp->reg->def->id;
365 			return (0);
366 		}
367 	}
368 
369 	return (ERANGE);
370 }
371