1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2019 Michal Meloun <mmel@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 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/bus.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/mutex.h>
35 #include <sys/rman.h>
36 #include <machine/bus.h>
37
38 #include <dev/iicbus/iiconf.h>
39 #include <dev/iicbus/iicbus.h>
40
41 #include <dev/ofw/ofw_bus.h>
42 #include <dev/ofw/ofw_bus_subr.h>
43
44 #include <dev/extres/regulator/regulator.h>
45
46 #include <dev/iicbus/pmic/act8846.h>
47
48 #include "regdev_if.h"
49
50 MALLOC_DEFINE(M_ACT8846_REG, "ACT8846 regulator", "ACT8846 power regulator");
51
52 #if 0
53 #define dprintf(sc, format, arg...)
54 device_printf(sc->base_sc->dev, "%s: " format, __func__, arg) */
55 #else
56 #define dprintf(sc, format, arg...)
57 #endif
58
59 enum act8846_reg_id {
60 ACT8846_REG_ID_REG1,
61 ACT8846_REG_ID_REG2,
62 ACT8846_REG_ID_REG3,
63 ACT8846_REG_ID_REG4,
64 ACT8846_REG_ID_REG5,
65 ACT8846_REG_ID_REG6,
66 ACT8846_REG_ID_REG7,
67 ACT8846_REG_ID_REG8,
68 ACT8846_REG_ID_REG9,
69 ACT8846_REG_ID_REG10,
70 ACT8846_REG_ID_REG11,
71 ACT8846_REG_ID_REG12,
72 ACT8846_REG_ID_REG13,
73 };
74
75 struct act8846_regdef {
76 intptr_t id; /* ID */
77 char *name; /* Regulator name */
78 char *supply_name; /* Source property name */
79 uint8_t enable_reg;
80 uint8_t enable_mask;
81 uint8_t voltage_reg;
82 uint8_t voltage_mask;
83 struct regulator_range *ranges;
84 int nranges;
85 };
86 struct act8846_softc;
87
88 struct act8846_reg_sc {
89 struct regnode *regnode;
90 struct act8846_softc *base_sc;
91 struct act8846_regdef *def;
92 phandle_t xref;
93 struct regnode_std_param *param;
94 };
95
96
97 static struct regulator_range act8846_ranges[] = {
98 REG_RANGE_INIT( 0, 23, 600000, 25000),
99 REG_RANGE_INIT( 24, 47, 1200000, 50000),
100 REG_RANGE_INIT( 48, 64, 2400000, 100000),
101 };
102
103 static struct act8846_regdef act8846_regdefs[] = {
104 {
105 .id = ACT8846_REG_ID_REG1,
106 .name = "REG1",
107 .supply_name = "vp1",
108 .enable_reg = ACT8846_REG1_CTRL,
109 .enable_mask = ACT8846_CTRL_ENA,
110 },
111 {
112 .id = ACT8846_REG_ID_REG2,
113 .name = "REG2",
114 .supply_name = "vp2",
115 .enable_reg = ACT8846_REG2_CTRL,
116 .enable_mask = ACT8846_CTRL_ENA,
117 .voltage_reg = ACT8846_REG2_VSET0,
118 .voltage_mask = ACT8846_VSEL_MASK,
119 .ranges = act8846_ranges,
120 .nranges = nitems(act8846_ranges),
121 },
122 {
123 .id = ACT8846_REG_ID_REG3,
124 .name = "REG3",
125 .supply_name = "vp3",
126 .enable_reg = ACT8846_REG3_CTRL,
127 .enable_mask = ACT8846_CTRL_ENA,
128 .voltage_reg = ACT8846_REG3_VSET0,
129 .voltage_mask = ACT8846_VSEL_MASK,
130 .ranges = act8846_ranges,
131 .nranges = nitems(act8846_ranges),
132 },
133 {
134 .id = ACT8846_REG_ID_REG4,
135 .name = "REG4",
136 .supply_name = "vp4",
137 .enable_reg = ACT8846_REG4_CTRL,
138 .enable_mask = ACT8846_CTRL_ENA,
139 .voltage_reg = ACT8846_REG4_VSET0,
140 .voltage_mask = ACT8846_VSEL_MASK,
141 .ranges = act8846_ranges,
142 .nranges = nitems(act8846_ranges),
143 },
144 {
145 .id = ACT8846_REG_ID_REG5,
146 .name = "REG5",
147 .supply_name = "inl1",
148 .enable_reg = ACT8846_REG5_CTRL,
149 .enable_mask = ACT8846_CTRL_ENA,
150 .voltage_reg = ACT8846_REG5_VSET,
151 .voltage_mask = ACT8846_VSEL_MASK,
152 .ranges = act8846_ranges,
153 .nranges = nitems(act8846_ranges),
154 },
155 {
156 .id = ACT8846_REG_ID_REG6,
157 .name = "REG6",
158 .supply_name = "inl1",
159 .enable_reg = ACT8846_REG6_CTRL,
160 .enable_mask = ACT8846_CTRL_ENA,
161 .voltage_reg = ACT8846_REG6_VSET,
162 .voltage_mask = ACT8846_VSEL_MASK,
163 .ranges = act8846_ranges,
164 .nranges = nitems(act8846_ranges),
165 },
166 {
167 .id = ACT8846_REG_ID_REG7,
168 .name = "REG7",
169 .supply_name = "inl1",
170 .enable_reg = ACT8846_REG7_CTRL,
171 .enable_mask = ACT8846_CTRL_ENA,
172 .voltage_reg = ACT8846_REG7_VSET,
173 .voltage_mask = ACT8846_VSEL_MASK,
174 .ranges = act8846_ranges,
175 .nranges = nitems(act8846_ranges),
176 },
177 {
178 .id = ACT8846_REG_ID_REG8,
179 .name = "REG8",
180 .supply_name = "inl2",
181 .enable_reg = ACT8846_REG8_CTRL,
182 .enable_mask = ACT8846_CTRL_ENA,
183 .voltage_reg = ACT8846_REG8_VSET,
184 .voltage_mask = ACT8846_VSEL_MASK,
185 .ranges = act8846_ranges,
186 .nranges = nitems(act8846_ranges),
187 },
188 {
189 .id = ACT8846_REG_ID_REG9,
190 .name = "REG9",
191 .supply_name = "inl2",
192 .enable_reg = ACT8846_REG9_CTRL,
193 .enable_mask = ACT8846_CTRL_ENA,
194 .voltage_reg = ACT8846_REG9_VSET,
195 .voltage_mask = ACT8846_VSEL_MASK,
196 .ranges = act8846_ranges,
197 .nranges = nitems(act8846_ranges),
198 },
199 {
200 .id = ACT8846_REG_ID_REG10,
201 .name = "REG10",
202 .supply_name = "inl3",
203 .enable_reg = ACT8846_REG10_CTRL,
204 .enable_mask = ACT8846_CTRL_ENA,
205 .voltage_reg = ACT8846_REG10_VSET,
206 .voltage_mask = ACT8846_VSEL_MASK,
207 .ranges = act8846_ranges,
208 .nranges = nitems(act8846_ranges),
209 },
210 {
211 .id = ACT8846_REG_ID_REG11,
212 .name = "REG11",
213 .supply_name = "inl3",
214 .enable_reg = ACT8846_REG11_CTRL,
215 .enable_mask = ACT8846_CTRL_ENA,
216 .voltage_reg = ACT8846_REG11_VSET,
217 .voltage_mask = ACT8846_VSEL_MASK,
218 .ranges = act8846_ranges,
219 .nranges = nitems(act8846_ranges),
220 },
221 {
222 .id = ACT8846_REG_ID_REG12,
223 .name = "REG12",
224 .supply_name = "inl3",
225 .enable_reg = ACT8846_REG12_CTRL,
226 .enable_mask = ACT8846_CTRL_ENA,
227 .voltage_reg = ACT8846_REG12_VSET,
228 .voltage_mask = ACT8846_VSEL_MASK,
229 .ranges = act8846_ranges,
230 .nranges = nitems(act8846_ranges),
231 },
232 {
233 .id = ACT8846_REG_ID_REG13,
234 .name = "REG13",
235 .supply_name = "inl1",
236 .enable_reg = ACT8846_REG13_CTRL,
237 .enable_mask = ACT8846_CTRL_ENA,
238 },
239 };
240
241 static int
act8846_read_sel(struct act8846_reg_sc * sc,uint8_t * sel)242 act8846_read_sel(struct act8846_reg_sc *sc, uint8_t *sel)
243 {
244 int rv;
245
246 rv = RD1(sc->base_sc, sc->def->voltage_reg, sel);
247 if (rv != 0)
248 return (rv);
249 *sel &= sc->def->voltage_mask;
250 *sel >>= ffs(sc->def->voltage_mask) - 1;
251 return (0);
252 }
253
254 static int
act8846_write_sel(struct act8846_reg_sc * sc,uint8_t sel)255 act8846_write_sel(struct act8846_reg_sc *sc, uint8_t sel)
256 {
257 int rv;
258
259 sel <<= ffs(sc->def->voltage_mask) - 1;
260 sel &= sc->def->voltage_mask;
261
262 rv = RM1(sc->base_sc, sc->def->voltage_reg,
263 sc->def->voltage_mask, sel);
264 if (rv != 0)
265 return (rv);
266 return (rv);
267 }
268
269 static int
act8846_regnode_init(struct regnode * regnode)270 act8846_regnode_init(struct regnode *regnode)
271 {
272 return (0);
273 }
274
275 static int
act8846_regnode_enable(struct regnode * regnode,bool enable,int * udelay)276 act8846_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
277 {
278 struct act8846_reg_sc *sc;
279 int rv;
280
281 sc = regnode_get_softc(regnode);
282
283 dprintf(sc, "%sabling regulator %s\n",
284 enable ? "En" : "Dis",
285 sc->def->name);
286 rv = RM1(sc->base_sc, sc->def->enable_reg,
287 sc->def->enable_mask, enable ? sc->def->enable_mask: 0);
288 *udelay = sc->param->enable_delay;
289
290 return (rv);
291 }
292
293 static int
act8846_regnode_set_voltage(struct regnode * regnode,int min_uvolt,int max_uvolt,int * udelay)294 act8846_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
295 int max_uvolt, int *udelay)
296 {
297 struct act8846_reg_sc *sc;
298 uint8_t sel;
299 int uvolt, rv;
300
301 sc = regnode_get_softc(regnode);
302
303 if (sc->def->ranges == NULL)
304 return (ENXIO);
305
306 dprintf(sc, "Setting %s to %d<->%d uvolts\n",
307 sc->def->name,
308 min_uvolt,
309 max_uvolt);
310 rv = regulator_range_volt_to_sel8(sc->def->ranges, sc->def->nranges,
311 min_uvolt, max_uvolt, &sel);
312 if (rv != 0)
313 return (rv);
314 *udelay = sc->param->ramp_delay;
315 rv = act8846_write_sel(sc, sel);
316
317 act8846_read_sel(sc, &sel);
318 regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges,
319 sel, &uvolt);
320 dprintf(sc, "Regulator %s set to %d uvolt\n", sc->def->name,
321 uvolt);
322
323 return (rv);
324 }
325
326 static int
act8846_regnode_get_voltage(struct regnode * regnode,int * uvolt)327 act8846_regnode_get_voltage(struct regnode *regnode, int *uvolt)
328 {
329 struct act8846_reg_sc *sc;
330 uint8_t sel;
331 int rv;
332
333 sc = regnode_get_softc(regnode);
334
335 if (sc->def->ranges == NULL) {
336 if (sc->def->id == ACT8846_REG_ID_REG13) {
337 *uvolt = 1800000;
338 return (0);
339 }
340 return (ENXIO);
341 }
342
343 rv = act8846_read_sel(sc, &sel);
344 if (rv != 0)
345 return (rv);
346 rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges,
347 sel, uvolt);
348 dprintf(sc, "Regulator %s is at %d uvolt\n", sc->def->name,
349 *uvolt);
350
351 return (rv);
352 }
353
354 static regnode_method_t act8846_regnode_methods[] = {
355 /* Regulator interface */
356 REGNODEMETHOD(regnode_init, act8846_regnode_init),
357 REGNODEMETHOD(regnode_enable, act8846_regnode_enable),
358 REGNODEMETHOD(regnode_set_voltage, act8846_regnode_set_voltage),
359 REGNODEMETHOD(regnode_get_voltage, act8846_regnode_get_voltage),
360 REGNODEMETHOD_END
361 };
362 DEFINE_CLASS_1(act8846_regnode, act8846_regnode_class, act8846_regnode_methods,
363 sizeof(struct act8846_reg_sc), regnode_class);
364
365 static int
act8846_fdt_parse(struct act8846_softc * sc,phandle_t pnode,phandle_t node,struct act8846_regdef * def,struct regnode_init_def * init_def)366 act8846_fdt_parse(struct act8846_softc *sc, phandle_t pnode, phandle_t node,
367 struct act8846_regdef *def, struct regnode_init_def *init_def)
368 {
369 int rv;
370 phandle_t supply_node;
371 char prop_name[64]; /* Maximum OFW property name length. */
372
373 rv = regulator_parse_ofw_stdparam(sc->dev, node, init_def);
374
375 /* Get parent supply. */
376 if (def->supply_name == NULL)
377 return (0);
378
379 snprintf(prop_name, sizeof(prop_name), "%s-supply",
380 def->supply_name);
381 rv = OF_getencprop(pnode, prop_name, &supply_node,
382 sizeof(supply_node));
383 if (rv <= 0)
384 return (rv);
385 supply_node = OF_node_from_xref(supply_node);
386 rv = OF_getprop_alloc(supply_node, "regulator-name",
387 (void **)&init_def->parent_name);
388 if (rv <= 0)
389 init_def->parent_name = NULL;
390 return (0);
391 }
392
393 static struct act8846_reg_sc *
act8846_attach(struct act8846_softc * sc,phandle_t pnode,phandle_t node,struct act8846_regdef * def)394 act8846_attach(struct act8846_softc *sc, phandle_t pnode, phandle_t node,
395 struct act8846_regdef *def)
396 {
397 struct act8846_reg_sc *reg_sc;
398 struct regnode_init_def initdef;
399 struct regnode *regnode;
400
401 memset(&initdef, 0, sizeof(initdef));
402 if (act8846_fdt_parse(sc, pnode, node, def, &initdef) != 0) {
403 device_printf(sc->dev, "cannot parse FDT data for regulator\n");
404 return (NULL);
405 }
406 initdef.id = def->id;
407 initdef.ofw_node = node;
408
409 regnode = regnode_create(sc->dev, &act8846_regnode_class, &initdef);
410 if (regnode == NULL) {
411 device_printf(sc->dev, "cannot create regulator\n");
412 return (NULL);
413 }
414
415 reg_sc = regnode_get_softc(regnode);
416 reg_sc->base_sc = sc;
417 reg_sc->def = def;
418 reg_sc->xref = OF_xref_from_node(node);
419 reg_sc->param = regnode_get_stdparam(regnode);
420
421 regnode_register(regnode);
422
423 if (bootverbose) {
424 int volt, rv;
425 regnode_topo_slock();
426 rv = regnode_get_voltage(regnode, &volt);
427 if (rv == ENODEV) {
428 device_printf(sc->dev,
429 " Regulator %s: parent doesn't exist yet.\n",
430 regnode_get_name(regnode));
431 } else if (rv != 0) {
432 device_printf(sc->dev,
433 " Regulator %s: voltage: INVALID!!!\n",
434 regnode_get_name(regnode));
435 } else {
436 device_printf(sc->dev,
437 " Regulator %s: voltage: %d uV\n",
438 regnode_get_name(regnode), volt);
439 }
440 regnode_topo_unlock();
441 }
442
443 return (reg_sc);
444 }
445
446
447 int
act8846_regulator_attach(struct act8846_softc * sc,phandle_t node)448 act8846_regulator_attach(struct act8846_softc *sc, phandle_t node)
449 {
450 struct act8846_reg_sc *reg;
451 phandle_t child, rnode;
452 int i;
453
454 rnode = ofw_bus_find_child(node, "regulators");
455 if (rnode <= 0) {
456 device_printf(sc->dev, " Cannot find regulators subnode\n");
457 return (ENXIO);
458 }
459
460 /* ACT8846 specific definitio. */
461 sc->nregs = nitems(act8846_regdefs);
462 sc->regs = malloc(sizeof(struct act8846_reg_sc *) * sc->nregs,
463 M_ACT8846_REG, M_WAITOK | M_ZERO);
464
465
466 /* Attach all known regulators if exist in DT. */
467 for (i = 0; i < sc->nregs; i++) {
468 child = ofw_bus_find_child(rnode, act8846_regdefs[i].name);
469 if (child == 0) {
470 if (bootverbose)
471 device_printf(sc->dev,
472 "Regulator %s missing in DT\n",
473 act8846_regdefs[i].name);
474 continue;
475 }
476 reg = act8846_attach(sc, node, child, act8846_regdefs + i);
477 if (reg == NULL) {
478 device_printf(sc->dev, "Cannot attach regulator: %s\n",
479 act8846_regdefs[i].name);
480 return (ENXIO);
481 }
482 sc->regs[i] = reg;
483 }
484 return (0);
485 }
486
487 int
act8846_regulator_map(device_t dev,phandle_t xref,int ncells,pcell_t * cells,int * num)488 act8846_regulator_map(device_t dev, phandle_t xref, int ncells,
489 pcell_t *cells, int *num)
490 {
491 struct act8846_softc *sc;
492 int i;
493
494 sc = device_get_softc(dev);
495 for (i = 0; i < sc->nregs; i++) {
496 if (sc->regs[i] == NULL)
497 continue;
498 if (sc->regs[i]->xref == xref) {
499 *num = sc->regs[i]->def->id;
500 return (0);
501 }
502 }
503 return (ENXIO);
504 }
505