blob: 023cf211fc4c1300a6d31c348bcc87346810a686 [file] [log] [blame]
Neil Armstrong5fc0a862022-04-27 13:28:10 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2022 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 *
6 */
7
8#include <common.h>
9#include <fdtdec.h>
10#include <errno.h>
11#include <dm.h>
12#include <i2c.h>
13#include <log.h>
14#include <linux/delay.h>
15#include <power/pmic.h>
16#include <power/regulator.h>
17#include <power/tps65219.h>
18
19static const unsigned int tps65219_buck_vout[TPS65219_BUCK_NUM] = {
20 [0] = TPS65219_BUCK1_VOUT_REG,
21 [1] = TPS65219_BUCK2_VOUT_REG,
22 [2] = TPS65219_BUCK3_VOUT_REG
23};
24
25static const unsigned int tps65219_ldo_vout[TPS65219_LDO_NUM] = {
26 [0] = TPS65219_LDO1_VOUT_REG,
27 [1] = TPS65219_LDO2_VOUT_REG,
28 [2] = TPS65219_LDO3_VOUT_REG,
29 [3] = TPS65219_LDO4_VOUT_REG,
30};
31
32static int tps65219_reg_enable(struct udevice *dev, unsigned int adr, int idx,
33 int op, bool *enable)
34{
35 int ret;
36
37 ret = pmic_reg_read(dev->parent, adr);
38 if (ret < 0)
39 return ret;
40
41 if (op == PMIC_OP_GET) {
42 if (ret & BIT(idx))
43 *enable = true;
44 else
45 *enable = false;
46
47 return 0;
48 } else if (op == PMIC_OP_SET) {
49 if (*enable)
50 ret |= BIT(idx);
51 else
52 ret &= ~BIT(idx);
53
54 ret = pmic_reg_write(dev->parent, adr, ret);
55 if (ret)
56 return ret;
57 }
58
59 return 0;
60}
61
62static int tps65219_buck_enable(struct udevice *dev, int op, bool *enable)
63{
64 unsigned int adr;
65 struct dm_regulator_uclass_plat *uc_pdata;
66 int idx;
67
68 idx = dev->driver_data - 1;
69 uc_pdata = dev_get_uclass_plat(dev);
70 adr = uc_pdata->ctrl_reg;
71
72 return tps65219_reg_enable(dev, adr, idx, op, enable);
73}
74
75static int tps65219_buck_volt2val(int uV)
76{
77 if (uV > TPS65219_BUCK_VOLT_MAX)
78 return -EINVAL;
79 else if (uV >= 1400000)
80 return (uV - 1400000) / 100000 + 0x20;
81 else if (uV >= 600000)
82 return (uV - 600000) / 25000 + 0x00;
83 else
84 return -EINVAL;
85}
86
87static int tps65219_buck_val2volt(int val)
88{
89 if (val > TPS65219_VOLT_MASK)
90 return -EINVAL;
91 else if (val > 0x34)
92 return TPS65219_BUCK_VOLT_MAX;
93 else if (val > 0x20)
94 return 1400000 + (val - 0x20) * 100000;
95 else if (val >= 0)
96 return 600000 + val * 25000;
97 else
98 return -EINVAL;
99}
100
101static int tps65219_buck_val(struct udevice *dev, int op, int *uV)
102{
103 unsigned int adr;
104 int ret, val;
105 struct dm_regulator_uclass_plat *uc_pdata;
106
107 uc_pdata = dev_get_uclass_plat(dev);
108 adr = uc_pdata->volt_reg;
109
110 ret = pmic_reg_read(dev->parent, adr);
111 if (ret < 0)
112 return ret;
113
114 if (op == PMIC_OP_GET) {
115 *uV = 0;
116
117 ret &= TPS65219_VOLT_MASK;
118 ret = tps65219_buck_val2volt(ret);
119 if (ret < 0)
120 return ret;
121
122 *uV = ret;
123 return 0;
124 }
125
126 val = tps65219_buck_volt2val(*uV);
127 if (val < 0)
128 return val;
129
130 ret &= ~TPS65219_VOLT_MASK;
131 ret |= val;
132
133 ret = pmic_reg_write(dev->parent, adr, ret);
134
135 udelay(100);
136
137 return ret;
138}
139
140static int tps65219_ldo_enable(struct udevice *dev, int op, bool *enable)
141{
142 unsigned int adr;
143 struct dm_regulator_uclass_plat *uc_pdata;
144 int idx;
145
146 idx = TPS65219_BUCK_NUM + (dev->driver_data - 1);
147 uc_pdata = dev_get_uclass_plat(dev);
148 adr = uc_pdata->ctrl_reg;
149
150 return tps65219_reg_enable(dev, adr, idx, op, enable);
151}
152
153static int tps65219_ldo_volt2val(int idx, int uV)
154{
155 int base = TPS65219_LDO12_VOLT_MIN;
156 int max = TPS65219_LDO12_VOLT_MAX;
157
158 if (idx > 1) {
159 base = TPS65219_LDO34_VOLT_MIN;
160 max = TPS65219_LDO34_VOLT_MAX;
161 }
162
163 if (uV > max)
164 return -EINVAL;
165 else if (uV >= base)
166 return (uV - TPS65219_LDO12_VOLT_MIN) / 50000;
167 else
168 return -EINVAL;
169}
170
171static int tps65219_ldo_val2volt(int idx, int val)
172{
173 int reg_base = TPS65219_LDO12_VOLT_REG_MIN;
174 int reg_max = TPS65219_LDO12_VOLT_REG_MAX;
175 int base = TPS65219_LDO12_VOLT_MIN;
176 int max = TPS65219_LDO12_VOLT_MAX;
177
178 if (idx > 1) {
179 base = TPS65219_LDO34_VOLT_MIN;
180 max = TPS65219_LDO34_VOLT_MAX;
181 reg_base = TPS65219_LDO34_VOLT_REG_MIN;
182 reg_max = TPS65219_LDO34_VOLT_REG_MAX;
183 }
184
185 if (val > TPS65219_VOLT_MASK || val < 0)
186 return -EINVAL;
187 else if (val >= reg_max)
188 return max;
189 else if (val <= reg_base)
190 return base;
191 else if (val >= 0)
192 return TPS65219_LDO12_VOLT_MIN + (50000 * val);
193 else
194 return -EINVAL;
195}
196
197static int tps65219_ldo_val(struct udevice *dev, int op, int *uV)
198{
199 unsigned int adr;
200 int ret, val;
201 struct dm_regulator_uclass_plat *uc_pdata;
202 int idx;
203
204 idx = dev->driver_data - 1;
205 uc_pdata = dev_get_uclass_plat(dev);
206 adr = uc_pdata->volt_reg;
207
208 ret = pmic_reg_read(dev->parent, adr);
209 if (ret < 0)
210 return ret;
211
212 if (op == PMIC_OP_GET) {
213 *uV = 0;
214
215 ret &= TPS65219_VOLT_MASK;
216 ret = tps65219_ldo_val2volt(idx, ret);
217 if (ret < 0)
218 return ret;
219
220 *uV = ret;
221 return 0;
222 }
223
224 /* LDO1 & LDO2 in BYPASS mode only supports 1.5V max */
225 if (idx < 2 &&
226 (ret & BIT(TPS65219_LDO12_BYP_CONFIG)) &&
227 *uV < TPS65219_LDO12_VOLT_BYP_MIN)
228 return -EINVAL;
229
230 val = tps65219_ldo_volt2val(idx, *uV);
231 if (val < 0)
232 return val;
233
234 ret &= ~TPS65219_VOLT_MASK;
235 ret |= val;
236
237 ret = pmic_reg_write(dev->parent, adr, ret);
238
239 udelay(100);
240
241 return ret;
242}
243
244static int tps65219_ldo_probe(struct udevice *dev)
245{
246 struct dm_regulator_uclass_plat *uc_pdata;
247 int idx;
248
249 uc_pdata = dev_get_uclass_plat(dev);
250 uc_pdata->type = REGULATOR_TYPE_LDO;
251
252 /* idx must be in 1..TPS65219_LDO_NUM */
253 idx = dev->driver_data;
254 if (idx < 1 || idx > TPS65219_LDO_NUM) {
255 printf("Wrong ID for regulator\n");
256 return -EINVAL;
257 }
258
259 uc_pdata->ctrl_reg = TPS65219_ENABLE_CTRL_REG;
260 uc_pdata->volt_reg = tps65219_ldo_vout[idx - 1];
261
262 return 0;
263}
264
265static int tps65219_buck_probe(struct udevice *dev)
266{
267 struct dm_regulator_uclass_plat *uc_pdata;
268 int idx;
269
270 uc_pdata = dev_get_uclass_plat(dev);
271 uc_pdata->type = REGULATOR_TYPE_BUCK;
272
273 /* idx must be in 1..TPS65219_BUCK_NUM */
274 idx = dev->driver_data;
275 if (idx < 1 || idx > TPS65219_BUCK_NUM) {
276 printf("Wrong ID for regulator\n");
277 return -EINVAL;
278 }
279
280 uc_pdata->ctrl_reg = TPS65219_ENABLE_CTRL_REG;
281 uc_pdata->volt_reg = tps65219_buck_vout[idx - 1];
282
283 return 0;
284}
285
286static int ldo_get_value(struct udevice *dev)
287{
288 int uV;
289 int ret;
290
291 ret = tps65219_ldo_val(dev, PMIC_OP_GET, &uV);
292 if (ret)
293 return ret;
294
295 return uV;
296}
297
298static int ldo_set_value(struct udevice *dev, int uV)
299{
300 return tps65219_ldo_val(dev, PMIC_OP_SET, &uV);
301}
302
303static int ldo_get_enable(struct udevice *dev)
304{
305 bool enable = false;
306 int ret;
307
308 ret = tps65219_ldo_enable(dev, PMIC_OP_GET, &enable);
309 if (ret)
310 return ret;
311
312 return enable;
313}
314
315static int ldo_set_enable(struct udevice *dev, bool enable)
316{
317 return tps65219_ldo_enable(dev, PMIC_OP_SET, &enable);
318}
319
320static int buck_get_value(struct udevice *dev)
321{
322 int uV;
323 int ret;
324
325 ret = tps65219_buck_val(dev, PMIC_OP_GET, &uV);
326 if (ret)
327 return ret;
328
329 return uV;
330}
331
332static int buck_set_value(struct udevice *dev, int uV)
333{
334 return tps65219_buck_val(dev, PMIC_OP_SET, &uV);
335}
336
337static int buck_get_enable(struct udevice *dev)
338{
339 bool enable = false;
340 int ret;
341
342 ret = tps65219_buck_enable(dev, PMIC_OP_GET, &enable);
343 if (ret)
344 return ret;
345
346 return enable;
347}
348
349static int buck_set_enable(struct udevice *dev, bool enable)
350{
351 return tps65219_buck_enable(dev, PMIC_OP_SET, &enable);
352}
353
354static const struct dm_regulator_ops tps65219_ldo_ops = {
355 .get_value = ldo_get_value,
356 .set_value = ldo_set_value,
357 .get_enable = ldo_get_enable,
358 .set_enable = ldo_set_enable,
359};
360
361U_BOOT_DRIVER(tps65219_ldo) = {
362 .name = TPS65219_LDO_DRIVER,
363 .id = UCLASS_REGULATOR,
364 .ops = &tps65219_ldo_ops,
365 .probe = tps65219_ldo_probe,
366};
367
368static const struct dm_regulator_ops tps65219_buck_ops = {
369 .get_value = buck_get_value,
370 .set_value = buck_set_value,
371 .get_enable = buck_get_enable,
372 .set_enable = buck_set_enable,
373};
374
375U_BOOT_DRIVER(tps65219_buck) = {
376 .name = TPS65219_BUCK_DRIVER,
377 .id = UCLASS_REGULATOR,
378 .ops = &tps65219_buck_ops,
379 .probe = tps65219_buck_probe,
380};