blob: 5809a53fa214c5cb92980cf818f37060fe499f00 [file] [log] [blame]
Keerthy4a030002019-10-24 15:00:51 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2019
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>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Simon Glassdbd79542020-05-10 11:40:11 -060014#include <linux/delay.h>
Keerthy4a030002019-10-24 15:00:51 +053015#include <power/pmic.h>
16#include <power/regulator.h>
17#include <power/tps65941.h>
18
Bhargav Raviprakash83491492024-04-22 09:48:53 +000019/* Single Phase Buck IDs */
20#define TPS65941_BUCK_ID_1 1
21#define TPS65941_BUCK_ID_2 2
22#define TPS65941_BUCK_ID_3 3
23#define TPS65941_BUCK_ID_4 4
24#define TPS65941_BUCK_ID_5 5
25
26/* Multi Phase Buck IDs */
27#define TPS65941_BUCK_ID_12 12
28#define TPS65941_BUCK_ID_34 34
29#define TPS65941_BUCK_ID_123 123
30#define TPS65941_BUCK_ID_1234 1234
31
32/* LDO IDs */
33#define TPS65941_LDO_ID_1 1
34#define TPS65941_LDO_ID_2 2
35#define TPS65941_LDO_ID_3 3
36#define TPS65941_LDO_ID_4 4
37
Bhargav Raviprakash096829d2024-04-22 09:49:01 +000038#define TPS65941_BUCK_CONV_OPS_IDX 0
39#define TPS65941_LDO_CONV_OPS_IDX 0
Bhargav Raviprakash12045722024-04-22 09:49:09 +000040#define TPS65224_LDO_CONV_OPS_IDX 1
41#define TPS65224_BUCK_CONV_OPS_IDX 1
Bhargav Raviprakash096829d2024-04-22 09:49:01 +000042
43struct tps65941_reg_conv_ops {
44 int volt_mask;
45 int (*volt2val)(int idx, int uV);
46 int (*val2volt)(int idx, int volt);
47 int slew_mask;
48 int (*lookup_slew)(int id);
49};
50
Keerthy4a030002019-10-24 15:00:51 +053051static const char tps65941_buck_ctrl[TPS65941_BUCK_NUM] = {0x4, 0x6, 0x8, 0xA,
52 0xC};
53static const char tps65941_buck_vout[TPS65941_BUCK_NUM] = {0xE, 0x10, 0x12,
54 0x14, 0x16};
55static const char tps65941_ldo_ctrl[TPS65941_BUCK_NUM] = {0x1D, 0x1E, 0x1F,
56 0x20};
57static const char tps65941_ldo_vout[TPS65941_BUCK_NUM] = {0x23, 0x24, 0x25,
58 0x26};
59
Bhargav Raviprakash12045722024-04-22 09:49:09 +000060static inline int tps65941_get_chip_id(struct udevice *dev)
61{
62 return dev->parent->driver_data;
63}
64
Keerthy4a030002019-10-24 15:00:51 +053065static int tps65941_buck_enable(struct udevice *dev, int op, bool *enable)
66{
67 int ret;
68 unsigned int adr;
Simon Glass71fa5b42020-12-03 16:55:18 -070069 struct dm_regulator_uclass_plat *uc_pdata;
Keerthy4a030002019-10-24 15:00:51 +053070
Simon Glass71fa5b42020-12-03 16:55:18 -070071 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +053072 adr = uc_pdata->ctrl_reg;
73
74 ret = pmic_reg_read(dev->parent, adr);
75 if (ret < 0)
76 return ret;
77
78 if (op == PMIC_OP_GET) {
79 ret &= TPS65941_BUCK_MODE_MASK;
80
81 if (ret)
82 *enable = true;
83 else
84 *enable = false;
85
86 return 0;
87 } else if (op == PMIC_OP_SET) {
88 if (*enable)
89 ret |= TPS65941_BUCK_MODE_MASK;
90 else
91 ret &= ~TPS65941_BUCK_MODE_MASK;
92 ret = pmic_reg_write(dev->parent, adr, ret);
93 if (ret)
94 return ret;
95 }
96
97 return 0;
98}
99
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000100static int tps65941_buck_volt2val(__maybe_unused int idx, int uV)
Keerthy4a030002019-10-24 15:00:51 +0530101{
102 if (uV > TPS65941_BUCK_VOLT_MAX)
103 return -EINVAL;
104 else if (uV > 1650000)
105 return (uV - 1660000) / 20000 + 0xAB;
106 else if (uV > 1110000)
107 return (uV - 1110000) / 10000 + 0x73;
108 else if (uV > 600000)
109 return (uV - 600000) / 5000 + 0x0F;
110 else if (uV >= 300000)
111 return (uV - 300000) / 20000 + 0x00;
112 else
113 return -EINVAL;
114}
115
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000116static int tps65941_buck_val2volt(__maybe_unused int idx, int val)
Keerthy4a030002019-10-24 15:00:51 +0530117{
118 if (val > TPS65941_BUCK_VOLT_MAX_HEX)
119 return -EINVAL;
120 else if (val > 0xAB)
121 return 1660000 + (val - 0xAB) * 20000;
122 else if (val > 0x73)
123 return 1100000 + (val - 0x73) * 10000;
124 else if (val > 0xF)
125 return 600000 + (val - 0xF) * 5000;
126 else if (val >= 0x0)
127 return 300000 + val * 5000;
128 else
129 return -EINVAL;
130}
131
132int tps65941_lookup_slew(int id)
133{
134 switch (id) {
135 case 0:
136 return 33000;
137 case 1:
138 return 20000;
139 case 2:
140 return 10000;
141 case 3:
142 return 5000;
143 case 4:
144 return 2500;
145 case 5:
146 return 1300;
147 case 6:
148 return 630;
149 case 7:
150 return 310;
151 default:
152 return -1;
153 }
154}
155
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000156static int tps65224_buck_volt2val(int idx, int uV)
157{
158 /* This functions maps a value which is in micro Volts to the VSET value.
159 * The mapping is as per the datasheet of TPS65224.
160 */
161
162 if (uV > TPS65224_BUCK_VOLT_MAX)
163 return -EINVAL;
164
165 if (idx > 0) {
166 /* Buck2, Buck3 and Buck4 of TPS65224 has a different schema in
167 * converting b/w micro_volt and VSET hex values
168 *
169 * VSET value starts from 0x00 for 0.5V, and for every increment
170 * in VSET value the output voltage increases by 25mV. This is upto
171 * 1.15V where VSET is 0x1A.
172 *
173 * For 0x1B the output voltage is 1.2V, and for every increment of
174 * VSET the output voltage increases by 50mV upto the max voltage of
175 * 3.3V
176 *
177 * | Voltage Ranges | VSET Ranges | Voltage Step |
178 * +-----------------+--------------+--------------+
179 * | 0.5V to 1.50V | 0x00 to 0x1A | 25mV |
180 * | 1.2V to 3.3V | 0x1B to 0x45 | 50mV |
181 */
182 if (uV >= 1200000)
183 return (uV - 1200000) / 50000 + 0x1B;
184 else if (uV >= 500000)
185 return (uV - 500000) / 25000;
186 else
187 return -EINVAL;
188 }
189
190 /* Buck1 and Buck12(dual phase) has a different mapping b/w output
191 * voltage and VSET value.
192 *
193 * | Voltage Ranges | VSET Ranges | Voltage Step |
194 * +-----------------+--------------+--------------+
195 * | 0.5V to 0.58V | 0xA to 0xE | 20mV |
196 * | 0.6V to 1.095V | 0xF to 0x72 | 5mV |
197 * | 1.1V to 1.65V | 0x73 to 0xAA | 10mV |
198 * | 1.6V to 3.3V | 0xAB to 0xFD | 20mV |
199 *
200 */
201 if (uV >= 1660000)
202 return (uV - 1660000) / 20000 + 0xAB;
203 else if (uV >= 1100000)
204 return (uV - 1100000) / 10000 + 0x73;
205 else if (uV >= 600000)
206 return (uV - 600000) / 5000 + 0x0F;
207 else if (uV >= 500000)
208 return (uV - 500000) / 20000 + 0x0A;
209 else
210 return -EINVAL;
211}
212
213static int tps65224_buck_val2volt(int idx, int val)
214{
215 /* This function does the opposite to the tps65224_buck_volt2val function
216 * described above.
217 * This maps the VSET value to micro volts. Please refer to the ranges
218 * mentioned the comments of tps65224_buck_volt2val.
219 */
220
221 if (idx > 0) {
222 if (val > TPS65224_BUCK234_VOLT_MAX_HEX)
223 return -EINVAL;
224 else if (val >= 0x1B)
225 return 1200000 + (val - 0x1B) * 50000;
226 else if (val >= 0x00)
227 return 500000 + (val - 0x00) * 25000;
228 else
229 return -EINVAL;
230 }
231
232 if (val > TPS65224_BUCK1_VOLT_MAX_HEX)
233 return -EINVAL;
234 else if (val >= 0xAB)
235 return 1660000 + (val - 0xAB) * 20000;
236 else if (val >= 0x73)
237 return 1100000 + (val - 0x73) * 10000;
238 else if (val >= 0xF)
239 return 600000 + (val - 0xF) * 5000;
240 else if (val >= 0xA)
241 return 500000 + (val - 0xA) * 20000;
242 else
243 return -EINVAL;
244}
245
246int tps65224_lookup_slew(int id)
247{
248 switch (id) {
249 case 0:
250 return 10000;
251 case 1:
252 return 5000;
253 case 2:
254 return 2500;
255 case 3:
256 return 1250;
257 default:
258 return -1;
259 }
260}
261
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000262static const struct tps65941_reg_conv_ops buck_conv_ops[] = {
263 [TPS65941_BUCK_CONV_OPS_IDX] = {
264 .volt_mask = TPS65941_BUCK_VOLT_MASK,
265 .volt2val = tps65941_buck_volt2val,
266 .val2volt = tps65941_buck_val2volt,
267 .slew_mask = TP65941_BUCK_CONF_SLEW_MASK,
268 .lookup_slew = tps65941_lookup_slew,
269 },
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000270 [TPS65224_BUCK_CONV_OPS_IDX] = {
271 .volt_mask = TPS65941_BUCK_VOLT_MASK,
272 .volt2val = tps65224_buck_volt2val,
273 .val2volt = tps65224_buck_val2volt,
274 .slew_mask = TPS65224_BUCK_CONF_SLEW_MASK,
275 .lookup_slew = tps65224_lookup_slew,
276 },
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000277};
278
Keerthy4a030002019-10-24 15:00:51 +0530279static int tps65941_buck_val(struct udevice *dev, int op, int *uV)
280{
281 unsigned int hex, adr;
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000282 int ret, delta, uwait, slew, idx;
Simon Glass71fa5b42020-12-03 16:55:18 -0700283 struct dm_regulator_uclass_plat *uc_pdata;
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000284 const struct tps65941_reg_conv_ops *conv_ops;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000285 ulong chip_id;
Keerthy4a030002019-10-24 15:00:51 +0530286
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000287 idx = dev->driver_data;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000288 chip_id = tps65941_get_chip_id(dev);
289 if (chip_id == TPS65224) {
290 /* idx is the buck id number as per devicetree node which will be same
291 * as the regulator name in the datasheet.
292 * The idx for buck1. buck2, buck3, buck4, buck12 will be 1, 2, 3, 4
293 * and 12 respectively.
294 * In the driver the numbering is from 0. Hence the -1.
295 */
296 idx = (idx == TPS65941_BUCK_ID_12) ? 0 : (idx - 1);
297 conv_ops = &buck_conv_ops[TPS65224_BUCK_CONV_OPS_IDX];
298 } else {
299 conv_ops = &buck_conv_ops[TPS65941_BUCK_CONV_OPS_IDX];
300 }
301
Simon Glass71fa5b42020-12-03 16:55:18 -0700302 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +0530303
304 if (op == PMIC_OP_GET)
305 *uV = 0;
306
307 adr = uc_pdata->volt_reg;
308
309 ret = pmic_reg_read(dev->parent, adr);
310 if (ret < 0)
311 return ret;
312
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000313 ret &= conv_ops->volt_mask;
314 ret = conv_ops->val2volt(idx, ret);
Keerthy4a030002019-10-24 15:00:51 +0530315 if (ret < 0)
316 return ret;
317
318 if (op == PMIC_OP_GET) {
319 *uV = ret;
320 return 0;
321 }
322
323 /*
324 * Compute the delta voltage, find the slew rate and wait
325 * for the appropriate amount of time after voltage switch
326 */
327 if (*uV > ret)
328 delta = *uV - ret;
329 else
330 delta = ret - *uV;
331
332 slew = pmic_reg_read(dev->parent, uc_pdata->ctrl_reg + 1);
333 if (slew < 0)
334 return ret;
335
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000336 slew &= conv_ops->slew_mask;
337 slew = conv_ops->lookup_slew(slew);
Keerthy4a030002019-10-24 15:00:51 +0530338 if (slew <= 0)
339 return ret;
340
341 uwait = delta / slew;
342
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000343 hex = conv_ops->volt2val(idx, *uV);
Keerthy4a030002019-10-24 15:00:51 +0530344 if (hex < 0)
345 return hex;
346
347 ret &= 0x0;
348 ret = hex;
349
350 ret = pmic_reg_write(dev->parent, adr, ret);
351
352 udelay(uwait);
353
354 return ret;
355}
356
357static int tps65941_ldo_enable(struct udevice *dev, int op, bool *enable)
358{
359 int ret;
360 unsigned int adr;
Simon Glass71fa5b42020-12-03 16:55:18 -0700361 struct dm_regulator_uclass_plat *uc_pdata;
Keerthy4a030002019-10-24 15:00:51 +0530362
Simon Glass71fa5b42020-12-03 16:55:18 -0700363 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +0530364 adr = uc_pdata->ctrl_reg;
365
366 ret = pmic_reg_read(dev->parent, adr);
367 if (ret < 0)
368 return ret;
369
370 if (op == PMIC_OP_GET) {
371 ret &= TPS65941_LDO_MODE_MASK;
372
373 if (ret)
374 *enable = true;
375 else
376 *enable = false;
377
378 return 0;
379 } else if (op == PMIC_OP_SET) {
380 if (*enable)
381 ret |= TPS65941_LDO_MODE_MASK;
382 else
383 ret &= ~TPS65941_LDO_MODE_MASK;
384 ret = pmic_reg_write(dev->parent, adr, ret);
385 if (ret)
386 return ret;
387 }
388
389 return 0;
390}
391
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000392static int tps65941_ldo_val2volt(__maybe_unused int idx, int val)
Keerthy4a030002019-10-24 15:00:51 +0530393{
394 if (val > TPS65941_LDO_VOLT_MAX_HEX || val < TPS65941_LDO_VOLT_MIN_HEX)
395 return -EINVAL;
396 else if (val >= TPS65941_LDO_VOLT_MIN_HEX)
397 return 600000 + (val - TPS65941_LDO_VOLT_MIN_HEX) * 50000;
398 else
399 return -EINVAL;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000400}
401
402static int tps65224_ldo_volt2val(int idx, int uV)
403{
404 int base = TPS65224_LDO1_VOLT_MIN;
405 int max = TPS65224_LDO1_VOLT_MAX;
406 int offset = TPS65224_LDO1_VOLT_MIN_HEX;
407 int step = TPS65224_LDO_STEP;
408
409 if (idx > 0) {
410 base = TPS65224_LDO23_VOLT_MIN;
411 max = TPS65224_LDO23_VOLT_MAX;
412 offset = TPS65224_LDO23_VOLT_MIN_HEX;
413 }
414
415 if (uV > max)
416 return -EINVAL;
417 else if (uV >= base)
418 return (uV - base) / step + offset;
419 else
420 return -EINVAL;
421}
422
423static int tps65224_ldo_val2volt(int idx, int val)
424{
425 int reg_base = TPS65224_LDO1_VOLT_MIN_HEX;
426 int reg_max = TPS65224_LDO1_VOLT_MAX_HEX;
427 int base = TPS65224_LDO1_VOLT_MIN;
428 int max = TPS65224_LDO1_VOLT_MAX;
429 int step = TPS65224_LDO_STEP;
430 /* In LDOx_VOUT reg the BIT0 is reserved and the
431 * vout value is stored from BIT1 to BIT7.
432 * Hence the below bit shit is done.
433 */
434 int mask = TPS65224_LDO_VOLT_MASK >> 1;
435
436 if (idx > 0) {
437 base = TPS65224_LDO23_VOLT_MIN;
438 max = TPS65224_LDO23_VOLT_MAX;
439 reg_base = TPS65224_LDO23_VOLT_MIN_HEX;
440 reg_max = TPS65224_LDO23_VOLT_MAX_HEX;
441 }
442
443 /* The VSET register of LDO has its 0th bit as reserved
444 * hence shifting the value to right by 1 bit.
445 */
446 val = val >> 1;
447
448 if (val < 0 || val > mask)
449 return -EINVAL;
450
451 if (val <= reg_base)
452 return base;
453
454 if (val >= reg_max)
455 return max;
456
457 return base + (step * (val - reg_base));
Keerthy4a030002019-10-24 15:00:51 +0530458}
459
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000460static const struct tps65941_reg_conv_ops ldo_conv_ops[] = {
461 [TPS65941_LDO_CONV_OPS_IDX] = {
462 .volt_mask = TPS65941_LDO_VOLT_MASK,
463 .volt2val = tps65941_buck_volt2val,
464 .val2volt = tps65941_ldo_val2volt,
465 },
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000466 [TPS65224_LDO_CONV_OPS_IDX] = {
467 .volt_mask = TPS65224_LDO_VOLT_MASK,
468 .volt2val = tps65224_ldo_volt2val,
469 .val2volt = tps65224_ldo_val2volt,
470 },
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000471};
472
Keerthy4a030002019-10-24 15:00:51 +0530473static int tps65941_ldo_val(struct udevice *dev, int op, int *uV)
474{
475 unsigned int hex, adr;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000476 int ret, ret_volt, idx;
Simon Glass71fa5b42020-12-03 16:55:18 -0700477 struct dm_regulator_uclass_plat *uc_pdata;
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000478 const struct tps65941_reg_conv_ops *conv_ops;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000479 ulong chip_id;
Keerthy4a030002019-10-24 15:00:51 +0530480
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000481 chip_id = tps65941_get_chip_id(dev);
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000482 idx = dev->driver_data;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000483 if (chip_id == TPS65224) {
484 /* idx is the ldo id number as per devicetree node which will be same
485 * as the regulator name in the datasheet.
486 * The idx for ldo1, ldo2, ldo3 will be 1, 2 & 3 respectively.
487 * In the driver the numbering is from 0. Hence the -1.
488 */
489 idx = idx - 1;
490 conv_ops = &ldo_conv_ops[TPS65224_LDO_CONV_OPS_IDX];
491 } else {
492 conv_ops = &ldo_conv_ops[TPS65941_LDO_CONV_OPS_IDX];
493 }
494
Simon Glass71fa5b42020-12-03 16:55:18 -0700495 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +0530496
497 if (op == PMIC_OP_GET)
498 *uV = 0;
499
500 adr = uc_pdata->volt_reg;
501
502 ret = pmic_reg_read(dev->parent, adr);
503 if (ret < 0)
504 return ret;
505
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000506 ret &= conv_ops->volt_mask;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000507 ret_volt = conv_ops->val2volt(idx, ret);
508 if (ret_volt < 0)
509 return ret_volt;
Keerthy4a030002019-10-24 15:00:51 +0530510
511 if (op == PMIC_OP_GET) {
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000512 *uV = ret_volt;
Keerthy4a030002019-10-24 15:00:51 +0530513 return 0;
514 }
515
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000516 /* TPS65224 LDO1 in BYPASS mode only supports 2.2V min to 3.6V max */
517 if (chip_id == TPS65224 && idx == 0 && (ret & BIT(TPS65224_LDO_BYP_CONFIG)) &&
518 *uV < TPS65224_LDO1_VOLT_BYP_MIN)
519 return -EINVAL;
520
521 /* TPS65224 LDO2 & LDO3 in BYPASS mode supports 1.5V min to 5.5V max */
522 if (chip_id == TPS65224 && idx > 0 && (ret & BIT(TPS65224_LDO_BYP_CONFIG)) &&
523 *uV < TPS65224_LDO23_VOLT_BYP_MIN)
524 return -EINVAL;
525
Bhargav Raviprakash096829d2024-04-22 09:49:01 +0000526 hex = conv_ops->volt2val(idx, *uV);
Keerthy4a030002019-10-24 15:00:51 +0530527 if (hex < 0)
528 return hex;
529
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000530 if (chip_id == TPS65224) {
531 hex = hex << TPS65941_LDO_MODE_MASK;
532 ret &= ~TPS65224_LDO_VOLT_MASK;
533 ret |= hex;
534 } else {
535 ret = hex;
536 }
Keerthy4a030002019-10-24 15:00:51 +0530537
538 ret = pmic_reg_write(dev->parent, adr, ret);
539
540 return ret;
541}
542
543static int tps65941_ldo_probe(struct udevice *dev)
544{
Simon Glass71fa5b42020-12-03 16:55:18 -0700545 struct dm_regulator_uclass_plat *uc_pdata;
Keerthy4a030002019-10-24 15:00:51 +0530546 int idx;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000547 ulong chip_id;
548
549 chip_id = tps65941_get_chip_id(dev);
Keerthy4a030002019-10-24 15:00:51 +0530550
Simon Glass71fa5b42020-12-03 16:55:18 -0700551 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +0530552 uc_pdata->type = REGULATOR_TYPE_LDO;
553
554 idx = dev->driver_data;
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000555 switch (idx) {
556 case TPS65941_LDO_ID_1:
557 case TPS65941_LDO_ID_2:
558 case TPS65941_LDO_ID_3:
Keerthy4a030002019-10-24 15:00:51 +0530559 debug("Single phase regulator\n");
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000560 break;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000561 case TPS65941_LDO_ID_4:
562 if (chip_id != TPS65224) {
563 debug("Single phase regulator\n");
564 break;
565 }
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000566 default:
567 pr_err("Wrong ID for regulator\n");
Keerthy4a030002019-10-24 15:00:51 +0530568 return -EINVAL;
569 }
570
571 uc_pdata->ctrl_reg = tps65941_ldo_ctrl[idx - 1];
572 uc_pdata->volt_reg = tps65941_ldo_vout[idx - 1];
573
574 return 0;
575}
576
577static int tps65941_buck_probe(struct udevice *dev)
578{
Simon Glass71fa5b42020-12-03 16:55:18 -0700579 struct dm_regulator_uclass_plat *uc_pdata;
Keerthy4a030002019-10-24 15:00:51 +0530580 int idx;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000581 ulong chip_id;
582
583 chip_id = tps65941_get_chip_id(dev);
Keerthy4a030002019-10-24 15:00:51 +0530584
Simon Glass71fa5b42020-12-03 16:55:18 -0700585 uc_pdata = dev_get_uclass_plat(dev);
Keerthy4a030002019-10-24 15:00:51 +0530586 uc_pdata->type = REGULATOR_TYPE_BUCK;
587
588 idx = dev->driver_data;
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000589 switch (idx) {
590 case TPS65941_BUCK_ID_1:
591 case TPS65941_BUCK_ID_2:
592 case TPS65941_BUCK_ID_3:
593 case TPS65941_BUCK_ID_4:
Keerthy4a030002019-10-24 15:00:51 +0530594 debug("Single phase regulator\n");
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000595 break;
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000596 case TPS65941_BUCK_ID_5:
597 if (chip_id != TPS65224) {
598 debug("Single phase regulator\n");
599 } else {
600 pr_err("Wrong ID for regulator\n");
601 return -EINVAL;
602 }
603 break;
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000604 case TPS65941_BUCK_ID_12:
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000605 idx = 1;
606 break;
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000607 case TPS65941_BUCK_ID_123:
608 case TPS65941_BUCK_ID_1234:
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000609 if (chip_id != TPS65224) {
610 idx = 1;
611 } else {
612 pr_err("Wrong ID for regulator\n");
613 return -EINVAL;
614 }
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000615 break;
616 case TPS65941_BUCK_ID_34:
Bhargav Raviprakash12045722024-04-22 09:49:09 +0000617 if (chip_id != TPS65224) {
618 idx = 3;
619 } else {
620 pr_err("Wrong ID for regulator\n");
621 return -EINVAL;
622 }
Bhargav Raviprakash83491492024-04-22 09:48:53 +0000623 break;
624 default:
625 pr_err("Wrong ID for regulator\n");
Keerthy4a030002019-10-24 15:00:51 +0530626 return -EINVAL;
627 }
628
629 uc_pdata->ctrl_reg = tps65941_buck_ctrl[idx - 1];
630 uc_pdata->volt_reg = tps65941_buck_vout[idx - 1];
631
632 return 0;
633}
634
635static int ldo_get_value(struct udevice *dev)
636{
637 int uV;
638 int ret;
639
640 ret = tps65941_ldo_val(dev, PMIC_OP_GET, &uV);
641 if (ret)
642 return ret;
643
644 return uV;
645}
646
647static int ldo_set_value(struct udevice *dev, int uV)
648{
649 return tps65941_ldo_val(dev, PMIC_OP_SET, &uV);
650}
651
652static int ldo_get_enable(struct udevice *dev)
653{
654 bool enable = false;
655 int ret;
656
657 ret = tps65941_ldo_enable(dev, PMIC_OP_GET, &enable);
658 if (ret)
659 return ret;
660
661 return enable;
662}
663
664static int ldo_set_enable(struct udevice *dev, bool enable)
665{
666 return tps65941_ldo_enable(dev, PMIC_OP_SET, &enable);
667}
668
669static int buck_get_value(struct udevice *dev)
670{
671 int uV;
672 int ret;
673
674 ret = tps65941_buck_val(dev, PMIC_OP_GET, &uV);
675 if (ret)
676 return ret;
677
678 return uV;
679}
680
681static int buck_set_value(struct udevice *dev, int uV)
682{
683 return tps65941_buck_val(dev, PMIC_OP_SET, &uV);
684}
685
686static int buck_get_enable(struct udevice *dev)
687{
688 bool enable = false;
689 int ret;
690
691 ret = tps65941_buck_enable(dev, PMIC_OP_GET, &enable);
692 if (ret)
693 return ret;
694
695 return enable;
696}
697
698static int buck_set_enable(struct udevice *dev, bool enable)
699{
700 return tps65941_buck_enable(dev, PMIC_OP_SET, &enable);
701}
702
703static const struct dm_regulator_ops tps65941_ldo_ops = {
704 .get_value = ldo_get_value,
705 .set_value = ldo_set_value,
706 .get_enable = ldo_get_enable,
707 .set_enable = ldo_set_enable,
708};
709
710U_BOOT_DRIVER(tps65941_ldo) = {
711 .name = TPS65941_LDO_DRIVER,
712 .id = UCLASS_REGULATOR,
713 .ops = &tps65941_ldo_ops,
714 .probe = tps65941_ldo_probe,
715};
716
717static const struct dm_regulator_ops tps65941_buck_ops = {
718 .get_value = buck_get_value,
719 .set_value = buck_set_value,
720 .get_enable = buck_get_enable,
721 .set_enable = buck_set_enable,
722};
723
724U_BOOT_DRIVER(tps65941_buck) = {
725 .name = TPS65941_BUCK_DRIVER,
726 .id = UCLASS_REGULATOR,
727 .ops = &tps65941_buck_ops,
728 .probe = tps65941_buck_probe,
729};