1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2011-2013
4 * Texas Instruments, <www.ti.com>
5 */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <linux/errno.h>
10 #include <power/pmic.h>
11 #include <power/tps65218.h>
12
13 #ifndef CONFIG_DM_I2C
tps65218_reg_read(uchar dest_reg,uchar * dest_val)14 int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
15 {
16 uchar read_val;
17 int ret;
18
19 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
20 if (ret)
21 return ret;
22
23 *dest_val = read_val;
24
25 return 0;
26 }
27
28 /**
29 * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC
30 * register or bit field regardless of protection
31 * level.
32 *
33 * @prot_level: Register password protection. Use
34 * TPS65218_PROT_LEVEL_NONE,
35 * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2
36 * @dest_reg: Register address to write.
37 * @dest_val: Value to write.
38 * @mask: Bit mask (8 bits) to be applied. Function will only
39 * change bits that are set in the bit mask.
40 *
41 * @return: 0 for success, not 0 on failure, as per the i2c API
42 */
tps65218_reg_write(uchar prot_level,uchar dest_reg,uchar dest_val,uchar mask)43 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
44 uchar mask)
45 {
46 uchar read_val;
47 uchar xor_reg;
48 int ret;
49
50 /*
51 * If we are affecting only a bit field, read dest_reg and apply the
52 * mask
53 */
54 if (mask != TPS65218_MASK_ALL_BITS) {
55 ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
56 if (ret)
57 return ret;
58 read_val &= (~mask);
59 read_val |= (dest_val & mask);
60 dest_val = read_val;
61 }
62
63 if (prot_level > 0) {
64 xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
65 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
66 &xor_reg, 1);
67 if (ret)
68 return ret;
69 }
70
71 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
72 if (ret)
73 return ret;
74
75 if (prot_level == TPS65218_PROT_LEVEL_2) {
76 ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
77 &xor_reg, 1);
78 if (ret)
79 return ret;
80
81 ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
82 if (ret)
83 return ret;
84 }
85
86 return 0;
87 }
88 #else
89 struct udevice *tps65218_dev __attribute__((section(".data"))) = NULL;
90
tps65218_reg_read(uchar dest_reg,uchar * dest_val)91 int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
92 {
93 uchar read_val;
94 int ret;
95
96 if (!tps65218_dev)
97 return -ENODEV;
98
99 ret = dm_i2c_read(tps65218_dev, dest_reg, &read_val, 1);
100 if (ret)
101 return ret;
102
103 *dest_val = read_val;
104
105 return 0;
106 }
107
tps65218_reg_write(uchar prot_level,uchar dest_reg,uchar dest_val,uchar mask)108 int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
109 uchar mask)
110 {
111 uchar read_val;
112 uchar xor_reg;
113 int ret;
114
115 if (!tps65218_dev)
116 return -ENODEV;
117
118 /*
119 * If we are affecting only a bit field, read dest_reg and apply the
120 * mask
121 */
122 if (mask != TPS65218_MASK_ALL_BITS) {
123 ret = dm_i2c_read(tps65218_dev, dest_reg, &read_val, 1);
124 if (ret)
125 return ret;
126
127 read_val &= (~mask);
128 read_val |= (dest_val & mask);
129 dest_val = read_val;
130 }
131
132 if (prot_level > 0) {
133 xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
134 ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
135 1);
136 if (ret)
137 return ret;
138 }
139
140 ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
141 if (ret)
142 return ret;
143
144 if (prot_level == TPS65218_PROT_LEVEL_2) {
145 ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
146 1);
147 if (ret)
148 return ret;
149
150 ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
151 if (ret)
152 return ret;
153 }
154
155 return 0;
156 }
157 #endif
158
159 /**
160 * tps65218_voltage_update() - Function to change a voltage level, as this
161 * is a multi-step process.
162 * @dc_cntrl_reg: DC voltage control register to change.
163 * @volt_sel: New value for the voltage register
164 * @return: 0 for success, not 0 on failure.
165 */
tps65218_voltage_update(uchar dc_cntrl_reg,uchar volt_sel)166 int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
167 {
168 if ((dc_cntrl_reg != TPS65218_DCDC1) &&
169 (dc_cntrl_reg != TPS65218_DCDC2) &&
170 (dc_cntrl_reg != TPS65218_DCDC3))
171 return 1;
172
173 /* set voltage level */
174 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
175 TPS65218_DCDC_VSEL_MASK))
176 return 1;
177
178 /* set GO bit to initiate voltage transition */
179 if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW,
180 TPS65218_DCDC_GO, TPS65218_DCDC_GO))
181 return 1;
182
183 return 0;
184 }
185
186 /**
187 * tps65218_toggle_fseal() - Perform the sequence that toggles the FSEAL bit.
188 *
189 * @return: 0 on success, -EBADE if the sequence was broken
190 */
tps65218_toggle_fseal(void)191 int tps65218_toggle_fseal(void)
192 {
193 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
194 0xb1, TPS65218_MASK_ALL_BITS))
195 return -EBADE;
196
197 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
198 0xfe, TPS65218_MASK_ALL_BITS))
199 return -EBADE;
200
201 if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
202 0xa3, TPS65218_MASK_ALL_BITS))
203 return -EBADE;
204
205 return 0;
206 }
207
208 /**
209 * tps65218_lock_fseal() - Perform the sequence that locks the FSEAL bit to 1.
210 *
211 * The FSEAL bit prevents the PMIC from turning off DCDC5 and DCDC6. It can be
212 * toggled at most 3 times: 0->1, 1->0, and finally 0->1. After the third switch
213 * its value is locked and can only be reset by powering off the PMIC entirely.
214 *
215 * @return: 0 on success, -EBADE if the sequence was broken
216 */
tps65218_lock_fseal(void)217 int tps65218_lock_fseal(void)
218 {
219 int i;
220
221 for (i = 0; i < 3; i++)
222 if (tps65218_toggle_fseal())
223 return -EBADE;
224
225 return 0;
226 }
227
228 #ifndef CONFIG_DM_I2C
power_tps65218_init(unsigned char bus)229 int power_tps65218_init(unsigned char bus)
230 {
231 static const char name[] = "TPS65218_PMIC";
232 struct pmic *p = pmic_alloc();
233
234 if (!p) {
235 printf("%s: POWER allocation error!\n", __func__);
236 return -ENOMEM;
237 }
238
239 p->name = name;
240 p->interface = PMIC_I2C;
241 p->number_of_regs = TPS65218_PMIC_NUM_OF_REGS;
242 p->hw.i2c.addr = TPS65218_CHIP_PM;
243 p->hw.i2c.tx_num = 1;
244 p->bus = bus;
245
246 return 0;
247 }
248 #else
power_tps65218_init(unsigned char bus)249 int power_tps65218_init(unsigned char bus)
250 {
251 struct udevice *dev = NULL;
252 int rc;
253
254 rc = i2c_get_chip_for_busnum(bus, TPS65218_CHIP_PM, 1, &dev);
255 if (rc)
256 return rc;
257 tps65218_dev = dev;
258 return 0;
259 }
260 #endif
261