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 }
Cache object: 92b74a0d928c1b1315e77cbcae9ae3e4
|