xref: /openbmc/u-boot/drivers/power/pmic/palmas.c (revision 33621d247e771168ebaab2218d02e625371d144a)
1*33621d24SKeerthy /*
2*33621d24SKeerthy  * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
3*33621d24SKeerthy  * Keerthy <j-keerthy@ti.com>
4*33621d24SKeerthy  *
5*33621d24SKeerthy  * SPDX-License-Identifier:	GPL-2.0+
6*33621d24SKeerthy  */
7*33621d24SKeerthy 
8*33621d24SKeerthy #include <common.h>
9*33621d24SKeerthy #include <fdtdec.h>
10*33621d24SKeerthy #include <errno.h>
11*33621d24SKeerthy #include <dm.h>
12*33621d24SKeerthy #include <i2c.h>
13*33621d24SKeerthy #include <power/pmic.h>
14*33621d24SKeerthy #include <power/regulator.h>
15*33621d24SKeerthy #include <power/palmas.h>
16*33621d24SKeerthy #include <dm/device.h>
17*33621d24SKeerthy 
18*33621d24SKeerthy DECLARE_GLOBAL_DATA_PTR;
19*33621d24SKeerthy 
20*33621d24SKeerthy static const struct pmic_child_info pmic_children_info[] = {
21*33621d24SKeerthy 	{ .prefix = "ldo", .driver = PALMAS_LDO_DRIVER },
22*33621d24SKeerthy 	{ .prefix = "smps", .driver = PALMAS_SMPS_DRIVER },
23*33621d24SKeerthy 	{ },
24*33621d24SKeerthy };
25*33621d24SKeerthy 
26*33621d24SKeerthy static int palmas_write(struct udevice *dev, uint reg, const uint8_t *buff,
27*33621d24SKeerthy 			  int len)
28*33621d24SKeerthy {
29*33621d24SKeerthy 	if (dm_i2c_write(dev, reg, buff, len)) {
30*33621d24SKeerthy 		error("write error to device: %p register: %#x!", dev, reg);
31*33621d24SKeerthy 		return -EIO;
32*33621d24SKeerthy 	}
33*33621d24SKeerthy 
34*33621d24SKeerthy 	return 0;
35*33621d24SKeerthy }
36*33621d24SKeerthy 
37*33621d24SKeerthy static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
38*33621d24SKeerthy {
39*33621d24SKeerthy 	if (dm_i2c_read(dev, reg, buff, len)) {
40*33621d24SKeerthy 		error("read error from device: %p register: %#x!", dev, reg);
41*33621d24SKeerthy 		return -EIO;
42*33621d24SKeerthy 	}
43*33621d24SKeerthy 
44*33621d24SKeerthy 	return 0;
45*33621d24SKeerthy }
46*33621d24SKeerthy 
47*33621d24SKeerthy static int palmas_bind(struct udevice *dev)
48*33621d24SKeerthy {
49*33621d24SKeerthy 	int pmic_node = -1, regulators_node;
50*33621d24SKeerthy 	const void *blob = gd->fdt_blob;
51*33621d24SKeerthy 	int children;
52*33621d24SKeerthy 	int node = dev->of_offset;
53*33621d24SKeerthy 	int subnode, len;
54*33621d24SKeerthy 
55*33621d24SKeerthy 	fdt_for_each_subnode(blob, subnode, node) {
56*33621d24SKeerthy 		const char *name;
57*33621d24SKeerthy 		char *temp;
58*33621d24SKeerthy 
59*33621d24SKeerthy 		name = fdt_get_name(blob, subnode, &len);
60*33621d24SKeerthy 		temp = strstr(name, "pmic");
61*33621d24SKeerthy 		if (temp) {
62*33621d24SKeerthy 			pmic_node = subnode;
63*33621d24SKeerthy 			break;
64*33621d24SKeerthy 		}
65*33621d24SKeerthy 	}
66*33621d24SKeerthy 
67*33621d24SKeerthy 	if (pmic_node <= 0) {
68*33621d24SKeerthy 		debug("%s: %s pmic subnode not found!", __func__, dev->name);
69*33621d24SKeerthy 		return -ENXIO;
70*33621d24SKeerthy 	}
71*33621d24SKeerthy 
72*33621d24SKeerthy 	regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators");
73*33621d24SKeerthy 
74*33621d24SKeerthy 	if (regulators_node <= 0) {
75*33621d24SKeerthy 		debug("%s: %s reg subnode not found!", __func__, dev->name);
76*33621d24SKeerthy 		return -ENXIO;
77*33621d24SKeerthy 	}
78*33621d24SKeerthy 
79*33621d24SKeerthy 	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
80*33621d24SKeerthy 	if (!children)
81*33621d24SKeerthy 		debug("%s: %s - no child found\n", __func__, dev->name);
82*33621d24SKeerthy 
83*33621d24SKeerthy 	/* Always return success for this device */
84*33621d24SKeerthy 	return 0;
85*33621d24SKeerthy }
86*33621d24SKeerthy 
87*33621d24SKeerthy static struct dm_pmic_ops palmas_ops = {
88*33621d24SKeerthy 	.read = palmas_read,
89*33621d24SKeerthy 	.write = palmas_write,
90*33621d24SKeerthy };
91*33621d24SKeerthy 
92*33621d24SKeerthy static const struct udevice_id palmas_ids[] = {
93*33621d24SKeerthy 	{ .compatible = "ti,tps659038", .data = TPS659038 },
94*33621d24SKeerthy 	{ .compatible = "ti,tps65917" , .data = TPS65917 },
95*33621d24SKeerthy 	{ }
96*33621d24SKeerthy };
97*33621d24SKeerthy 
98*33621d24SKeerthy U_BOOT_DRIVER(pmic_palmas) = {
99*33621d24SKeerthy 	.name = "palmas_pmic",
100*33621d24SKeerthy 	.id = UCLASS_PMIC,
101*33621d24SKeerthy 	.of_match = palmas_ids,
102*33621d24SKeerthy 	.bind = palmas_bind,
103*33621d24SKeerthy 	.ops = &palmas_ops,
104*33621d24SKeerthy };
105