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