1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * NXP PCA9450 regulator driver
4 * Copyright (C) 2022 Marek Vasut <marex@denx.de>
7 * ROHM BD71837 regulator driver
13 #include <linux/bitops.h>
14 #include <power/pca9450.h>
15 #include <power/pmic.h>
16 #include <power/regulator.h>
18 #define HW_STATE_CONTROL 0
22 * struct pca9450_vrange - describe linear range of voltages
24 * @min_volt: smallest voltage in range
25 * @step: how much voltage changes at each selector step
26 * @min_sel: smallest selector in the range
27 * @max_sel: maximum selector in the range
29 struct pca9450_vrange
{
30 unsigned int min_volt
;
37 * struct pca9450_plat - describe regulator control registers
39 * @name: name of the regulator. Used for matching the dt-entry
40 * @enable_reg: register address used to enable/disable regulator
41 * @enablemask: register mask used to enable/disable regulator
42 * @volt_reg: register address used to configure regulator voltage
43 * @volt_mask: register mask used to configure regulator voltage
44 * @ranges: pointer to ranges of regulator voltages and matching register
46 * @numranges: number of voltage ranges pointed by ranges
54 struct pca9450_vrange
*ranges
;
55 unsigned int numranges
;
58 #define PCA_RANGE(_min, _vstep, _sel_low, _sel_hi) \
60 .min_volt = (_min), .step = (_vstep), \
61 .min_sel = (_sel_low), .max_sel = (_sel_hi), \
64 #define PCA_DATA(_name, enreg, enmask, vreg, vmask, _range) \
66 .name = (_name), .enable_reg = (enreg), .enablemask = (enmask), \
67 .volt_reg = (vreg), .volt_mask = (vmask), .ranges = (_range), \
68 .numranges = ARRAY_SIZE(_range) \
71 static struct pca9450_vrange pca9450_buck123_vranges
[] = {
72 PCA_RANGE(600000, 12500, 0, 0x7f),
75 static struct pca9450_vrange pca9450_buck456_vranges
[] = {
76 PCA_RANGE(600000, 25000, 0, 0x70),
77 PCA_RANGE(3400000, 0, 0x71, 0x7f),
80 static struct pca9450_vrange pca9450_ldo1_vranges
[] = {
81 PCA_RANGE(1600000, 100000, 0x0, 0x3),
82 PCA_RANGE(3000000, 100000, 0x4, 0x7),
85 static struct pca9450_vrange pca9450_ldo2_vranges
[] = {
86 PCA_RANGE(800000, 50000, 0x0, 0x7),
89 static struct pca9450_vrange pca9450_ldo34_vranges
[] = {
90 PCA_RANGE(800000, 100000, 0x0, 0x19),
91 PCA_RANGE(3300000, 0, 0x1a, 0x1f),
94 static struct pca9450_vrange pca9450_ldo5_vranges
[] = {
95 PCA_RANGE(1800000, 100000, 0x0, 0xf),
99 * We use enable mask 'HW_STATE_CONTROL' to indicate that this regulator
100 * must not be enabled or disabled by SW. The typical use-case for PCA9450
101 * is powering NXP i.MX8. In this use-case we (for now) only allow control
102 * for BUCK4, BUCK5, BUCK6 which are not boot critical.
104 static struct pca9450_plat pca9450_reg_data
[] = {
105 /* Bucks 1-3 which support dynamic voltage scaling */
106 PCA_DATA("BUCK1", PCA9450_BUCK1CTRL
, HW_STATE_CONTROL
,
107 PCA9450_BUCK1OUT_DVS0
, PCA9450_DVS_BUCK_RUN_MASK
,
108 pca9450_buck123_vranges
),
109 PCA_DATA("BUCK2", PCA9450_BUCK2CTRL
, HW_STATE_CONTROL
,
110 PCA9450_BUCK2OUT_DVS0
, PCA9450_DVS_BUCK_RUN_MASK
,
111 pca9450_buck123_vranges
),
112 PCA_DATA("BUCK3", PCA9450_BUCK3CTRL
, HW_STATE_CONTROL
,
113 PCA9450_BUCK3OUT_DVS0
, PCA9450_DVS_BUCK_RUN_MASK
,
114 pca9450_buck123_vranges
),
115 /* Bucks 4-6 which do not support dynamic voltage scaling */
116 PCA_DATA("BUCK4", PCA9450_BUCK4CTRL
, HW_STATE_CONTROL
,
117 PCA9450_BUCK4OUT
, PCA9450_DVS_BUCK_RUN_MASK
,
118 pca9450_buck456_vranges
),
119 PCA_DATA("BUCK5", PCA9450_BUCK5CTRL
, HW_STATE_CONTROL
,
120 PCA9450_BUCK5OUT
, PCA9450_DVS_BUCK_RUN_MASK
,
121 pca9450_buck456_vranges
),
122 PCA_DATA("BUCK6", PCA9450_BUCK6CTRL
, HW_STATE_CONTROL
,
123 PCA9450_BUCK6OUT
, PCA9450_DVS_BUCK_RUN_MASK
,
124 pca9450_buck456_vranges
),
126 PCA_DATA("LDO1", PCA9450_LDO1CTRL
, HW_STATE_CONTROL
,
127 PCA9450_LDO1CTRL
, PCA9450_LDO12_MASK
,
128 pca9450_ldo1_vranges
),
129 PCA_DATA("LDO2", PCA9450_LDO2CTRL
, HW_STATE_CONTROL
,
130 PCA9450_LDO2CTRL
, PCA9450_LDO12_MASK
,
131 pca9450_ldo2_vranges
),
132 PCA_DATA("LDO3", PCA9450_LDO3CTRL
, HW_STATE_CONTROL
,
133 PCA9450_LDO3CTRL
, PCA9450_LDO34_MASK
,
134 pca9450_ldo34_vranges
),
135 PCA_DATA("LDO4", PCA9450_LDO4CTRL
, HW_STATE_CONTROL
,
136 PCA9450_LDO4CTRL
, PCA9450_LDO34_MASK
,
137 pca9450_ldo34_vranges
),
138 PCA_DATA("LDO5", PCA9450_LDO5CTRL_H
, HW_STATE_CONTROL
,
139 PCA9450_LDO5CTRL_H
, PCA9450_LDO5_MASK
,
140 pca9450_ldo5_vranges
),
143 static int vrange_find_value(struct pca9450_vrange
*r
, unsigned int sel
,
146 if (!val
|| sel
< r
->min_sel
|| sel
> r
->max_sel
)
149 *val
= r
->min_volt
+ r
->step
* (sel
- r
->min_sel
);
153 static int vrange_find_selector(struct pca9450_vrange
*r
, int val
,
157 int num_vals
= r
->max_sel
- r
->min_sel
+ 1;
159 if (val
>= r
->min_volt
&&
160 val
<= r
->min_volt
+ r
->step
* (num_vals
- 1)) {
162 *sel
= r
->min_sel
+ ((val
- r
->min_volt
) / r
->step
);
172 static int pca9450_get_enable(struct udevice
*dev
)
174 struct pca9450_plat
*plat
= dev_get_plat(dev
);
178 * boot critical regulators on pca9450 must not be controlled by sw
179 * due to the 'feature' which leaves power rails down if pca9450 is
180 * reseted to snvs state. hence we can't get the state here.
182 * if we are alive it means we probably are on run state and
183 * if the regulator can't be controlled we can assume it is
186 if (plat
->enablemask
== HW_STATE_CONTROL
)
189 val
= pmic_reg_read(dev
->parent
, plat
->enable_reg
);
193 return (val
& plat
->enablemask
);
196 static int pca9450_set_enable(struct udevice
*dev
, bool enable
)
199 struct pca9450_plat
*plat
= dev_get_plat(dev
);
202 * boot critical regulators on pca9450 must not be controlled by sw
203 * due to the 'feature' which leaves power rails down if pca9450 is
204 * reseted to snvs state. Hence we can't set the state here.
206 if (plat
->enablemask
== HW_STATE_CONTROL
)
207 return enable
? 0 : -EINVAL
;
210 val
= plat
->enablemask
;
212 return pmic_clrsetbits(dev
->parent
, plat
->enable_reg
, plat
->enablemask
,
216 static int pca9450_get_value(struct udevice
*dev
)
218 struct pca9450_plat
*plat
= dev_get_plat(dev
);
219 unsigned int reg
, tmp
;
222 ret
= pmic_reg_read(dev
->parent
, plat
->volt_reg
);
227 reg
&= plat
->volt_mask
;
229 for (i
= 0; i
< plat
->numranges
; i
++) {
230 struct pca9450_vrange
*r
= &plat
->ranges
[i
];
232 if (!vrange_find_value(r
, reg
, &tmp
))
236 pr_err("Unknown voltage value read from pmic\n");
241 static int pca9450_set_value(struct udevice
*dev
, int uvolt
)
243 struct pca9450_plat
*plat
= dev_get_plat(dev
);
247 for (i
= 0; i
< plat
->numranges
; i
++) {
248 struct pca9450_vrange
*r
= &plat
->ranges
[i
];
250 found
= !vrange_find_selector(r
, uvolt
, &sel
);
255 * We require exactly the requested value to be
256 * supported - this can be changed later if needed
258 found
= !vrange_find_value(r
, sel
, &tmp
);
259 if (found
&& tmp
== uvolt
)
268 return pmic_clrsetbits(dev
->parent
, plat
->volt_reg
,
269 plat
->volt_mask
, sel
);
272 static int pca9450_regulator_probe(struct udevice
*dev
)
274 struct pca9450_plat
*plat
= dev_get_plat(dev
);
277 type
= dev_get_driver_data(dev_get_parent(dev
));
279 if (type
!= NXP_CHIP_TYPE_PCA9450A
&& type
!= NXP_CHIP_TYPE_PCA9450BC
) {
280 debug("Unknown PMIC type\n");
284 for (i
= 0; i
< ARRAY_SIZE(pca9450_reg_data
); i
++) {
285 if (strcmp(dev
->name
, pca9450_reg_data
[i
].name
))
288 /* PCA9450B/PCA9450C uses BUCK1 and BUCK3 in dual-phase */
289 if (type
== NXP_CHIP_TYPE_PCA9450BC
&&
290 !strcmp(pca9450_reg_data
[i
].name
, "BUCK3")) {
294 *plat
= pca9450_reg_data
[i
];
299 pr_err("Unknown regulator '%s'\n", dev
->name
);
304 static const struct dm_regulator_ops pca9450_regulator_ops
= {
305 .get_value
= pca9450_get_value
,
306 .set_value
= pca9450_set_value
,
307 .get_enable
= pca9450_get_enable
,
308 .set_enable
= pca9450_set_enable
,
311 U_BOOT_DRIVER(pca9450_regulator
) = {
312 .name
= PCA9450_REGULATOR_DRIVER
,
313 .id
= UCLASS_REGULATOR
,
314 .ops
= &pca9450_regulator_ops
,
315 .probe
= pca9450_regulator_probe
,
316 .plat_auto
= sizeof(struct pca9450_plat
),