]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/power/regulator/lp873x_regulator.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / power / regulator / lp873x_regulator.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
99785de8
K
2/*
3 * (C) Copyright 2016
4 * Texas Instruments Incorporated, <www.ti.com>
5 *
6 * Keerthy <j-keerthy@ti.com>
99785de8
K
7 */
8
d678a59d 9#include <common.h>
99785de8
K
10#include <fdtdec.h>
11#include <errno.h>
12#include <dm.h>
99785de8
K
13#include <power/pmic.h>
14#include <power/regulator.h>
15#include <power/lp873x.h>
16
99785de8
K
17static const char lp873x_buck_ctrl[LP873X_BUCK_NUM] = {0x2, 0x4};
18static const char lp873x_buck_volt[LP873X_BUCK_NUM] = {0x6, 0x7};
19static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9};
20static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB};
21
22static int lp873x_buck_enable(struct udevice *dev, int op, bool *enable)
23{
24 int ret;
25 unsigned int adr;
caa4daa2 26 struct dm_regulator_uclass_plat *uc_pdata;
99785de8 27
caa4daa2 28 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
29 adr = uc_pdata->ctrl_reg;
30
31 ret = pmic_reg_read(dev->parent, adr);
32 if (ret < 0)
33 return ret;
34
35 if (op == PMIC_OP_GET) {
36 ret &= LP873X_BUCK_MODE_MASK;
37
38 if (ret)
39 *enable = true;
40 else
41 *enable = false;
42
43 return 0;
44 } else if (op == PMIC_OP_SET) {
45 if (*enable)
46 ret |= LP873X_BUCK_MODE_MASK;
47 else
48 ret &= ~(LP873X_BUCK_MODE_MASK);
49 ret = pmic_reg_write(dev->parent, adr, ret);
50 if (ret)
51 return ret;
52 }
53
54 return 0;
55}
56
57static int lp873x_buck_volt2hex(int uV)
58{
59 if (uV > LP873X_BUCK_VOLT_MAX)
60 return -EINVAL;
61 else if (uV > 1400000)
62 return (uV - 1420000) / 20000 + 0x9E;
63 else if (uV > 730000)
64 return (uV - 735000) / 5000 + 0x18;
65 else if (uV >= 700000)
66 return (uV - 700000) / 10000 + 0x1;
67 else
68 return -EINVAL;
69}
70
71static int lp873x_buck_hex2volt(int hex)
72{
73 if (hex > LP873X_BUCK_VOLT_MAX_HEX)
74 return -EINVAL;
75 else if (hex > 0x9D)
76 return 1400000 + (hex - 0x9D) * 20000;
77 else if (hex > 0x17)
78 return 730000 + (hex - 0x17) * 5000;
79 else if (hex >= 0x14)
80 return 700000 + (hex - 0x14) * 10000;
81 else
82 return -EINVAL;
83}
84
85static int lp873x_buck_val(struct udevice *dev, int op, int *uV)
86{
87 unsigned int hex, adr;
88 int ret;
caa4daa2 89 struct dm_regulator_uclass_plat *uc_pdata;
99785de8 90
caa4daa2 91 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
92
93 if (op == PMIC_OP_GET)
94 *uV = 0;
95
96 adr = uc_pdata->volt_reg;
97
98 ret = pmic_reg_read(dev->parent, adr);
99 if (ret < 0)
100 return ret;
101
102 if (op == PMIC_OP_GET) {
103 ret &= LP873X_BUCK_VOLT_MASK;
104 ret = lp873x_buck_hex2volt(ret);
105 if (ret < 0)
106 return ret;
107 *uV = ret;
108
109 return 0;
110 }
111
112 hex = lp873x_buck_volt2hex(*uV);
113 if (hex < 0)
114 return hex;
115
116 ret &= 0x0;
117 ret |= hex;
118
119 ret = pmic_reg_write(dev->parent, adr, ret);
120
121 return ret;
122}
123
124static int lp873x_ldo_enable(struct udevice *dev, int op, bool *enable)
125{
126 int ret;
127 unsigned int adr;
caa4daa2 128 struct dm_regulator_uclass_plat *uc_pdata;
99785de8 129
caa4daa2 130 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
131 adr = uc_pdata->ctrl_reg;
132
133 ret = pmic_reg_read(dev->parent, adr);
134 if (ret < 0)
135 return ret;
136
137 if (op == PMIC_OP_GET) {
138 ret &= LP873X_LDO_MODE_MASK;
139
140 if (ret)
141 *enable = true;
142 else
143 *enable = false;
144
145 return 0;
146 } else if (op == PMIC_OP_SET) {
147 if (*enable)
148 ret |= LP873X_LDO_MODE_MASK;
149 else
150 ret &= ~(LP873X_LDO_MODE_MASK);
151
152 ret = pmic_reg_write(dev->parent, adr, ret);
153 if (ret)
154 return ret;
155 }
156
157 return 0;
158}
159
160static int lp873x_ldo_volt2hex(int uV)
161{
162 if (uV > LP873X_LDO_VOLT_MAX)
163 return -EINVAL;
164
165 return (uV - 800000) / 100000;
166}
167
168static int lp873x_ldo_hex2volt(int hex)
169{
170 if (hex > LP873X_LDO_VOLT_MAX_HEX)
171 return -EINVAL;
172
173 if (!hex)
174 return 0;
175
176 return (hex * 100000) + 800000;
177}
178
179static int lp873x_ldo_val(struct udevice *dev, int op, int *uV)
180{
181 unsigned int hex, adr;
182 int ret;
183
caa4daa2 184 struct dm_regulator_uclass_plat *uc_pdata;
99785de8
K
185
186 if (op == PMIC_OP_GET)
187 *uV = 0;
188
caa4daa2 189 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
190
191 adr = uc_pdata->volt_reg;
192
193 ret = pmic_reg_read(dev->parent, adr);
194 if (ret < 0)
195 return ret;
196
197 if (op == PMIC_OP_GET) {
198 ret &= LP873X_LDO_VOLT_MASK;
199 ret = lp873x_ldo_hex2volt(ret);
200 if (ret < 0)
201 return ret;
202 *uV = ret;
203 return 0;
204 }
205
206 hex = lp873x_ldo_volt2hex(*uV);
207 if (hex < 0)
208 return hex;
209
210 ret &= ~LP873X_LDO_VOLT_MASK;
211 ret |= hex;
212 if (*uV > 1650000)
213 ret |= 0x80;
214 ret = pmic_reg_write(dev->parent, adr, ret);
215
216 return ret;
217}
218
219static int lp873x_ldo_probe(struct udevice *dev)
220{
caa4daa2 221 struct dm_regulator_uclass_plat *uc_pdata;
99785de8 222
caa4daa2 223 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
224 uc_pdata->type = REGULATOR_TYPE_LDO;
225
226 int idx = dev->driver_data;
227 if (idx >= LP873X_LDO_NUM) {
228 printf("Wrong ID for regulator\n");
229 return -1;
230 }
231
232 uc_pdata->ctrl_reg = lp873x_ldo_ctrl[idx];
233 uc_pdata->volt_reg = lp873x_ldo_volt[idx];
234
235 return 0;
236}
237
238static int ldo_get_value(struct udevice *dev)
239{
240 int uV;
241 int ret;
242
243 ret = lp873x_ldo_val(dev, PMIC_OP_GET, &uV);
244 if (ret)
245 return ret;
246
247 return uV;
248}
249
250static int ldo_set_value(struct udevice *dev, int uV)
251{
252 return lp873x_ldo_val(dev, PMIC_OP_SET, &uV);
253}
254
43d0247e 255static int ldo_get_enable(struct udevice *dev)
99785de8
K
256{
257 bool enable = false;
258 int ret;
259
260 ret = lp873x_ldo_enable(dev, PMIC_OP_GET, &enable);
261 if (ret)
262 return ret;
263
264 return enable;
265}
266
267static int ldo_set_enable(struct udevice *dev, bool enable)
268{
269 return lp873x_ldo_enable(dev, PMIC_OP_SET, &enable);
270}
271
272static int lp873x_buck_probe(struct udevice *dev)
273{
caa4daa2 274 struct dm_regulator_uclass_plat *uc_pdata;
99785de8
K
275 int idx;
276
caa4daa2 277 uc_pdata = dev_get_uclass_plat(dev);
99785de8
K
278 uc_pdata->type = REGULATOR_TYPE_BUCK;
279
280 idx = dev->driver_data;
281 if (idx >= LP873X_BUCK_NUM) {
282 printf("Wrong ID for regulator\n");
283 return -1;
284 }
285
286 uc_pdata->ctrl_reg = lp873x_buck_ctrl[idx];
287 uc_pdata->volt_reg = lp873x_buck_volt[idx];
288
289 return 0;
290}
291
292static int buck_get_value(struct udevice *dev)
293{
294 int uV;
295 int ret;
296
297 ret = lp873x_buck_val(dev, PMIC_OP_GET, &uV);
298 if (ret)
299 return ret;
300
301 return uV;
302}
303
304static int buck_set_value(struct udevice *dev, int uV)
305{
306 return lp873x_buck_val(dev, PMIC_OP_SET, &uV);
307}
308
43d0247e 309static int buck_get_enable(struct udevice *dev)
99785de8
K
310{
311 bool enable = false;
312 int ret;
313
314
315 ret = lp873x_buck_enable(dev, PMIC_OP_GET, &enable);
316 if (ret)
317 return ret;
318
319 return enable;
320}
321
322static int buck_set_enable(struct udevice *dev, bool enable)
323{
324 return lp873x_buck_enable(dev, PMIC_OP_SET, &enable);
325}
326
327static const struct dm_regulator_ops lp873x_ldo_ops = {
328 .get_value = ldo_get_value,
329 .set_value = ldo_set_value,
330 .get_enable = ldo_get_enable,
331 .set_enable = ldo_set_enable,
332};
333
334U_BOOT_DRIVER(lp873x_ldo) = {
335 .name = LP873X_LDO_DRIVER,
336 .id = UCLASS_REGULATOR,
337 .ops = &lp873x_ldo_ops,
338 .probe = lp873x_ldo_probe,
339};
340
341static const struct dm_regulator_ops lp873x_buck_ops = {
342 .get_value = buck_get_value,
343 .set_value = buck_set_value,
344 .get_enable = buck_get_enable,
345 .set_enable = buck_set_enable,
346};
347
348U_BOOT_DRIVER(lp873x_buck) = {
349 .name = LP873X_BUCK_DRIVER,
350 .id = UCLASS_REGULATOR,
351 .ops = &lp873x_buck_ops,
352 .probe = lp873x_buck_probe,
353};