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