xref: /openbmc/u-boot/drivers/power/pmic/rk8xx.c (revision 172e3c11901229f0fb88317ac73a47d944a74f46)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2453c5a92SJacob Chen /*
3453c5a92SJacob Chen  * Copyright (C) 2015 Google, Inc
4453c5a92SJacob Chen  * Written by Simon Glass <sjg@chromium.org>
5453c5a92SJacob Chen  */
6453c5a92SJacob Chen 
7453c5a92SJacob Chen #include <common.h>
8453c5a92SJacob Chen #include <dm.h>
9453c5a92SJacob Chen #include <errno.h>
10453c5a92SJacob Chen #include <power/rk8xx_pmic.h>
11453c5a92SJacob Chen #include <power/pmic.h>
12453c5a92SJacob Chen 
13453c5a92SJacob Chen static const struct pmic_child_info pmic_children_info[] = {
14453c5a92SJacob Chen 	{ .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
15453c5a92SJacob Chen 	{ .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
16453c5a92SJacob Chen 	{ .prefix = "SWITCH_REG", .driver = "rk8xx_switch"},
17453c5a92SJacob Chen 	{ },
18453c5a92SJacob Chen };
19453c5a92SJacob Chen 
rk8xx_reg_count(struct udevice * dev)20453c5a92SJacob Chen static int rk8xx_reg_count(struct udevice *dev)
21453c5a92SJacob Chen {
22453c5a92SJacob Chen 	return RK808_NUM_OF_REGS;
23453c5a92SJacob Chen }
24453c5a92SJacob Chen 
rk8xx_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)25453c5a92SJacob Chen static int rk8xx_write(struct udevice *dev, uint reg, const uint8_t *buff,
26453c5a92SJacob Chen 			  int len)
27453c5a92SJacob Chen {
28453c5a92SJacob Chen 	int ret;
29453c5a92SJacob Chen 
30453c5a92SJacob Chen 	ret = dm_i2c_write(dev, reg, buff, len);
31453c5a92SJacob Chen 	if (ret) {
32*c83c436dSSimon Glass 		debug("write error to device: %p register: %#x!\n", dev, reg);
33453c5a92SJacob Chen 		return ret;
34453c5a92SJacob Chen 	}
35453c5a92SJacob Chen 
36453c5a92SJacob Chen 	return 0;
37453c5a92SJacob Chen }
38453c5a92SJacob Chen 
rk8xx_read(struct udevice * dev,uint reg,uint8_t * buff,int len)39453c5a92SJacob Chen static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
40453c5a92SJacob Chen {
41453c5a92SJacob Chen 	int ret;
42453c5a92SJacob Chen 
43453c5a92SJacob Chen 	ret = dm_i2c_read(dev, reg, buff, len);
44453c5a92SJacob Chen 	if (ret) {
45*c83c436dSSimon Glass 		debug("read error from device: %p register: %#x!\n", dev, reg);
46453c5a92SJacob Chen 		return ret;
47453c5a92SJacob Chen 	}
48453c5a92SJacob Chen 
49453c5a92SJacob Chen 	return 0;
50453c5a92SJacob Chen }
51453c5a92SJacob Chen 
52453c5a92SJacob Chen #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
rk8xx_bind(struct udevice * dev)53453c5a92SJacob Chen static int rk8xx_bind(struct udevice *dev)
54453c5a92SJacob Chen {
557a869e6cSSimon Glass 	ofnode regulators_node;
56453c5a92SJacob Chen 	int children;
57453c5a92SJacob Chen 
587a869e6cSSimon Glass 	regulators_node = dev_read_subnode(dev, "regulators");
597a869e6cSSimon Glass 	if (!ofnode_valid(regulators_node)) {
60*c83c436dSSimon Glass 		debug("%s: %s regulators subnode not found!\n", __func__,
61453c5a92SJacob Chen 		      dev->name);
62453c5a92SJacob Chen 		return -ENXIO;
63453c5a92SJacob Chen 	}
64453c5a92SJacob Chen 
65453c5a92SJacob Chen 	debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
66453c5a92SJacob Chen 
67453c5a92SJacob Chen 	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
68453c5a92SJacob Chen 	if (!children)
69453c5a92SJacob Chen 		debug("%s: %s - no child found\n", __func__, dev->name);
70453c5a92SJacob Chen 
71453c5a92SJacob Chen 	/* Always return success for this device */
72453c5a92SJacob Chen 	return 0;
73453c5a92SJacob Chen }
74453c5a92SJacob Chen #endif
75453c5a92SJacob Chen 
rk8xx_probe(struct udevice * dev)76453c5a92SJacob Chen static int rk8xx_probe(struct udevice *dev)
77453c5a92SJacob Chen {
78453c5a92SJacob Chen 	struct rk8xx_priv *priv = dev_get_priv(dev);
79453c5a92SJacob Chen 	uint8_t msb, lsb;
80453c5a92SJacob Chen 
81453c5a92SJacob Chen 	/* read Chip variant */
82453c5a92SJacob Chen 	rk8xx_read(dev, ID_MSB, &msb, 1);
83453c5a92SJacob Chen 	rk8xx_read(dev, ID_LSB, &lsb, 1);
84453c5a92SJacob Chen 
85453c5a92SJacob Chen 	priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
86453c5a92SJacob Chen 
87453c5a92SJacob Chen 	return 0;
88453c5a92SJacob Chen }
89453c5a92SJacob Chen 
90453c5a92SJacob Chen static struct dm_pmic_ops rk8xx_ops = {
91453c5a92SJacob Chen 	.reg_count = rk8xx_reg_count,
92453c5a92SJacob Chen 	.read = rk8xx_read,
93453c5a92SJacob Chen 	.write = rk8xx_write,
94453c5a92SJacob Chen };
95453c5a92SJacob Chen 
96453c5a92SJacob Chen static const struct udevice_id rk8xx_ids[] = {
97453c5a92SJacob Chen 	{ .compatible = "rockchip,rk808" },
98453c5a92SJacob Chen 	{ .compatible = "rockchip,rk818" },
99453c5a92SJacob Chen 	{ }
100453c5a92SJacob Chen };
101453c5a92SJacob Chen 
102453c5a92SJacob Chen U_BOOT_DRIVER(pmic_rk8xx) = {
103453c5a92SJacob Chen 	.name = "rk8xx pmic",
104453c5a92SJacob Chen 	.id = UCLASS_PMIC,
105453c5a92SJacob Chen 	.of_match = rk8xx_ids,
106453c5a92SJacob Chen #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
107453c5a92SJacob Chen 	.bind = rk8xx_bind,
108453c5a92SJacob Chen #endif
1097c1fb0a7SKever Yang 	.priv_auto_alloc_size   = sizeof(struct rk8xx_priv),
110453c5a92SJacob Chen 	.probe = rk8xx_probe,
111453c5a92SJacob Chen 	.ops = &rk8xx_ops,
112453c5a92SJacob Chen };
113