xref: /freebsd/sys/dev/iicbus/pmic/fan53555.c (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
5  * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
6  * Copyright (c) 2019 Michal Meloun <mmel@FreeBSD.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/mutex.h>
38 #include <sys/rman.h>
39 #include <machine/bus.h>
40 
41 #include <dev/iicbus/iiconf.h>
42 #include <dev/iicbus/iicbus.h>
43 
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
46 
47 #include <dev/extres/regulator/regulator.h>
48 
49 #include "regdev_if.h"
50 
51 /* Registers */
52 #define	FAN53555_VSEL0		0x00
53 #define	FAN53555_VSEL1		0x01
54 #define	 FAN53555_VSEL_ENA		(1 << 7)
55 #define	 FAN53555_VSEL_MODE		(1 << 6)
56 #define	 FAN53555_VSEL_MASK		0x3f
57 #define	FAN53555_CTRL		0x02
58 #define	FAN53555_ID1		0x03
59 #define	 FAN53555_ID1_DIE_ID(x)		(((x) >> 4) & 0x0F)
60 #define	FAN53555_ID2		0x04
61 #define	 FAN53555_ID2_DIE_REV(x)	(((x) >> 4) & 0x0F)
62 #define	FAN53555_MON		0x05
63 
64 
65 #if 0
66 #define	dprintf(sc, format, arg...)					\
67 	device_printf(sc->base_dev, "%s: " format, __func__, arg)
68 #else
69 #define	dprintf(sc, format, arg...)
70 #endif
71 
72 enum fan53555_pmic_type {
73 	FAN53555 = 1,
74 	SYR827,
75 	SYR828,
76 };
77 
78 static struct ofw_compat_data compat_data[] = {
79 	{"fcs,fan53555", 	FAN53555},
80 	{"silergy,syr827",	SYR827},
81 	{"silergy,syr828",	SYR828},
82 	{NULL,		0}
83 };
84 
85 struct fan53555_reg_sc {
86 	struct regnode		*regnode;
87 	char			*name;
88 	device_t		base_dev;
89 	uint8_t			live_reg;
90 	uint8_t			sleep_reg;
91 	struct regulator_range	*range;
92 	struct regnode_std_param *param;
93 };
94 
95 struct fan53555_softc {
96 	device_t		dev;
97 	uint8_t			live_reg;
98 	uint8_t			sleep_reg;
99 };
100 
101 static struct regulator_range syr_8_range =
102    REG_RANGE_INIT(  0, 0x3F,  712500, 12500);
103 
104 static struct regulator_range fan_0_0_range =
105    REG_RANGE_INIT(  0, 0x3F,  600000, 10000);
106 static struct regulator_range fan_0_13_range =
107    REG_RANGE_INIT(  0, 0x3F,  800000, 10000);
108 static struct regulator_range fan_1_range =
109    REG_RANGE_INIT(  0, 0x3F,  600000, 10000);
110 static struct regulator_range fan_4_range =
111    REG_RANGE_INIT(  0, 0x3F,  603000, 12826);
112 
113 
114 static int
115 fan53555_read(device_t dev, uint8_t reg, uint8_t *val)
116 {
117 	uint8_t addr;
118 	int rv;
119 	struct iic_msg msgs[2] = {
120 		{0, IIC_M_WR | IIC_M_NOSTOP, 1, &addr},
121 		{0, IIC_M_RD, 1, val},
122 	};
123 
124 	msgs[0].slave = iicbus_get_addr(dev);
125 	msgs[1].slave = iicbus_get_addr(dev);
126 	addr = reg;
127 
128 	rv = iicbus_transfer_excl(dev, msgs, 2, IIC_INTRWAIT);
129 	if (rv != 0) {
130 		device_printf(dev, "Error when reading reg 0x%02X, rv: %d\n",
131 		    reg,  rv);
132 		return (EIO);
133 	}
134 
135 	return (0);
136 }
137 
138 static int
139 fan53555_write(device_t dev, uint8_t reg, uint8_t val)
140 {
141 	uint8_t data[2];
142 	int rv;
143 
144 	struct iic_msg msgs[1] = {
145 		{0, IIC_M_WR, 2, data},
146 	};
147 
148 	msgs[0].slave = iicbus_get_addr(dev);
149 	data[0] = reg;
150 	data[1] = val;
151 
152 	rv = iicbus_transfer_excl(dev, msgs, 1, IIC_INTRWAIT);
153 	if (rv != 0) {
154 		device_printf(dev,
155 		    "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
156 		return (EIO);
157 	}
158 	return (0);
159 }
160 
161 static int
162 fan53555_read_sel(struct fan53555_reg_sc *sc, uint8_t *sel)
163 {
164 	int rv;
165 
166 	rv = fan53555_read(sc->base_dev, sc->live_reg, sel);
167 	if (rv != 0)
168 		return (rv);
169 	*sel &= FAN53555_VSEL_MASK;
170 	return (0);
171 }
172 
173 static int
174 fan53555_write_sel(struct fan53555_reg_sc *sc, uint8_t sel)
175 {
176 	int rv;
177 	uint8_t reg;
178 
179 	rv = fan53555_read(sc->base_dev, sc->live_reg, &reg);
180 	if (rv != 0)
181 		return (rv);
182 	reg &= ~FAN53555_VSEL_MASK;
183 	reg |= sel;
184 
185 	rv = fan53555_write(sc->base_dev, sc->live_reg, reg);
186 	if (rv != 0)
187 		return (rv);
188 	return (rv);
189 }
190 
191 static int
192 fan53555_regnode_init(struct regnode *regnode)
193 {
194 	return (0);
195 }
196 
197 static int
198 fan53555_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
199 {
200 	struct fan53555_reg_sc *sc;
201 	uint8_t val;
202 
203 	sc = regnode_get_softc(regnode);
204 
205 	dprintf(sc, "%sabling regulator %s\n", enable ? "En" : "Dis",
206 	    sc->name);
207 	fan53555_read(sc->base_dev, sc->live_reg, &val);
208 	if (enable)
209 		val |=FAN53555_VSEL_ENA;
210 	else
211 		val &= ~FAN53555_VSEL_ENA;
212 	fan53555_write(sc->base_dev, sc->live_reg, val);
213 
214 	*udelay = sc->param->enable_delay;
215 	return (0);
216 }
217 
218 
219 static int
220 fan53555_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
221     int max_uvolt, int *udelay)
222 {
223 	struct fan53555_reg_sc *sc;
224 	uint8_t sel;
225 	int uvolt, rv;
226 
227 	sc = regnode_get_softc(regnode);
228 
229 	dprintf(sc, "Setting %s to %d<->%d uvolts\n", sc->name, min_uvolt,
230 	    max_uvolt);
231 	rv = regulator_range_volt_to_sel8(sc->range, 1, min_uvolt, max_uvolt,
232 	    &sel);
233 	if (rv != 0)
234 		return (rv);
235 	*udelay = sc->param->ramp_delay;
236 	rv = fan53555_write_sel(sc, sel);
237 	dprintf(sc, "Regulator %s writing sel: 0x%02X\n", sc->name, sel);
238 
239 	fan53555_read_sel(sc, &sel);
240 	regulator_range_sel8_to_volt(sc->range, 1, sel, &uvolt);
241 	dprintf(sc, "Regulator %s set to %d uvolt (sel: 0x%02X)\n", sc->name,
242 	    uvolt, sel);
243 
244 	return (rv);
245 }
246 
247 static int
248 fan53555_regnode_get_voltage(struct regnode *regnode, int *uvolt)
249 {
250 	struct fan53555_reg_sc *sc;
251 	uint8_t sel;
252 	int rv;
253 
254 	sc = regnode_get_softc(regnode);
255 
256 	rv = fan53555_read_sel(sc, &sel);
257 	if (rv != 0)
258 		return (rv);
259 	rv = regulator_range_sel8_to_volt(sc->range, 1, sel, uvolt);
260 	dprintf(sc, "Regulator %s is at %d uvolt ((sel: 0x%02X)\n", sc->name,
261 	    *uvolt, sel);
262 
263 	return (rv);
264 }
265 
266 static regnode_method_t fan53555_regnode_methods[] = {
267 	/* Regulator interface */
268 	REGNODEMETHOD(regnode_init,		fan53555_regnode_init),
269 	REGNODEMETHOD(regnode_enable,		fan53555_regnode_enable),
270 	REGNODEMETHOD(regnode_set_voltage,	fan53555_regnode_set_voltage),
271 	REGNODEMETHOD(regnode_get_voltage,	fan53555_regnode_get_voltage),
272 	REGNODEMETHOD_END
273 };
274 DEFINE_CLASS_1(fan53555_regnode, fan53555_regnode_class,
275     fan53555_regnode_methods, sizeof(struct fan53555_reg_sc), regnode_class);
276 
277 static struct regulator_range *
278 fan53555_get_range(struct fan53555_softc *sc, int type, uint8_t id,
279     uint8_t rev)
280 {
281 	if (type == SYR827 || type == SYR828) {
282 		switch (id) {
283 		case 8:
284 			return (&syr_8_range);
285 		default:
286 			return (NULL);
287 		}
288 	}
289 
290 	if (type == FAN53555) {
291 		switch (id) {
292 		case 0:
293 			if (rev == 0)
294 				return (&fan_0_0_range);
295 			else if (rev == 13)
296 				return (&fan_0_13_range);
297 			else
298 				return (NULL);
299 		case 1:
300 		case 3:
301 		case 5:
302 		case 8:
303 			return (&fan_1_range);
304 		case 4:
305 			return (&fan_4_range);
306 		default:
307 			return (NULL);
308 		}
309 	}
310 
311 	return (NULL);
312 }
313 
314 static struct fan53555_reg_sc *
315 fan53555_reg_attach(struct fan53555_softc *sc, phandle_t node, int  type)
316 {
317 	struct fan53555_reg_sc *reg_sc;
318 	struct regnode_init_def initdef;
319 	struct regnode *regnode;
320 	static struct regulator_range *range;
321 	uint8_t id1, id2;
322 
323 	memset(&initdef, 0, sizeof(initdef));
324 	if (regulator_parse_ofw_stdparam(sc->dev, node, &initdef) != 0) {
325 		device_printf(sc->dev, "cannot parse regulator FDT data\n");
326 		return (NULL);
327 	}
328 
329 	if (fan53555_read(sc->dev, FAN53555_ID1, &id1) != 0) {
330 		device_printf(sc->dev, "cannot read ID1\n");
331 		return (NULL);
332 	}
333 
334 	if (fan53555_read(sc->dev, FAN53555_ID2, &id2) != 0) {
335 		device_printf(sc->dev, "cannot read ID2\n");
336 		return (NULL);
337 	}
338 	dprintf(sc, "Device ID1: 0x%02X, ID2: 0x%02X\n", id1, id2);
339 
340 	range = fan53555_get_range(sc, type, FAN53555_ID1_DIE_ID(id1),
341 	     FAN53555_ID2_DIE_REV(id2));
342 	if (range == NULL) {
343 		device_printf(sc->dev,
344 		    "cannot determine chip type (ID1: 0x%02X, ID2: 0x%02X)\n",
345 		    id1, id2);
346 		return (NULL);
347 	}
348 
349 	initdef.id = 1;
350 	initdef.ofw_node = node;
351 
352 	regnode = regnode_create(sc->dev, &fan53555_regnode_class, &initdef);
353 	if (regnode == NULL) {
354 		device_printf(sc->dev, "cannot create regulator\n");
355 		return (NULL);
356 	}
357 
358 	reg_sc = regnode_get_softc(regnode);
359 	reg_sc->name = "fan53555";
360 	reg_sc->regnode = regnode;
361 	reg_sc->base_dev = sc->dev;
362 	reg_sc->param = regnode_get_stdparam(regnode);
363 	reg_sc->range = range;
364 	reg_sc->live_reg = sc->live_reg;
365 	reg_sc->sleep_reg = sc->sleep_reg;
366 
367 	dprintf(sc->dev, "live_reg: %d, sleep_reg: %d\n", reg_sc->live_reg,
368 	    reg_sc->sleep_reg);
369 
370 	regnode_register(regnode);
371 
372 	if (bootverbose) {
373 		int volt, rv;
374 		regnode_topo_slock();
375 		rv = regnode_get_voltage(regnode, &volt);
376 		if (rv == ENODEV) {
377 			device_printf(sc->dev,
378 			   " Regulator %s: parent doesn't exist yet.\n",
379 			   regnode_get_name(regnode));
380 		} else if (rv != 0) {
381 			device_printf(sc->dev,
382 			   " Regulator %s: voltage: INVALID!!!\n",
383 			   regnode_get_name(regnode));
384 		} else {
385 			device_printf(sc->dev,
386 			    " Regulator %s: voltage: %d uV\n",
387 			    regnode_get_name(regnode), volt);
388 		}
389 		regnode_topo_unlock();
390 	}
391 
392 	return (reg_sc);
393 }
394 
395 static int
396 fan53555_probe(device_t dev)
397 {
398 	int type;
399 
400 	if (!ofw_bus_status_okay(dev))
401 		return (ENXIO);
402 
403 	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
404 	switch (type) {
405 	case FAN53555:
406 		device_set_desc(dev, "FAN53555 PMIC");
407 		break;
408 	case SYR827:
409 		device_set_desc(dev, "SYR827 PMIC");
410 		break;
411 	case SYR828:
412 		device_set_desc(dev, "SYR828 PMIC");
413 		break;
414 	default:
415 		return (ENXIO);
416 	}
417 
418 	return (BUS_PROBE_DEFAULT);
419 }
420 
421 static int
422 fan53555_attach(device_t dev)
423 {
424 	struct fan53555_softc *sc;
425 	phandle_t node;
426 	int type, susp_sel, rv;
427 
428 	sc = device_get_softc(dev);
429 	sc->dev = dev;
430 	node = ofw_bus_get_node(dev);
431 	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
432 
433 	rv = OF_getencprop(node, "fcs,suspend-voltage-selector", &susp_sel,
434 		sizeof(susp_sel));
435 	if (rv <= 0)
436 		susp_sel = 1;
437 	if (susp_sel == 1) {
438 		sc->live_reg = FAN53555_VSEL0;
439 		sc->sleep_reg = FAN53555_VSEL1;
440 	} else {
441 		sc->live_reg = FAN53555_VSEL1;
442 		sc->sleep_reg = FAN53555_VSEL0;
443 	}
444 	if (fan53555_reg_attach(sc, node, type) == NULL)
445 		device_printf(dev, "cannot attach regulator.\n");
446 
447 	return (0);
448 }
449 
450 static int
451 fan53555_detach(device_t dev)
452 {
453 
454 	/* We cannot detach regulators */
455 	return (EBUSY);
456 }
457 
458 static device_method_t fan53555_methods[] = {
459 	DEVMETHOD(device_probe,		fan53555_probe),
460 	DEVMETHOD(device_attach,	fan53555_attach),
461 	DEVMETHOD(device_detach,	fan53555_detach),
462 
463 	/* Regdev interface */
464 	DEVMETHOD(regdev_map,		regdev_default_ofw_map),
465 
466 	DEVMETHOD_END
467 };
468 
469 static devclass_t fan53555_devclass;
470 static DEFINE_CLASS_0(fan53555_pmic, fan53555_driver, fan53555_methods,
471     sizeof(struct fan53555_softc));
472 
473 EARLY_DRIVER_MODULE(fan53555, iicbus, fan53555_driver, fan53555_devclass, 0, 0,
474     BUS_PASS_RESOURCE);
475 MODULE_VERSION(fan53555, 1);
476 MODULE_DEPEND(fan53555, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
477 IICBUS_FDT_PNP_INFO(compat_data);
478