blob: bd44e0d9ae05150d1123998d3c9be43d47db8af1 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Greg Guyotteea6f27c2013-08-30 16:28:42 -04002/*
3 * (C) Copyright 2011-2013
4 * Texas Instruments, <www.ti.com>
Greg Guyotteea6f27c2013-08-30 16:28:42 -04005 */
6
Greg Guyotteea6f27c2013-08-30 16:28:42 -04007#include <i2c.h>
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +01008#include <dm.h>
9#include <errno.h>
10#include <fdtdec.h>
11#include <power/pmic.h>
Greg Guyotteea6f27c2013-08-30 16:28:42 -040012#include <power/tps65217.h>
13
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +010014#if !CONFIG_IS_ENABLED(DM_PMIC)
Marek BehĂșn4bebdd32021-05-20 13:23:52 +020015struct udevice *tps65217_dev __section(".data") = NULL;
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010016
Greg Guyotteea6f27c2013-08-30 16:28:42 -040017/**
18 * tps65217_reg_read() - Generic function that can read a TPS65217 register
19 * @src_reg: Source register address
20 * @src_val: Address of destination variable
21 * @return: 0 for success, not 0 on failure.
22 */
23int tps65217_reg_read(uchar src_reg, uchar *src_val)
24{
Igor Opaniukf7c91762021-02-09 13:52:45 +020025#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040026 return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010027#else
28 return dm_i2c_read(tps65217_dev, src_reg, src_val, 1);
29#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040030}
31
32/**
33 * tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
34 * register or bit field regardless of protection
35 * level.
36 *
37 * @prot_level: Register password protection. Use
38 * TPS65217_PROT_LEVEL_NONE,
39 * TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
40 * @dest_reg: Register address to write.
41 * @dest_val: Value to write.
42 * @mask: Bit mask (8 bits) to be applied. Function will only
43 * change bits that are set in the bit mask.
44 *
45 * @return: 0 for success, not 0 on failure, as per the i2c API
46 */
47int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
48 uchar mask)
49{
50 uchar read_val;
51 uchar xor_reg;
52 int ret;
53
54 /*
55 * If we are affecting only a bit field, read dest_reg and apply the
56 * mask
57 */
58 if (mask != TPS65217_MASK_ALL_BITS) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020059#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040060 ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010061#else
62 ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
63#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040064 if (ret)
65 return ret;
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010066
Greg Guyotteea6f27c2013-08-30 16:28:42 -040067 read_val &= (~mask);
68 read_val |= (dest_val & mask);
69 dest_val = read_val;
70 }
71
72 if (prot_level > 0) {
73 xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
Igor Opaniukf7c91762021-02-09 13:52:45 +020074#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040075 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
76 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010077#else
78 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
79 &xor_reg, 1);
80#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040081 if (ret)
82 return ret;
83 }
Igor Opaniukf7c91762021-02-09 13:52:45 +020084#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040085 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010086#else
87 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
88#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040089 if (ret)
90 return ret;
91
92 if (prot_level == TPS65217_PROT_LEVEL_2) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020093#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040094 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
95 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010096#else
97 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
98 &xor_reg, 1);
99#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400100 if (ret)
101 return ret;
102
Igor Opaniukf7c91762021-02-09 13:52:45 +0200103#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400104 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100105#else
106 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
107#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400108 if (ret)
109 return ret;
110 }
111
112 return 0;
113}
114
115/**
116 * tps65217_voltage_update() - Function to change a voltage level, as this
117 * is a multi-step process.
118 * @dc_cntrl_reg: DC voltage control register to change.
119 * @volt_sel: New value for the voltage register
120 * @return: 0 for success, not 0 on failure.
121 */
122int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
123{
124 if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
125 (dc_cntrl_reg != TPS65217_DEFDCDC2) &&
126 (dc_cntrl_reg != TPS65217_DEFDCDC3))
127 return 1;
128
129 /* set voltage level */
130 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
131 TPS65217_MASK_ALL_BITS))
132 return 1;
133
134 /* set GO bit to initiate voltage transition */
135 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
136 TPS65217_DCDC_GO, TPS65217_DCDC_GO))
137 return 1;
138
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100139 return 0;
140}
141
142int power_tps65217_init(unsigned char bus)
143{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200144#if CONFIG_IS_ENABLED(DM_I2C)
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100145 struct udevice *dev = NULL;
146 int rc;
147
148 rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
149 if (rc)
150 return rc;
151 tps65217_dev = dev;
152#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400153 return 0;
154}
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +0100155#else /* CONFIG_IS_ENABLED(DM_PMIC) */
156static const struct pmic_child_info pmic_children_info[] = {
157 { .prefix = "ldo", .driver = "tps65217_ldo" },
158 { },
159};
160
161static int tps65217_reg_count(struct udevice *dev)
162{
163 return TPS65217_PMIC_NUM_OF_REGS;
164}
165
166static int tps65217_write(struct udevice *dev, uint reg, const uint8_t *buff,
167 int len)
168{
169 if (dm_i2c_write(dev, reg, buff, len)) {
170 pr_err("write error to device: %p register: %#x!\n", dev, reg);
171 return -EIO;
172 }
173
174 return 0;
175}
176
177static int tps65217_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
178{
179 int ret;
180
181 ret = dm_i2c_read(dev, reg, buff, len);
182 if (ret) {
183 pr_err("read error %d from device: %p register: %#x!\n", ret,
184 dev, reg);
185 return -EIO;
186 }
187
188 return 0;
189}
190
191static int tps65217_bind(struct udevice *dev)
192{
193 ofnode regulators_node;
194 int children;
195
196 regulators_node = dev_read_subnode(dev, "regulators");
197 if (!ofnode_valid(regulators_node)) {
198 debug("%s: %s regulators subnode not found!\n", __func__,
199 dev->name);
200 return -ENXIO;
201 }
202
203 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
204
205 children = pmic_bind_children(dev, regulators_node, pmic_children_info);
206 if (!children)
207 debug("%s: %s - no child found\n", __func__, dev->name);
208
209 /* Always return success for this device */
210 return 0;
211}
212
213static struct dm_pmic_ops tps65217_ops = {
214 .reg_count = tps65217_reg_count,
215 .read = tps65217_read,
216 .write = tps65217_write,
217};
218
219static const struct udevice_id tps65217_ids[] = {
220 { .compatible = "ti,tps65217" },
221 { }
222};
223
224U_BOOT_DRIVER(pmic_tps65217) = {
225 .name = "tps65217 pmic",
226 .id = UCLASS_PMIC,
227 .of_match = tps65217_ids,
228 .bind = tps65217_bind,
229 .ops = &tps65217_ops,
230};
231#endif