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