2 * Copyright (C) 2018 Samsung Electronics
3 * Jaehoon Chung <jh80.chung@samsung.com>
5 * SPDX-License-Identifier: GPL-2.0
13 #include <power/pmic.h>
14 #include <power/regulator.h>
15 #include <power/s2mps11.h>
17 DECLARE_GLOBAL_DATA_PTR
;
19 #define MODE(_id, _val, _name) { \
21 .register_value = _val, \
25 /* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */
26 static struct dm_regulator_mode s2mps11_buck_modes
[] = {
27 MODE(OP_OFF
, S2MPS11_BUCK_MODE_OFF
, "OFF"),
28 MODE(OP_STANDBY
, S2MPS11_BUCK_MODE_STANDBY
, "ON/OFF"),
29 MODE(OP_ON
, S2MPS11_BUCK_MODE_STANDBY
, "ON"),
32 static struct dm_regulator_mode s2mps11_ldo_modes
[] = {
33 MODE(OP_OFF
, S2MPS11_LDO_MODE_OFF
, "OFF"),
34 MODE(OP_STANDBY
, S2MPS11_LDO_MODE_STANDBY
, "ON/OFF"),
35 MODE(OP_STANDBY_LPM
, S2MPS11_LDO_MODE_STANDBY_LPM
, "ON/LPM"),
36 MODE(OP_ON
, S2MPS11_LDO_MODE_ON
, "ON"),
39 static const char s2mps11_buck_ctrl
[] = {
40 0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
43 static const char s2mps11_buck_out
[] = {
44 0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
47 static int s2mps11_buck_hex2volt(int buck
, int hex
)
58 if (hex
> S2MPS11_BUCK7_8_10_VOLT_MAX_HEX
)
61 uV
= hex
* S2MPS11_BUCK_HSTEP
+ S2MPS11_BUCK_UV_HMIN
;
64 if (hex
> S2MPS11_BUCK9_VOLT_MAX_HEX
)
66 uV
= hex
* S2MPS11_BUCK9_STEP
* 2 + S2MPS11_BUCK9_UV_MIN
;
69 if (buck
== 5 && hex
> S2MPS11_BUCK5_VOLT_MAX_HEX
)
71 else if (buck
!= 5 && hex
> S2MPS11_BUCK_VOLT_MAX_HEX
)
74 uV
= hex
* S2MPS11_BUCK_LSTEP
+ S2MPS11_BUCK_UV_MIN
;
80 pr_err("Value: %#x is wrong for BUCK%d", hex
, buck
);
84 static int s2mps11_buck_volt2hex(int buck
, int uV
)
92 hex
= (uV
- S2MPS11_BUCK_UV_HMIN
) / S2MPS11_BUCK_HSTEP
;
93 if (hex
> S2MPS11_BUCK7_8_10_VOLT_MAX_HEX
)
98 hex
= (uV
- S2MPS11_BUCK9_UV_MIN
) / S2MPS11_BUCK9_STEP
;
99 if (hex
> S2MPS11_BUCK9_VOLT_MAX_HEX
)
103 hex
= (uV
- S2MPS11_BUCK_UV_MIN
) / S2MPS11_BUCK_LSTEP
;
104 if (buck
== 5 && hex
> S2MPS11_BUCK5_VOLT_MAX_HEX
)
106 else if (buck
!= 5 && hex
> S2MPS11_BUCK_VOLT_MAX_HEX
)
115 pr_err("Value: %d uV is wrong for BUCK%d", uV
, buck
);
119 static int s2mps11_buck_val(struct udevice
*dev
, int op
, int *uV
)
125 buck
= dev
->driver_data
;
126 if (buck
< 1 || buck
> S2MPS11_BUCK_NUM
) {
127 pr_err("Wrong buck number: %d\n", buck
);
131 if (op
== PMIC_OP_GET
)
134 addr
= s2mps11_buck_out
[buck
];
138 mask
= S2MPS11_BUCK9_VOLT_MASK
;
141 mask
= S2MPS11_BUCK_VOLT_MASK
;
145 ret
= pmic_read(dev
->parent
, addr
, &val
, 1);
149 if (op
== PMIC_OP_GET
) {
151 ret
= s2mps11_buck_hex2volt(buck
, val
);
158 hex
= s2mps11_buck_volt2hex(buck
, *uV
);
164 ret
= pmic_write(dev
->parent
, addr
, &val
, 1);
169 static int s2mps11_buck_mode(struct udevice
*dev
, int op
, int *opmode
)
171 unsigned int addr
, mode
;
175 buck
= dev
->driver_data
;
176 if (buck
< 1 || buck
> S2MPS11_BUCK_NUM
) {
177 pr_err("Wrong buck number: %d\n", buck
);
181 addr
= s2mps11_buck_ctrl
[buck
];
183 ret
= pmic_read(dev
->parent
, addr
, &val
, 1);
187 if (op
== PMIC_OP_GET
) {
188 val
&= (S2MPS11_BUCK_MODE_MASK
<< S2MPS11_BUCK_MODE_SHIFT
);
190 case S2MPS11_BUCK_MODE_OFF
:
193 case S2MPS11_BUCK_MODE_STANDBY
:
194 *opmode
= OP_STANDBY
;
196 case S2MPS11_BUCK_MODE_ON
:
207 mode
= S2MPS11_BUCK_MODE_OFF
;
210 mode
= S2MPS11_BUCK_MODE_STANDBY
;
213 mode
= S2MPS11_BUCK_MODE_ON
;
216 pr_err("Wrong mode: %d for buck: %d\n", *opmode
, buck
);
220 val
&= ~(S2MPS11_BUCK_MODE_MASK
<< S2MPS11_BUCK_MODE_SHIFT
);
222 ret
= pmic_write(dev
->parent
, addr
, &val
, 1);
227 static int s2mps11_buck_enable(struct udevice
*dev
, int op
, bool *enable
)
231 if (op
== PMIC_OP_GET
) {
232 ret
= s2mps11_buck_mode(dev
, op
, &on_off
);
245 } else if (op
== PMIC_OP_SET
) {
251 ret
= s2mps11_buck_mode(dev
, op
, &on_off
);
259 static int buck_get_value(struct udevice
*dev
)
264 ret
= s2mps11_buck_val(dev
, PMIC_OP_GET
, &uV
);
270 static int buck_set_value(struct udevice
*dev
, int uV
)
272 return s2mps11_buck_val(dev
, PMIC_OP_SET
, &uV
);
275 static int buck_get_enable(struct udevice
*dev
)
280 ret
= s2mps11_buck_enable(dev
, PMIC_OP_GET
, &enable
);
286 static int buck_set_enable(struct udevice
*dev
, bool enable
)
288 return s2mps11_buck_enable(dev
, PMIC_OP_SET
, &enable
);
291 static int buck_get_mode(struct udevice
*dev
)
296 ret
= s2mps11_buck_mode(dev
, PMIC_OP_GET
, &mode
);
303 static int buck_set_mode(struct udevice
*dev
, int mode
)
305 return s2mps11_buck_mode(dev
, PMIC_OP_SET
, &mode
);
308 static int s2mps11_buck_probe(struct udevice
*dev
)
310 struct dm_regulator_uclass_platdata
*uc_pdata
;
312 uc_pdata
= dev_get_uclass_platdata(dev
);
314 uc_pdata
->type
= REGULATOR_TYPE_BUCK
;
315 uc_pdata
->mode
= s2mps11_buck_modes
;
316 uc_pdata
->mode_count
= ARRAY_SIZE(s2mps11_buck_modes
);
321 static const struct dm_regulator_ops s2mps11_buck_ops
= {
322 .get_value
= buck_get_value
,
323 .set_value
= buck_set_value
,
324 .get_enable
= buck_get_enable
,
325 .set_enable
= buck_set_enable
,
326 .get_mode
= buck_get_mode
,
327 .set_mode
= buck_set_mode
,
330 U_BOOT_DRIVER(s2mps11_buck
) = {
331 .name
= S2MPS11_BUCK_DRIVER
,
332 .id
= UCLASS_REGULATOR
,
333 .ops
= &s2mps11_buck_ops
,
334 .probe
= s2mps11_buck_probe
,
337 static int s2mps11_ldo_hex2volt(int ldo
, int hex
)
341 if (hex
> S2MPS11_LDO_VOLT_MAX_HEX
) {
342 pr_err("Value: %#x is wrong for LDO%d", hex
, ldo
);
352 uV
= hex
* S2MPS11_LDO_STEP
+ S2MPS11_LDO_UV_MIN
;
355 uV
= hex
* S2MPS11_LDO_STEP
* 2 + S2MPS11_LDO_UV_MIN
;
362 static int s2mps11_ldo_volt2hex(int ldo
, int uV
)
372 hex
= (uV
- S2MPS11_LDO_UV_MIN
) / S2MPS11_LDO_STEP
;
375 hex
= (uV
- S2MPS11_LDO_UV_MIN
) / (S2MPS11_LDO_STEP
* 2);
379 if (hex
>= 0 && hex
<= S2MPS11_LDO_VOLT_MAX_HEX
)
382 pr_err("Value: %d uV is wrong for LDO%d", uV
, ldo
);
388 static int s2mps11_ldo_val(struct udevice
*dev
, int op
, int *uV
)
394 ldo
= dev
->driver_data
;
395 if (ldo
< 1 || ldo
> S2MPS11_LDO_NUM
) {
396 pr_err("Wrong ldo number: %d\n", ldo
);
400 addr
= S2MPS11_REG_L1CTRL
+ ldo
- 1;
402 ret
= pmic_read(dev
->parent
, addr
, &val
, 1);
406 if (op
== PMIC_OP_GET
) {
408 val
&= S2MPS11_LDO_VOLT_MASK
;
409 ret
= s2mps11_ldo_hex2volt(ldo
, val
);
417 hex
= s2mps11_ldo_volt2hex(ldo
, *uV
);
421 val
&= ~S2MPS11_LDO_VOLT_MASK
;
423 ret
= pmic_write(dev
->parent
, addr
, &val
, 1);
428 static int s2mps11_ldo_mode(struct udevice
*dev
, int op
, int *opmode
)
430 unsigned int addr
, mode
;
434 ldo
= dev
->driver_data
;
435 if (ldo
< 1 || ldo
> S2MPS11_LDO_NUM
) {
436 pr_err("Wrong ldo number: %d\n", ldo
);
439 addr
= S2MPS11_REG_L1CTRL
+ ldo
- 1;
441 ret
= pmic_read(dev
->parent
, addr
, &val
, 1);
445 if (op
== PMIC_OP_GET
) {
446 val
&= (S2MPS11_LDO_MODE_MASK
<< S2MPS11_LDO_MODE_SHIFT
);
448 case S2MPS11_LDO_MODE_OFF
:
451 case S2MPS11_LDO_MODE_STANDBY
:
452 *opmode
= OP_STANDBY
;
454 case S2MPS11_LDO_MODE_STANDBY_LPM
:
455 *opmode
= OP_STANDBY_LPM
;
457 case S2MPS11_LDO_MODE_ON
:
468 mode
= S2MPS11_LDO_MODE_OFF
;
471 mode
= S2MPS11_LDO_MODE_STANDBY
;
474 mode
= S2MPS11_LDO_MODE_STANDBY_LPM
;
477 mode
= S2MPS11_LDO_MODE_ON
;
480 pr_err("Wrong mode: %d for ldo: %d\n", *opmode
, ldo
);
484 val
&= ~(S2MPS11_LDO_MODE_MASK
<< S2MPS11_LDO_MODE_SHIFT
);
486 ret
= pmic_write(dev
->parent
, addr
, &val
, 1);
491 static int s2mps11_ldo_enable(struct udevice
*dev
, int op
, bool *enable
)
495 if (op
== PMIC_OP_GET
) {
496 ret
= s2mps11_ldo_mode(dev
, op
, &on_off
);
509 } else if (op
== PMIC_OP_SET
) {
515 ret
= s2mps11_ldo_mode(dev
, op
, &on_off
);
523 static int ldo_get_value(struct udevice
*dev
)
528 ret
= s2mps11_ldo_val(dev
, PMIC_OP_GET
, &uV
);
535 static int ldo_set_value(struct udevice
*dev
, int uV
)
537 return s2mps11_ldo_val(dev
, PMIC_OP_SET
, &uV
);
540 static int ldo_get_enable(struct udevice
*dev
)
545 ret
= s2mps11_ldo_enable(dev
, PMIC_OP_GET
, &enable
);
551 static int ldo_set_enable(struct udevice
*dev
, bool enable
)
553 return s2mps11_ldo_enable(dev
, PMIC_OP_SET
, &enable
);
556 static int ldo_get_mode(struct udevice
*dev
)
560 ret
= s2mps11_ldo_mode(dev
, PMIC_OP_GET
, &mode
);
566 static int ldo_set_mode(struct udevice
*dev
, int mode
)
568 return s2mps11_ldo_mode(dev
, PMIC_OP_SET
, &mode
);
571 static int s2mps11_ldo_probe(struct udevice
*dev
)
573 struct dm_regulator_uclass_platdata
*uc_pdata
;
575 uc_pdata
= dev_get_uclass_platdata(dev
);
576 uc_pdata
->type
= REGULATOR_TYPE_LDO
;
577 uc_pdata
->mode
= s2mps11_ldo_modes
;
578 uc_pdata
->mode_count
= ARRAY_SIZE(s2mps11_ldo_modes
);
583 static const struct dm_regulator_ops s2mps11_ldo_ops
= {
584 .get_value
= ldo_get_value
,
585 .set_value
= ldo_set_value
,
586 .get_enable
= ldo_get_enable
,
587 .set_enable
= ldo_set_enable
,
588 .get_mode
= ldo_get_mode
,
589 .set_mode
= ldo_set_mode
,
592 U_BOOT_DRIVER(s2mps11_ldo
) = {
593 .name
= S2MPS11_LDO_DRIVER
,
594 .id
= UCLASS_REGULATOR
,
595 .ops
= &s2mps11_ldo_ops
,
596 .probe
= s2mps11_ldo_probe
,