1 // SPDX-License-Identifier: GPL-2.0+
3 #include <linux/bits.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
7 #include <linux/platform_device.h>
8 #include <linux/regmap.h>
9 #include <linux/regulator/driver.h>
10 #include <linux/regulator/machine.h>
11 #include <linux/regulator/of_regulator.h>
13 #define RT5120_REG_PGSTAT 0x03
14 #define RT5120_REG_CH1VID 0x06
15 #define RT5120_REG_CH1SLPVID 0x07
16 #define RT5120_REG_ENABLE 0x08
17 #define RT5120_REG_MODECTL 0x09
18 #define RT5120_REG_UVOVPROT 0x0A
19 #define RT5120_REG_SLPCTL 0x0C
20 #define RT5120_REG_INTSTAT 0x1E
21 #define RT5120_REG_DISCHG 0x1F
23 #define RT5120_OUTPG_MASK(rid) BIT(rid + 1)
24 #define RT5120_OUTUV_MASK(rid) BIT(rid + 9)
25 #define RT5120_OUTOV_MASK(rid) BIT(rid + 16)
26 #define RT5120_CH1VID_MASK GENMASK(6, 0)
27 #define RT5120_RIDEN_MASK(rid) BIT(rid + 1)
28 #define RT5120_RADEN_MASK(rid) BIT(rid)
29 #define RT5120_FPWM_MASK(rid) BIT(rid + 1)
30 #define RT5120_UVHICCUP_MASK BIT(1)
31 #define RT5120_OVHICCUP_MASK BIT(0)
32 #define RT5120_HOTDIE_MASK BIT(1)
34 #define RT5120_BUCK1_MINUV 600000
35 #define RT5120_BUCK1_MAXUV 1393750
36 #define RT5120_BUCK1_STEPUV 6250
37 #define RT5120_BUCK1_NUM_VOLT 0x80
39 #define RT5120_AUTO_MODE 0
40 #define RT5120_FPWM_MODE 1
43 RT5120_REGULATOR_BUCK1
= 0,
44 RT5120_REGULATOR_BUCK2
,
45 RT5120_REGULATOR_BUCK3
,
46 RT5120_REGULATOR_BUCK4
,
48 RT5120_REGULATOR_EXTEN
,
54 struct regmap
*regmap
;
55 struct regulator_desc rdesc
[RT5120_MAX_REGULATOR
];
58 static int rt5120_buck_set_mode(struct regulator_dev
*rdev
, unsigned int mode
)
60 struct regmap
*regmap
= rdev_get_regmap(rdev
);
61 int rid
= rdev_get_id(rdev
);
62 unsigned int mask
= RT5120_FPWM_MASK(rid
), val
;
65 case REGULATOR_MODE_NORMAL
:
68 case REGULATOR_MODE_FAST
:
69 val
= RT5120_FPWM_MASK(rid
);
75 return regmap_update_bits(regmap
, RT5120_REG_MODECTL
, mask
, val
);
78 static unsigned int rt5120_buck_get_mode(struct regulator_dev
*rdev
)
80 struct regmap
*regmap
= rdev_get_regmap(rdev
);
81 int ret
, rid
= rdev_get_id(rdev
);
84 ret
= regmap_read(regmap
, RT5120_REG_MODECTL
, &val
);
86 return REGULATOR_MODE_INVALID
;
88 if (val
& RT5120_FPWM_MASK(rid
))
89 return REGULATOR_MODE_FAST
;
91 return REGULATOR_MODE_NORMAL
;
94 static int rt5120_regulator_get_error_flags(struct regulator_dev
*rdev
,
97 struct regmap
*regmap
= rdev_get_regmap(rdev
);
98 unsigned int stat
, hd_stat
, cur_flags
= 0;
99 int rid
= rdev_get_id(rdev
), ret
;
102 * reg 0x03/0x04/0x05 to indicate PG/UV/OV
103 * use block read to descrease I/O xfer time
105 ret
= regmap_raw_read(regmap
, RT5120_REG_PGSTAT
, &stat
, 3);
109 ret
= regmap_read(regmap
, RT5120_REG_INTSTAT
, &hd_stat
);
113 if (!(stat
& RT5120_OUTPG_MASK(rid
))) {
114 if (stat
& RT5120_OUTUV_MASK(rid
))
115 cur_flags
|= REGULATOR_ERROR_UNDER_VOLTAGE
;
117 if (stat
& RT5120_OUTOV_MASK(rid
))
118 cur_flags
|= REGULATOR_ERROR_REGULATION_OUT
;
121 if (hd_stat
& RT5120_HOTDIE_MASK
)
122 cur_flags
|= REGULATOR_ERROR_OVER_TEMP
;
128 static int rt5120_buck1_set_suspend_voltage(struct regulator_dev
*rdev
, int uV
)
130 struct regmap
*regmap
= rdev_get_regmap(rdev
);
133 if (uV
< RT5120_BUCK1_MINUV
|| uV
> RT5120_BUCK1_MAXUV
)
136 sel
= (uV
- RT5120_BUCK1_MINUV
) / RT5120_BUCK1_STEPUV
;
137 return regmap_write(regmap
, RT5120_REG_CH1SLPVID
, sel
);
140 static int rt5120_regulator_set_suspend_enable(struct regulator_dev
*rdev
)
142 struct regmap
*regmap
= rdev_get_regmap(rdev
);
143 int rid
= rdev_get_id(rdev
);
144 unsigned int mask
= RT5120_RIDEN_MASK(rid
);
146 return regmap_update_bits(regmap
, RT5120_REG_SLPCTL
, mask
, mask
);
149 static int rt5120_regulator_set_suspend_disable(struct regulator_dev
*rdev
)
151 struct regmap
*regmap
= rdev_get_regmap(rdev
);
152 int rid
= rdev_get_id(rdev
);
153 unsigned int mask
= RT5120_RIDEN_MASK(rid
);
155 return regmap_update_bits(regmap
, RT5120_REG_SLPCTL
, mask
, 0);
158 static const struct regulator_ops rt5120_buck1_ops
= {
159 .enable
= regulator_enable_regmap
,
160 .disable
= regulator_disable_regmap
,
161 .is_enabled
= regulator_is_enabled_regmap
,
162 .list_voltage
= regulator_list_voltage_linear
,
163 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
164 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
165 .set_active_discharge
= regulator_set_active_discharge_regmap
,
166 .set_mode
= rt5120_buck_set_mode
,
167 .get_mode
= rt5120_buck_get_mode
,
168 .get_error_flags
= rt5120_regulator_get_error_flags
,
169 .set_suspend_voltage
= rt5120_buck1_set_suspend_voltage
,
170 .set_suspend_enable
= rt5120_regulator_set_suspend_enable
,
171 .set_suspend_disable
= rt5120_regulator_set_suspend_disable
,
174 static const struct regulator_ops rt5120_buck234_ops
= {
175 .enable
= regulator_enable_regmap
,
176 .disable
= regulator_disable_regmap
,
177 .is_enabled
= regulator_is_enabled_regmap
,
178 .set_active_discharge
= regulator_set_active_discharge_regmap
,
179 .set_mode
= rt5120_buck_set_mode
,
180 .get_mode
= rt5120_buck_get_mode
,
181 .get_error_flags
= rt5120_regulator_get_error_flags
,
182 .set_suspend_enable
= rt5120_regulator_set_suspend_enable
,
183 .set_suspend_disable
= rt5120_regulator_set_suspend_disable
,
186 static const struct regulator_ops rt5120_ldo_ops
= {
187 .enable
= regulator_enable_regmap
,
188 .disable
= regulator_disable_regmap
,
189 .is_enabled
= regulator_is_enabled_regmap
,
190 .set_active_discharge
= regulator_set_active_discharge_regmap
,
191 .get_error_flags
= rt5120_regulator_get_error_flags
,
192 .set_suspend_enable
= rt5120_regulator_set_suspend_enable
,
193 .set_suspend_disable
= rt5120_regulator_set_suspend_disable
,
196 static const struct regulator_ops rt5120_exten_ops
= {
197 .enable
= regulator_enable_regmap
,
198 .disable
= regulator_disable_regmap
,
199 .is_enabled
= regulator_is_enabled_regmap
,
200 .set_suspend_enable
= rt5120_regulator_set_suspend_enable
,
201 .set_suspend_disable
= rt5120_regulator_set_suspend_disable
,
204 static unsigned int rt5120_buck_of_map_mode(unsigned int mode
)
207 case RT5120_AUTO_MODE
:
208 return REGULATOR_MODE_NORMAL
;
209 case RT5120_FPWM_MODE
:
210 return REGULATOR_MODE_FAST
;
212 return REGULATOR_MODE_INVALID
;
216 static void rt5120_fillin_regulator_desc(struct regulator_desc
*desc
, int rid
)
218 static const char * const name
[] = {
219 "buck1", "buck2", "buck3", "buck4", "ldo", "exten" };
220 static const char * const sname
[] = {
221 "vin1", "vin2", "vin3", "vin4", "vinldo", NULL
};
223 /* Common regulator property */
224 desc
->name
= name
[rid
];
225 desc
->supply_name
= sname
[rid
];
226 desc
->owner
= THIS_MODULE
;
227 desc
->type
= REGULATOR_VOLTAGE
;
229 desc
->enable_reg
= RT5120_REG_ENABLE
;
230 desc
->enable_mask
= RT5120_RIDEN_MASK(rid
);
231 desc
->active_discharge_reg
= RT5120_REG_DISCHG
;
232 desc
->active_discharge_mask
= RT5120_RADEN_MASK(rid
);
233 desc
->active_discharge_on
= RT5120_RADEN_MASK(rid
);
234 /* Config n_voltages to 1 for all*/
235 desc
->n_voltages
= 1;
237 /* Only buck support mode change */
238 if (rid
>= RT5120_REGULATOR_BUCK1
&& rid
<= RT5120_REGULATOR_BUCK4
)
239 desc
->of_map_mode
= rt5120_buck_of_map_mode
;
241 /* RID specific property init */
243 case RT5120_REGULATOR_BUCK1
:
244 /* Only buck1 support voltage change by I2C */
245 desc
->n_voltages
= RT5120_BUCK1_NUM_VOLT
;
246 desc
->min_uV
= RT5120_BUCK1_MINUV
;
247 desc
->uV_step
= RT5120_BUCK1_STEPUV
;
248 desc
->vsel_reg
= RT5120_REG_CH1VID
;
249 desc
->vsel_mask
= RT5120_CH1VID_MASK
;
250 desc
->ops
= &rt5120_buck1_ops
;
252 case RT5120_REGULATOR_BUCK2
... RT5120_REGULATOR_BUCK4
:
253 desc
->ops
= &rt5120_buck234_ops
;
255 case RT5120_REGULATOR_LDO
:
256 desc
->ops
= &rt5120_ldo_ops
;
259 desc
->ops
= &rt5120_exten_ops
;
263 static int rt5120_of_parse_cb(struct rt5120_priv
*priv
, int rid
,
264 struct of_regulator_match
*match
)
266 struct regulator_desc
*desc
= priv
->rdesc
+ rid
;
267 struct regulator_init_data
*init_data
= match
->init_data
;
269 if (!init_data
|| rid
== RT5120_REGULATOR_BUCK1
)
272 if (init_data
->constraints
.min_uV
!= init_data
->constraints
.max_uV
) {
273 dev_err(priv
->dev
, "Variable voltage for fixed regulator\n");
277 desc
->fixed_uV
= init_data
->constraints
.min_uV
;
281 static struct of_regulator_match rt5120_regu_match
[RT5120_MAX_REGULATOR
] = {
282 [RT5120_REGULATOR_BUCK1
] = { .name
= "buck1", },
283 [RT5120_REGULATOR_BUCK2
] = { .name
= "buck2", },
284 [RT5120_REGULATOR_BUCK3
] = { .name
= "buck3", },
285 [RT5120_REGULATOR_BUCK4
] = { .name
= "buck4", },
286 [RT5120_REGULATOR_LDO
] = { .name
= "ldo", },
287 [RT5120_REGULATOR_EXTEN
] = { .name
= "exten", }
290 static int rt5120_parse_regulator_dt_data(struct rt5120_priv
*priv
)
292 struct device
*dev
= priv
->dev
->parent
;
293 struct device_node
*reg_node
;
296 for (i
= 0; i
< RT5120_MAX_REGULATOR
; i
++) {
297 rt5120_fillin_regulator_desc(priv
->rdesc
+ i
, i
);
299 rt5120_regu_match
[i
].desc
= priv
->rdesc
+ i
;
302 reg_node
= of_get_child_by_name(dev
->of_node
, "regulators");
304 dev_err(priv
->dev
, "Couldn't find 'regulators' node\n");
308 ret
= of_regulator_match(priv
->dev
, reg_node
, rt5120_regu_match
,
309 ARRAY_SIZE(rt5120_regu_match
));
311 of_node_put(reg_node
);
315 "Error parsing regulator init data (%d)\n", ret
);
319 for (i
= 0; i
< RT5120_MAX_REGULATOR
; i
++) {
320 ret
= rt5120_of_parse_cb(priv
, i
, rt5120_regu_match
+ i
);
322 dev_err(priv
->dev
, "Failed in [%d] of_passe_cb\n", i
);
330 static int rt5120_device_property_init(struct rt5120_priv
*priv
)
332 struct device
*dev
= priv
->dev
->parent
;
333 struct device_node
*np
= dev
->of_node
;
335 unsigned int prot_enable_val
= 0;
337 /* Assign UV/OV HW protection behavior */
338 prot_enable
= of_property_read_bool(np
,
339 "richtek,enable-undervolt-hiccup");
341 prot_enable_val
|= RT5120_UVHICCUP_MASK
;
343 prot_enable
= of_property_read_bool(np
,
344 "richtek,enable-overvolt-hiccup");
346 prot_enable_val
|= RT5120_OVHICCUP_MASK
;
348 return regmap_update_bits(priv
->regmap
, RT5120_REG_UVOVPROT
,
349 RT5120_UVHICCUP_MASK
| RT5120_OVHICCUP_MASK
,
353 static int rt5120_regulator_probe(struct platform_device
*pdev
)
355 struct rt5120_priv
*priv
;
356 struct regulator_dev
*rdev
;
357 struct regulator_config config
= {};
360 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
364 priv
->dev
= &pdev
->dev
;
366 priv
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
368 dev_err(&pdev
->dev
, "Failed to init regmap\n");
372 ret
= rt5120_device_property_init(priv
);
374 dev_err(&pdev
->dev
, "Failed to do property init\n");
378 ret
= rt5120_parse_regulator_dt_data(priv
);
380 dev_err(&pdev
->dev
, "Failed to parse dt data\n");
384 config
.dev
= &pdev
->dev
;
385 config
.regmap
= priv
->regmap
;
387 for (i
= 0; i
< RT5120_MAX_REGULATOR
; i
++) {
388 config
.of_node
= rt5120_regu_match
[i
].of_node
;
389 config
.init_data
= rt5120_regu_match
[i
].init_data
;
391 rdev
= devm_regulator_register(&pdev
->dev
, priv
->rdesc
+ i
,
395 "Failed to register regulator [%d]\n", i
);
396 return PTR_ERR(rdev
);
403 static const struct platform_device_id rt5120_regulator_dev_table
[] = {
404 { "rt5120-regulator", 0 },
407 MODULE_DEVICE_TABLE(platform
, rt5120_regulator_dev_table
);
409 static struct platform_driver rt5120_regulator_driver
= {
411 .name
= "rt5120-regulator",
412 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
414 .id_table
= rt5120_regulator_dev_table
,
415 .probe
= rt5120_regulator_probe
,
417 module_platform_driver(rt5120_regulator_driver
);
419 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
420 MODULE_DESCRIPTION("Richtek RT5120 regulator driver");
421 MODULE_LICENSE("GPL v2");