xref: /freebsd/sys/dev/iicbus/pmic/fan53555.c (revision 535af610)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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) & 0x0F)
60 #define	FAN53555_ID2		0x04
61 #define	 FAN53555_ID2_DIE_REV(x)	((x) & 0x0F)
62 #define	FAN53555_MON		0x05
63 
64 #define	TCS4525_VSEL0		0x11
65 #define	TCS4525_VSEL1		0x10
66 #define	TCS4525_CHIP_ID_12	12
67 
68 #if 0
69 #define	dprintf(sc, format, arg...)					\
70 	device_printf(sc->base_dev, "%s: " format, __func__, arg)
71 #else
72 #define	dprintf(sc, format, arg...)
73 #endif
74 
75 enum fan53555_pmic_type {
76 	FAN53555 = 1,
77 	SYR827,
78 	SYR828,
79 	TCS4525,
80 };
81 
82 static struct ofw_compat_data compat_data[] = {
83 	{"fcs,fan53555", 	FAN53555},
84 	{"silergy,syr827",	SYR827},
85 	{"silergy,syr828",	SYR828},
86 	{"tcs,tcs4525",		TCS4525},
87 	{NULL,		0}
88 };
89 
90 struct fan53555_reg_sc {
91 	struct regnode		*regnode;
92 	char			*name;
93 	device_t		base_dev;
94 	uint8_t			live_reg;
95 	uint8_t			sleep_reg;
96 	struct regulator_range	*range;
97 	struct regnode_std_param *param;
98 };
99 
100 struct fan53555_softc {
101 	device_t		dev;
102 	uint8_t			live_reg;
103 	uint8_t			sleep_reg;
104 };
105 
106 static struct regulator_range syr_8_range =
107    REG_RANGE_INIT(  0, 0x3F,  712500, 12500);
108 
109 static struct regulator_range fan_0_0_range =
110    REG_RANGE_INIT(  0, 0x3F,  600000, 10000);
111 static struct regulator_range fan_0_13_range =
112    REG_RANGE_INIT(  0, 0x3F,  800000, 10000);
113 static struct regulator_range fan_1_range =
114    REG_RANGE_INIT(  0, 0x3F,  600000, 10000);
115 static struct regulator_range fan_4_range =
116    REG_RANGE_INIT(  0, 0x3F,  603000, 12826);
117 
118 static struct regulator_range tcs_12_range =
119    REG_RANGE_INIT(  0, 0x3F,  800000, 6250);
120 
121 static int
122 fan53555_read(device_t dev, uint8_t reg, uint8_t *val)
123 {
124 	uint8_t addr;
125 	int rv;
126 	struct iic_msg msgs[2] = {
127 		{0, IIC_M_WR | IIC_M_NOSTOP, 1, &addr},
128 		{0, IIC_M_RD, 1, val},
129 	};
130 
131 	msgs[0].slave = iicbus_get_addr(dev);
132 	msgs[1].slave = iicbus_get_addr(dev);
133 	addr = reg;
134 
135 	rv = iicbus_transfer_excl(dev, msgs, 2, IIC_INTRWAIT);
136 	if (rv != 0) {
137 		device_printf(dev, "Error when reading reg 0x%02X, rv: %d\n",
138 		    reg,  rv);
139 		return (EIO);
140 	}
141 
142 	return (0);
143 }
144 
145 static int
146 fan53555_write(device_t dev, uint8_t reg, uint8_t val)
147 {
148 	uint8_t data[2];
149 	int rv;
150 
151 	struct iic_msg msgs[1] = {
152 		{0, IIC_M_WR, 2, data},
153 	};
154 
155 	msgs[0].slave = iicbus_get_addr(dev);
156 	data[0] = reg;
157 	data[1] = val;
158 
159 	rv = iicbus_transfer_excl(dev, msgs, 1, IIC_INTRWAIT);
160 	if (rv != 0) {
161 		device_printf(dev,
162 		    "Error when writing reg 0x%02X, rv: %d\n", reg, rv);
163 		return (EIO);
164 	}
165 	return (0);
166 }
167 
168 static int
169 fan53555_read_sel(struct fan53555_reg_sc *sc, uint8_t *sel)
170 {
171 	int rv;
172 
173 	rv = fan53555_read(sc->base_dev, sc->live_reg, sel);
174 	if (rv != 0)
175 		return (rv);
176 	*sel &= FAN53555_VSEL_MASK;
177 	return (0);
178 }
179 
180 static int
181 fan53555_write_sel(struct fan53555_reg_sc *sc, uint8_t sel)
182 {
183 	int rv;
184 	uint8_t reg;
185 
186 	rv = fan53555_read(sc->base_dev, sc->live_reg, &reg);
187 	if (rv != 0)
188 		return (rv);
189 	reg &= ~FAN53555_VSEL_MASK;
190 	reg |= sel;
191 
192 	rv = fan53555_write(sc->base_dev, sc->live_reg, reg);
193 	if (rv != 0)
194 		return (rv);
195 	return (rv);
196 }
197 
198 static int
199 fan53555_regnode_init(struct regnode *regnode)
200 {
201 	return (0);
202 }
203 
204 static int
205 fan53555_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
206 {
207 	struct fan53555_reg_sc *sc;
208 	uint8_t val;
209 
210 	sc = regnode_get_softc(regnode);
211 
212 	dprintf(sc, "%sabling regulator %s\n", enable ? "En" : "Dis",
213 	    sc->name);
214 	fan53555_read(sc->base_dev, sc->live_reg, &val);
215 	if (enable)
216 		val |=FAN53555_VSEL_ENA;
217 	else
218 		val &= ~FAN53555_VSEL_ENA;
219 	fan53555_write(sc->base_dev, sc->live_reg, val);
220 
221 	*udelay = sc->param->enable_delay;
222 	return (0);
223 }
224 
225 
226 static int
227 fan53555_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
228     int max_uvolt, int *udelay)
229 {
230 	struct fan53555_reg_sc *sc;
231 	uint8_t sel;
232 	int uvolt, rv;
233 
234 	sc = regnode_get_softc(regnode);
235 
236 	dprintf(sc, "Setting %s to %d<->%d uvolts\n", sc->name, min_uvolt,
237 	    max_uvolt);
238 	rv = regulator_range_volt_to_sel8(sc->range, 1, min_uvolt, max_uvolt,
239 	    &sel);
240 	if (rv != 0)
241 		return (rv);
242 	*udelay = sc->param->ramp_delay;
243 	rv = fan53555_write_sel(sc, sel);
244 	dprintf(sc, "Regulator %s writing sel: 0x%02X\n", sc->name, sel);
245 
246 	fan53555_read_sel(sc, &sel);
247 	regulator_range_sel8_to_volt(sc->range, 1, sel, &uvolt);
248 	dprintf(sc, "Regulator %s set to %d uvolt (sel: 0x%02X)\n", sc->name,
249 	    uvolt, sel);
250 
251 	return (rv);
252 }
253 
254 static int
255 fan53555_regnode_get_voltage(struct regnode *regnode, int *uvolt)
256 {
257 	struct fan53555_reg_sc *sc;
258 	uint8_t sel;
259 	int rv;
260 
261 	sc = regnode_get_softc(regnode);
262 
263 	rv = fan53555_read_sel(sc, &sel);
264 	if (rv != 0)
265 		return (rv);
266 	rv = regulator_range_sel8_to_volt(sc->range, 1, sel, uvolt);
267 	dprintf(sc, "Regulator %s is at %d uvolt ((sel: 0x%02X)\n", sc->name,
268 	    *uvolt, sel);
269 
270 	return (rv);
271 }
272 
273 static regnode_method_t fan53555_regnode_methods[] = {
274 	/* Regulator interface */
275 	REGNODEMETHOD(regnode_init,		fan53555_regnode_init),
276 	REGNODEMETHOD(regnode_enable,		fan53555_regnode_enable),
277 	REGNODEMETHOD(regnode_set_voltage,	fan53555_regnode_set_voltage),
278 	REGNODEMETHOD(regnode_get_voltage,	fan53555_regnode_get_voltage),
279 	REGNODEMETHOD_END
280 };
281 DEFINE_CLASS_1(fan53555_regnode, fan53555_regnode_class,
282     fan53555_regnode_methods, sizeof(struct fan53555_reg_sc), regnode_class);
283 
284 static struct regulator_range *
285 fan53555_get_range(struct fan53555_softc *sc, int type, uint8_t id,
286     uint8_t rev)
287 {
288 	if (type == SYR827 || type == SYR828) {
289 		switch (id) {
290 		case 8:
291 			return (&syr_8_range);
292 		default:
293 			return (NULL);
294 		}
295 	}
296 
297 	if (type == FAN53555) {
298 		switch (id) {
299 		case 0:
300 			if (rev == 0)
301 				return (&fan_0_0_range);
302 			else if (rev == 13)
303 				return (&fan_0_13_range);
304 			else
305 				return (NULL);
306 		case 1:
307 		case 3:
308 		case 5:
309 		case 8:
310 			return (&fan_1_range);
311 		case 4:
312 			return (&fan_4_range);
313 		default:
314 			return (NULL);
315 		}
316 	}
317 
318 	if (type == TCS4525) {
319 		switch (id) {
320 		case TCS4525_CHIP_ID_12:
321 			return (&tcs_12_range);
322 		default:
323 			return (NULL);
324 		}
325 	}
326 
327 	return (NULL);
328 }
329 
330 static struct fan53555_reg_sc *
331 fan53555_reg_attach(struct fan53555_softc *sc, phandle_t node, int  type)
332 {
333 	struct fan53555_reg_sc *reg_sc;
334 	struct regnode_init_def initdef;
335 	struct regnode *regnode;
336 	static struct regulator_range *range;
337 	uint8_t id1, id2;
338 
339 	memset(&initdef, 0, sizeof(initdef));
340 	if (regulator_parse_ofw_stdparam(sc->dev, node, &initdef) != 0) {
341 		device_printf(sc->dev, "cannot parse regulator FDT data\n");
342 		return (NULL);
343 	}
344 
345 	if (fan53555_read(sc->dev, FAN53555_ID1, &id1) != 0) {
346 		device_printf(sc->dev, "cannot read ID1\n");
347 		return (NULL);
348 	}
349 
350 	if (fan53555_read(sc->dev, FAN53555_ID2, &id2) != 0) {
351 		device_printf(sc->dev, "cannot read ID2\n");
352 		return (NULL);
353 	}
354 	dprintf(sc, "Device ID1: 0x%02X, ID2: 0x%02X\n", id1, id2);
355 
356 	range = fan53555_get_range(sc, type, FAN53555_ID1_DIE_ID(id1),
357 	     FAN53555_ID2_DIE_REV(id2));
358 	if (range == NULL) {
359 		device_printf(sc->dev,
360 		    "cannot determine chip type (ID1: 0x%02X, ID2: 0x%02X)\n",
361 		    id1, id2);
362 		return (NULL);
363 	}
364 
365 	initdef.id = 1;
366 	initdef.ofw_node = node;
367 
368 	regnode = regnode_create(sc->dev, &fan53555_regnode_class, &initdef);
369 	if (regnode == NULL) {
370 		device_printf(sc->dev, "cannot create regulator\n");
371 		return (NULL);
372 	}
373 
374 	reg_sc = regnode_get_softc(regnode);
375 	reg_sc->name = "fan53555";
376 	reg_sc->regnode = regnode;
377 	reg_sc->base_dev = sc->dev;
378 	reg_sc->param = regnode_get_stdparam(regnode);
379 	reg_sc->range = range;
380 	reg_sc->live_reg = sc->live_reg;
381 	reg_sc->sleep_reg = sc->sleep_reg;
382 
383 	dprintf(sc->dev, "live_reg: %d, sleep_reg: %d\n", reg_sc->live_reg,
384 	    reg_sc->sleep_reg);
385 
386 	regnode_register(regnode);
387 
388 	if (bootverbose) {
389 		int volt, rv;
390 		regnode_topo_slock();
391 		rv = regnode_get_voltage(regnode, &volt);
392 		if (rv == ENODEV) {
393 			device_printf(sc->dev,
394 			   " Regulator %s: parent doesn't exist yet.\n",
395 			   regnode_get_name(regnode));
396 		} else if (rv != 0) {
397 			device_printf(sc->dev,
398 			   " Regulator %s: voltage: INVALID!!!\n",
399 			   regnode_get_name(regnode));
400 		} else {
401 			device_printf(sc->dev,
402 			    " Regulator %s: voltage: %d uV\n",
403 			    regnode_get_name(regnode), volt);
404 		}
405 		regnode_topo_unlock();
406 	}
407 
408 	return (reg_sc);
409 }
410 
411 static int
412 fan53555_probe(device_t dev)
413 {
414 	int type;
415 
416 	if (!ofw_bus_status_okay(dev))
417 		return (ENXIO);
418 
419 	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
420 	switch (type) {
421 	case FAN53555:
422 		device_set_desc(dev, "FAN53555 PMIC");
423 		break;
424 	case SYR827:
425 		device_set_desc(dev, "SYR827 PMIC");
426 		break;
427 	case SYR828:
428 		device_set_desc(dev, "SYR828 PMIC");
429 		break;
430 	case TCS4525:
431 		device_set_desc(dev, "TCS4525 PMIC");
432 		break;
433 	default:
434 		return (ENXIO);
435 	}
436 
437 	return (BUS_PROBE_DEFAULT);
438 }
439 
440 static int
441 fan53555_attach(device_t dev)
442 {
443 	struct fan53555_softc *sc;
444 	phandle_t node;
445 	int type, susp_sel, rv;
446 
447 	sc = device_get_softc(dev);
448 	sc->dev = dev;
449 	node = ofw_bus_get_node(dev);
450 	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
451 
452 	rv = OF_getencprop(node, "fcs,suspend-voltage-selector", &susp_sel,
453 		sizeof(susp_sel));
454 	if (rv <= 0)
455 		susp_sel = 1;
456 
457 	switch (type) {
458 	case FAN53555:
459 	case SYR827:
460 	case SYR828:
461 		if (susp_sel == 1) {
462 			sc->live_reg = FAN53555_VSEL0;
463 			sc->sleep_reg = FAN53555_VSEL1;
464 		} else {
465 			sc->live_reg = FAN53555_VSEL1;
466 			sc->sleep_reg = FAN53555_VSEL0;
467 		}
468 		break;
469 	case TCS4525:
470 		if (susp_sel == 1) {
471 			sc->live_reg = TCS4525_VSEL0;
472 			sc->sleep_reg = TCS4525_VSEL1;
473 		} else {
474 			sc->live_reg = TCS4525_VSEL1;
475 			sc->sleep_reg = TCS4525_VSEL0;
476 		}
477 		break;
478 	default:
479 		return (ENXIO);
480 	}
481 	if (fan53555_reg_attach(sc, node, type) == NULL)
482 		device_printf(dev, "cannot attach regulator.\n");
483 
484 	return (0);
485 }
486 
487 static int
488 fan53555_detach(device_t dev)
489 {
490 
491 	/* We cannot detach regulators */
492 	return (EBUSY);
493 }
494 
495 static device_method_t fan53555_methods[] = {
496 	DEVMETHOD(device_probe,		fan53555_probe),
497 	DEVMETHOD(device_attach,	fan53555_attach),
498 	DEVMETHOD(device_detach,	fan53555_detach),
499 
500 	/* Regdev interface */
501 	DEVMETHOD(regdev_map,		regdev_default_ofw_map),
502 
503 	DEVMETHOD_END
504 };
505 
506 static DEFINE_CLASS_0(fan53555_pmic, fan53555_driver, fan53555_methods,
507     sizeof(struct fan53555_softc));
508 
509 EARLY_DRIVER_MODULE(fan53555, iicbus, fan53555_driver, 0, 0, BUS_PASS_RESOURCE);
510 MODULE_VERSION(fan53555, 1);
511 MODULE_DEPEND(fan53555, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
512 IICBUS_FDT_PNP_INFO(compat_data);
513