xref: /rk3399_rockchip-uboot/drivers/power/pmic/as3722.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
12838c07fSSimon Glass /*
22838c07fSSimon Glass  * Copyright (C) 2014 NVIDIA Corporation
32838c07fSSimon Glass  *
42838c07fSSimon Glass  * SPDX-License-Identifier: GPL-2.0+
52838c07fSSimon Glass  */
62838c07fSSimon Glass 
72838c07fSSimon Glass #define pr_fmt(fmt) "as3722: " fmt
82838c07fSSimon Glass 
92838c07fSSimon Glass #include <common.h>
102838c07fSSimon Glass #include <dm.h>
112838c07fSSimon Glass #include <errno.h>
122838c07fSSimon Glass #include <fdtdec.h>
132838c07fSSimon Glass #include <i2c.h>
14e3f44f5cSSimon Glass #include <dm/lists.h>
152838c07fSSimon Glass #include <power/as3722.h>
16e3f44f5cSSimon Glass #include <power/pmic.h>
172838c07fSSimon Glass 
18e3f44f5cSSimon Glass #define AS3722_NUM_OF_REGS	0x92
192838c07fSSimon Glass 
as3722_read(struct udevice * dev,uint reg,uint8_t * buff,int len)20e3f44f5cSSimon Glass static int as3722_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
212838c07fSSimon Glass {
22e3f44f5cSSimon Glass 	int ret;
232838c07fSSimon Glass 
24e3f44f5cSSimon Glass 	ret = dm_i2c_read(dev, reg, buff, len);
25e3f44f5cSSimon Glass 	if (ret < 0)
26e3f44f5cSSimon Glass 		return ret;
272838c07fSSimon Glass 
282838c07fSSimon Glass 	return 0;
292838c07fSSimon Glass }
302838c07fSSimon Glass 
as3722_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)31e3f44f5cSSimon Glass static int as3722_write(struct udevice *dev, uint reg, const uint8_t *buff,
32e3f44f5cSSimon Glass 			int len)
332838c07fSSimon Glass {
34e3f44f5cSSimon Glass 	int ret;
352838c07fSSimon Glass 
36e3f44f5cSSimon Glass 	ret = dm_i2c_write(dev, reg, buff, len);
37e3f44f5cSSimon Glass 	if (ret < 0)
38e3f44f5cSSimon Glass 		return ret;
392838c07fSSimon Glass 
402838c07fSSimon Glass 	return 0;
412838c07fSSimon Glass }
422838c07fSSimon Glass 
as3722_read_id(struct udevice * dev,uint * idp,uint * revisionp)43e3f44f5cSSimon Glass static int as3722_read_id(struct udevice *dev, uint *idp, uint *revisionp)
442838c07fSSimon Glass {
45e3f44f5cSSimon Glass 	int ret;
462838c07fSSimon Glass 
47e3f44f5cSSimon Glass 	ret = pmic_reg_read(dev, AS3722_ASIC_ID1);
48e3f44f5cSSimon Glass 	if (ret < 0) {
49*90aa625cSMasahiro Yamada 		pr_err("failed to read ID1 register: %d", ret);
50e3f44f5cSSimon Glass 		return ret;
512838c07fSSimon Glass 	}
52e3f44f5cSSimon Glass 	*idp = ret;
532838c07fSSimon Glass 
54e3f44f5cSSimon Glass 	ret = pmic_reg_read(dev, AS3722_ASIC_ID2);
55e3f44f5cSSimon Glass 	if (ret < 0) {
56*90aa625cSMasahiro Yamada 		pr_err("failed to read ID2 register: %d", ret);
57e3f44f5cSSimon Glass 		return ret;
582838c07fSSimon Glass 	}
59e3f44f5cSSimon Glass 	*revisionp = ret;
602838c07fSSimon Glass 
612838c07fSSimon Glass 	return 0;
622838c07fSSimon Glass }
632838c07fSSimon Glass 
64e3f44f5cSSimon Glass /* TODO(treding@nvidia.com): Add proper regulator support to avoid this */
as3722_sd_set_voltage(struct udevice * dev,unsigned int sd,u8 value)65e3f44f5cSSimon Glass int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value)
662838c07fSSimon Glass {
67e3f44f5cSSimon Glass 	int ret;
682838c07fSSimon Glass 
692838c07fSSimon Glass 	if (sd > 6)
702838c07fSSimon Glass 		return -EINVAL;
712838c07fSSimon Glass 
72e3f44f5cSSimon Glass 	ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value);
73e3f44f5cSSimon Glass 	if (ret < 0) {
74*90aa625cSMasahiro Yamada 		pr_err("failed to write SD%u voltage register: %d", sd, ret);
75e3f44f5cSSimon Glass 		return ret;
762838c07fSSimon Glass 	}
772838c07fSSimon Glass 
782838c07fSSimon Glass 	return 0;
792838c07fSSimon Glass }
802838c07fSSimon Glass 
as3722_ldo_set_voltage(struct udevice * dev,unsigned int ldo,u8 value)81e3f44f5cSSimon Glass int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 value)
822838c07fSSimon Glass {
83e3f44f5cSSimon Glass 	int ret;
842838c07fSSimon Glass 
852838c07fSSimon Glass 	if (ldo > 11)
862838c07fSSimon Glass 		return -EINVAL;
872838c07fSSimon Glass 
88e3f44f5cSSimon Glass 	ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value);
89e3f44f5cSSimon Glass 	if (ret < 0) {
90*90aa625cSMasahiro Yamada 		pr_err("failed to write LDO%u voltage register: %d", ldo,
91e3f44f5cSSimon Glass 		      ret);
92e3f44f5cSSimon Glass 		return ret;
932838c07fSSimon Glass 	}
942838c07fSSimon Glass 
952838c07fSSimon Glass 	return 0;
962838c07fSSimon Glass }
972838c07fSSimon Glass 
as3722_probe(struct udevice * dev)98e3f44f5cSSimon Glass static int as3722_probe(struct udevice *dev)
992838c07fSSimon Glass {
100e3f44f5cSSimon Glass 	uint id, revision;
101e3f44f5cSSimon Glass 	int ret;
1022838c07fSSimon Glass 
103e3f44f5cSSimon Glass 	ret = as3722_read_id(dev, &id, &revision);
104e3f44f5cSSimon Glass 	if (ret < 0) {
105*90aa625cSMasahiro Yamada 		pr_err("failed to read ID: %d", ret);
106e3f44f5cSSimon Glass 		return ret;
1072838c07fSSimon Glass 	}
1082838c07fSSimon Glass 
1092838c07fSSimon Glass 	if (id != AS3722_DEVICE_ID) {
110*90aa625cSMasahiro Yamada 		pr_err("unknown device");
1112838c07fSSimon Glass 		return -ENOENT;
1122838c07fSSimon Glass 	}
1132838c07fSSimon Glass 
114e3f44f5cSSimon Glass 	debug("AS3722 revision %#x found on I2C bus %s\n", revision, dev->name);
1152838c07fSSimon Glass 
1162838c07fSSimon Glass 	return 0;
1172838c07fSSimon Glass }
118e3f44f5cSSimon Glass 
119e3f44f5cSSimon Glass #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
120e3f44f5cSSimon Glass static const struct pmic_child_info pmic_children_info[] = {
121e3f44f5cSSimon Glass 	{ .prefix = "sd", .driver = "as3722_stepdown"},
122e3f44f5cSSimon Glass 	{ .prefix = "ldo", .driver = "as3722_ldo"},
123e3f44f5cSSimon Glass 	{ },
124e3f44f5cSSimon Glass };
125e3f44f5cSSimon Glass 
as3722_bind(struct udevice * dev)126e3f44f5cSSimon Glass static int as3722_bind(struct udevice *dev)
127e3f44f5cSSimon Glass {
128e3f44f5cSSimon Glass 	struct udevice *gpio_dev;
129e3f44f5cSSimon Glass 	ofnode regulators_node;
130e3f44f5cSSimon Glass 	int children;
131e3f44f5cSSimon Glass 	int ret;
132e3f44f5cSSimon Glass 
133e3f44f5cSSimon Glass 	regulators_node = dev_read_subnode(dev, "regulators");
134e3f44f5cSSimon Glass 	if (!ofnode_valid(regulators_node)) {
135e3f44f5cSSimon Glass 		debug("%s: %s regulators subnode not found\n", __func__,
136e3f44f5cSSimon Glass 		      dev->name);
137e3f44f5cSSimon Glass 		return -ENXIO;
138e3f44f5cSSimon Glass 	}
139e3f44f5cSSimon Glass 
140e3f44f5cSSimon Glass 	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
141e3f44f5cSSimon Glass 	if (!children)
142e3f44f5cSSimon Glass 		debug("%s: %s - no child found\n", __func__, dev->name);
143e3f44f5cSSimon Glass 	ret = device_bind_driver(dev, "gpio_as3722", "gpio_as3722", &gpio_dev);
144e3f44f5cSSimon Glass 	if (ret) {
145e3f44f5cSSimon Glass 		debug("%s: Cannot bind GPIOs (ret=%d)\n", __func__, ret);
146e3f44f5cSSimon Glass 		return ret;
147e3f44f5cSSimon Glass 	}
148e3f44f5cSSimon Glass 
149e3f44f5cSSimon Glass 	return 0;
150e3f44f5cSSimon Glass }
151e3f44f5cSSimon Glass #endif
152e3f44f5cSSimon Glass 
as3722_reg_count(struct udevice * dev)153e3f44f5cSSimon Glass static int as3722_reg_count(struct udevice *dev)
154e3f44f5cSSimon Glass {
155e3f44f5cSSimon Glass 	return AS3722_NUM_OF_REGS;
156e3f44f5cSSimon Glass }
157e3f44f5cSSimon Glass 
158e3f44f5cSSimon Glass static struct dm_pmic_ops as3722_ops = {
159e3f44f5cSSimon Glass 	.reg_count = as3722_reg_count,
160e3f44f5cSSimon Glass 	.read = as3722_read,
161e3f44f5cSSimon Glass 	.write = as3722_write,
162e3f44f5cSSimon Glass };
163e3f44f5cSSimon Glass 
164e3f44f5cSSimon Glass static const struct udevice_id as3722_ids[] = {
165e3f44f5cSSimon Glass 	{ .compatible = "ams,as3722" },
166e3f44f5cSSimon Glass 	{ }
167e3f44f5cSSimon Glass };
168e3f44f5cSSimon Glass 
169e3f44f5cSSimon Glass U_BOOT_DRIVER(pmic_as3722) = {
170e3f44f5cSSimon Glass 	.name = "as3722_pmic",
171e3f44f5cSSimon Glass 	.id = UCLASS_PMIC,
172e3f44f5cSSimon Glass 	.of_match = as3722_ids,
173e3f44f5cSSimon Glass #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
174e3f44f5cSSimon Glass 	.bind = as3722_bind,
175e3f44f5cSSimon Glass #endif
176e3f44f5cSSimon Glass 	.probe = as3722_probe,
177e3f44f5cSSimon Glass 	.ops = &as3722_ops,
178e3f44f5cSSimon Glass };
179