xref: /openbmc/u-boot/drivers/power/pmic/fan53555.c (revision d94604d5)
1*dfb0a70aSPhilipp Tomsich // SPDX-License-Identifier: GPL-2.0+
2*dfb0a70aSPhilipp Tomsich /*
3*dfb0a70aSPhilipp Tomsich  * (C) 2018 Theobroma Systems Design und Consulting GmbH
4*dfb0a70aSPhilipp Tomsich  */
5*dfb0a70aSPhilipp Tomsich 
6*dfb0a70aSPhilipp Tomsich #include <common.h>
7*dfb0a70aSPhilipp Tomsich #include <dm.h>
8*dfb0a70aSPhilipp Tomsich #include <dm/device-internal.h>
9*dfb0a70aSPhilipp Tomsich #include <dm/lists.h>
10*dfb0a70aSPhilipp Tomsich #include <i2c.h>
11*dfb0a70aSPhilipp Tomsich #include <power/pmic.h>
12*dfb0a70aSPhilipp Tomsich #include <power/regulator.h>
13*dfb0a70aSPhilipp Tomsich 
pmic_fan53555_reg_count(struct udevice * dev)14*dfb0a70aSPhilipp Tomsich static int pmic_fan53555_reg_count(struct udevice *dev)
15*dfb0a70aSPhilipp Tomsich {
16*dfb0a70aSPhilipp Tomsich 	return 1;
17*dfb0a70aSPhilipp Tomsich };
18*dfb0a70aSPhilipp Tomsich 
pmic_fan53555_read(struct udevice * dev,uint reg,u8 * buff,int len)19*dfb0a70aSPhilipp Tomsich static int pmic_fan53555_read(struct udevice *dev, uint reg,
20*dfb0a70aSPhilipp Tomsich 			      u8 *buff, int len)
21*dfb0a70aSPhilipp Tomsich {
22*dfb0a70aSPhilipp Tomsich 	if (dm_i2c_read(dev, reg, buff, len)) {
23*dfb0a70aSPhilipp Tomsich 		pr_err("%s: read error for register: %#x!", dev->name, reg);
24*dfb0a70aSPhilipp Tomsich 		return -EIO;
25*dfb0a70aSPhilipp Tomsich 	}
26*dfb0a70aSPhilipp Tomsich 
27*dfb0a70aSPhilipp Tomsich 	return 0;
28*dfb0a70aSPhilipp Tomsich }
29*dfb0a70aSPhilipp Tomsich 
pmic_fan53555_write(struct udevice * dev,uint reg,const u8 * buff,int len)30*dfb0a70aSPhilipp Tomsich static int pmic_fan53555_write(struct udevice *dev, uint reg,
31*dfb0a70aSPhilipp Tomsich 			       const u8 *buff, int len)
32*dfb0a70aSPhilipp Tomsich {
33*dfb0a70aSPhilipp Tomsich 	if (dm_i2c_write(dev, reg, buff, len)) {
34*dfb0a70aSPhilipp Tomsich 		pr_err("%s: write error for register: %#x!", dev->name, reg);
35*dfb0a70aSPhilipp Tomsich 		return -EIO;
36*dfb0a70aSPhilipp Tomsich 	}
37*dfb0a70aSPhilipp Tomsich 
38*dfb0a70aSPhilipp Tomsich 	return 0;
39*dfb0a70aSPhilipp Tomsich }
40*dfb0a70aSPhilipp Tomsich 
pmic_fan53555_bind(struct udevice * dev)41*dfb0a70aSPhilipp Tomsich static int pmic_fan53555_bind(struct udevice *dev)
42*dfb0a70aSPhilipp Tomsich {
43*dfb0a70aSPhilipp Tomsich 	/*
44*dfb0a70aSPhilipp Tomsich 	 * The FAN53555 has only a single regulator and therefore doesn't
45*dfb0a70aSPhilipp Tomsich 	 * have a subnode.  So we have to rebind a child device (the one
46*dfb0a70aSPhilipp Tomsich 	 * regulator) here.
47*dfb0a70aSPhilipp Tomsich 	 */
48*dfb0a70aSPhilipp Tomsich 
49*dfb0a70aSPhilipp Tomsich 	const char *regulator_driver_name = "fan53555_regulator";
50*dfb0a70aSPhilipp Tomsich 	struct udevice *child;
51*dfb0a70aSPhilipp Tomsich 	struct driver *drv;
52*dfb0a70aSPhilipp Tomsich 
53*dfb0a70aSPhilipp Tomsich 	debug("%s\n", __func__);
54*dfb0a70aSPhilipp Tomsich 
55*dfb0a70aSPhilipp Tomsich 	drv = lists_driver_lookup_name(regulator_driver_name);
56*dfb0a70aSPhilipp Tomsich 	if (!drv) {
57*dfb0a70aSPhilipp Tomsich 		dev_err(dev, "no driver '%s'\n", regulator_driver_name);
58*dfb0a70aSPhilipp Tomsich 		return -ENOENT;
59*dfb0a70aSPhilipp Tomsich 	}
60*dfb0a70aSPhilipp Tomsich 
61*dfb0a70aSPhilipp Tomsich 	return device_bind_with_driver_data(dev, drv, "SW", 0,
62*dfb0a70aSPhilipp Tomsich 					    dev_ofnode(dev), &child);
63*dfb0a70aSPhilipp Tomsich };
64*dfb0a70aSPhilipp Tomsich 
65*dfb0a70aSPhilipp Tomsich static struct dm_pmic_ops pmic_fan53555_ops = {
66*dfb0a70aSPhilipp Tomsich 	.reg_count = pmic_fan53555_reg_count,
67*dfb0a70aSPhilipp Tomsich 	.read = pmic_fan53555_read,
68*dfb0a70aSPhilipp Tomsich 	.write = pmic_fan53555_write,
69*dfb0a70aSPhilipp Tomsich };
70*dfb0a70aSPhilipp Tomsich 
71*dfb0a70aSPhilipp Tomsich static const struct udevice_id pmic_fan53555_match[] = {
72*dfb0a70aSPhilipp Tomsich 	{ .compatible = "fcs,fan53555" },
73*dfb0a70aSPhilipp Tomsich 	{ },
74*dfb0a70aSPhilipp Tomsich };
75*dfb0a70aSPhilipp Tomsich 
76*dfb0a70aSPhilipp Tomsich U_BOOT_DRIVER(pmic_fan53555) = {
77*dfb0a70aSPhilipp Tomsich 	.name = "pmic_fan53555",
78*dfb0a70aSPhilipp Tomsich 	.id = UCLASS_PMIC,
79*dfb0a70aSPhilipp Tomsich 	.of_match = pmic_fan53555_match,
80*dfb0a70aSPhilipp Tomsich 	.bind = pmic_fan53555_bind,
81*dfb0a70aSPhilipp Tomsich 	.ops = &pmic_fan53555_ops,
82*dfb0a70aSPhilipp Tomsich };
83