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