blob: ccbf2235933da9862f96f7e8d4d192743dd42533 [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
7#include <common.h>
8#include <i2c.h>
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +01009#include <dm.h>
10#include <errno.h>
11#include <fdtdec.h>
12#include <power/pmic.h>
Greg Guyotteea6f27c2013-08-30 16:28:42 -040013#include <power/tps65217.h>
14
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +010015#if !CONFIG_IS_ENABLED(DM_PMIC)
Marek BehĂșn4bebdd32021-05-20 13:23:52 +020016struct udevice *tps65217_dev __section(".data") = NULL;
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010017
Greg Guyotteea6f27c2013-08-30 16:28:42 -040018/**
19 * tps65217_reg_read() - Generic function that can read a TPS65217 register
20 * @src_reg: Source register address
21 * @src_val: Address of destination variable
22 * @return: 0 for success, not 0 on failure.
23 */
24int tps65217_reg_read(uchar src_reg, uchar *src_val)
25{
Igor Opaniukf7c91762021-02-09 13:52:45 +020026#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040027 return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010028#else
29 return dm_i2c_read(tps65217_dev, src_reg, src_val, 1);
30#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040031}
32
33/**
34 * tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
35 * register or bit field regardless of protection
36 * level.
37 *
38 * @prot_level: Register password protection. Use
39 * TPS65217_PROT_LEVEL_NONE,
40 * TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
41 * @dest_reg: Register address to write.
42 * @dest_val: Value to write.
43 * @mask: Bit mask (8 bits) to be applied. Function will only
44 * change bits that are set in the bit mask.
45 *
46 * @return: 0 for success, not 0 on failure, as per the i2c API
47 */
48int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
49 uchar mask)
50{
51 uchar read_val;
52 uchar xor_reg;
53 int ret;
54
55 /*
56 * If we are affecting only a bit field, read dest_reg and apply the
57 * mask
58 */
59 if (mask != TPS65217_MASK_ALL_BITS) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020060#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040061 ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010062#else
63 ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
64#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040065 if (ret)
66 return ret;
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010067
Greg Guyotteea6f27c2013-08-30 16:28:42 -040068 read_val &= (~mask);
69 read_val |= (dest_val & mask);
70 dest_val = read_val;
71 }
72
73 if (prot_level > 0) {
74 xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
Igor Opaniukf7c91762021-02-09 13:52:45 +020075#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040076 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
77 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010078#else
79 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
80 &xor_reg, 1);
81#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040082 if (ret)
83 return ret;
84 }
Igor Opaniukf7c91762021-02-09 13:52:45 +020085#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040086 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010087#else
88 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
89#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -040090 if (ret)
91 return ret;
92
93 if (prot_level == TPS65217_PROT_LEVEL_2) {
Igor Opaniukf7c91762021-02-09 13:52:45 +020094#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -040095 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
96 &xor_reg, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +010097#else
98 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
99 &xor_reg, 1);
100#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400101 if (ret)
102 return ret;
103
Igor Opaniukf7c91762021-02-09 13:52:45 +0200104#if !CONFIG_IS_ENABLED(DM_I2C)
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400105 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100106#else
107 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
108#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400109 if (ret)
110 return ret;
111 }
112
113 return 0;
114}
115
116/**
117 * tps65217_voltage_update() - Function to change a voltage level, as this
118 * is a multi-step process.
119 * @dc_cntrl_reg: DC voltage control register to change.
120 * @volt_sel: New value for the voltage register
121 * @return: 0 for success, not 0 on failure.
122 */
123int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
124{
125 if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
126 (dc_cntrl_reg != TPS65217_DEFDCDC2) &&
127 (dc_cntrl_reg != TPS65217_DEFDCDC3))
128 return 1;
129
130 /* set voltage level */
131 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
132 TPS65217_MASK_ALL_BITS))
133 return 1;
134
135 /* set GO bit to initiate voltage transition */
136 if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
137 TPS65217_DCDC_GO, TPS65217_DCDC_GO))
138 return 1;
139
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100140 return 0;
141}
142
143int power_tps65217_init(unsigned char bus)
144{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200145#if CONFIG_IS_ENABLED(DM_I2C)
Jean-Jacques Hiblot77a13972018-12-07 14:50:46 +0100146 struct udevice *dev = NULL;
147 int rc;
148
149 rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
150 if (rc)
151 return rc;
152 tps65217_dev = dev;
153#endif
Greg Guyotteea6f27c2013-08-30 16:28:42 -0400154 return 0;
155}
Lukasz Majewski8ec22ba2022-03-12 08:11:11 +0100156#else /* CONFIG_IS_ENABLED(DM_PMIC) */
157static const struct pmic_child_info pmic_children_info[] = {
158 { .prefix = "ldo", .driver = "tps65217_ldo" },
159 { },
160};
161
162static int tps65217_reg_count(struct udevice *dev)
163{
164 return TPS65217_PMIC_NUM_OF_REGS;
165}
166
167static int tps65217_write(struct udevice *dev, uint reg, const uint8_t *buff,
168 int len)
169{
170 if (dm_i2c_write(dev, reg, buff, len)) {
171 pr_err("write error to device: %p register: %#x!\n", dev, reg);
172 return -EIO;
173 }
174
175 return 0;
176}
177
178static int tps65217_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
179{
180 int ret;
181
182 ret = dm_i2c_read(dev, reg, buff, len);
183 if (ret) {
184 pr_err("read error %d from device: %p register: %#x!\n", ret,
185 dev, reg);
186 return -EIO;
187 }
188
189 return 0;
190}
191
192static int tps65217_bind(struct udevice *dev)
193{
194 ofnode regulators_node;
195 int children;
196
197 regulators_node = dev_read_subnode(dev, "regulators");
198 if (!ofnode_valid(regulators_node)) {
199 debug("%s: %s regulators subnode not found!\n", __func__,
200 dev->name);
201 return -ENXIO;
202 }
203
204 debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
205
206 children = pmic_bind_children(dev, regulators_node, pmic_children_info);
207 if (!children)
208 debug("%s: %s - no child found\n", __func__, dev->name);
209
210 /* Always return success for this device */
211 return 0;
212}
213
214static struct dm_pmic_ops tps65217_ops = {
215 .reg_count = tps65217_reg_count,
216 .read = tps65217_read,
217 .write = tps65217_write,
218};
219
220static const struct udevice_id tps65217_ids[] = {
221 { .compatible = "ti,tps65217" },
222 { }
223};
224
225U_BOOT_DRIVER(pmic_tps65217) = {
226 .name = "tps65217 pmic",
227 .id = UCLASS_PMIC,
228 .of_match = tps65217_ids,
229 .bind = tps65217_bind,
230 .ops = &tps65217_ops,
231};
232#endif