1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023 Richtek Technology Corp.
5 * Author: ChiYuan Huang <cy_huang@richtek.com>
9 #include <linux/kernel.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/module.h>
12 #include <linux/property.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/of_regulator.h>
17 #define RT4803_AUTO_MODE 1
18 #define RT4803_FPWM_MODE 2
20 #define RT4803_REG_CONFIG 0x01
21 #define RT4803_REG_VSELL 0x02
22 #define RT4803_REG_VSELH 0x03
23 #define RT4803_REG_ILIM 0x04
24 #define RT4803_REG_STAT 0x05
26 #define RT4803_MODE_MASK GENMASK(1, 0)
27 #define RT4803_VSEL_MASK GENMASK(4, 0)
28 #define RT4803_ILIM_MASK GENMASK(3, 0)
29 #define RT4803_TSD_MASK BIT(7)
30 #define RT4803_HOTDIE_MASK BIT(6)
31 #define RT4803_FAULT_MASK BIT(1)
32 #define RT4803_PGOOD_MASK BIT(0)
34 #define RT4803_VOUT_MINUV 2850000
35 #define RT4803_VOUT_STEPUV 50000
36 #define RT4803_VOUT_NUM 32
38 static int rt4803_set_mode(struct regulator_dev
*rdev
, unsigned int mode
)
40 struct regmap
*regmap
= rdev_get_regmap(rdev
);
44 case REGULATOR_MODE_NORMAL
:
45 modeval
= RT4803_AUTO_MODE
;
47 case REGULATOR_MODE_FAST
:
48 modeval
= RT4803_FPWM_MODE
;
54 modeval
<<= ffs(RT4803_MODE_MASK
) - 1;
56 return regmap_update_bits(regmap
, RT4803_REG_CONFIG
, RT4803_MODE_MASK
, modeval
);
59 static unsigned int rt4803_get_mode(struct regulator_dev
*rdev
)
61 struct regmap
*regmap
= rdev_get_regmap(rdev
);
65 ret
= regmap_read(regmap
, RT4803_REG_CONFIG
, &modeval
);
67 return REGULATOR_MODE_INVALID
;
69 modeval
>>= ffs(RT4803_MODE_MASK
) - 1;
72 case RT4803_AUTO_MODE
:
73 return REGULATOR_MODE_NORMAL
;
74 case RT4803_FPWM_MODE
:
75 return REGULATOR_MODE_FAST
;
77 return REGULATOR_MODE_INVALID
;
81 static int rt4803_get_error_flags(struct regulator_dev
*rdev
, unsigned int *flags
)
83 struct regmap
*regmap
= rdev_get_regmap(rdev
);
84 unsigned int state
, events
= 0;
87 ret
= regmap_read(regmap
, RT4803_REG_STAT
, &state
);
91 if (state
& RT4803_PGOOD_MASK
)
94 if (state
& RT4803_FAULT_MASK
)
95 events
|= REGULATOR_ERROR_FAIL
;
97 if (state
& RT4803_HOTDIE_MASK
)
98 events
|= REGULATOR_ERROR_OVER_TEMP_WARN
;
100 if (state
& RT4803_TSD_MASK
)
101 events
|= REGULATOR_ERROR_OVER_TEMP
;
108 static int rt4803_set_suspend_voltage(struct regulator_dev
*rdev
, int uV
)
110 struct regmap
*regmap
= rdev_get_regmap(rdev
);
111 unsigned int reg
, vsel
;
113 if (rdev
->desc
->vsel_reg
== RT4803_REG_VSELL
)
114 reg
= RT4803_REG_VSELH
;
116 reg
= RT4803_REG_VSELL
;
118 vsel
= (uV
- rdev
->desc
->min_uV
) / rdev
->desc
->uV_step
;
119 vsel
<<= ffs(RT4803_VSEL_MASK
) - 1;
121 return regmap_update_bits(regmap
, reg
, RT4803_VSEL_MASK
, vsel
);
124 static const struct regulator_ops rt4803_regulator_ops
= {
125 .list_voltage
= regulator_list_voltage_linear
,
126 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
127 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
128 .set_mode
= rt4803_set_mode
,
129 .get_mode
= rt4803_get_mode
,
130 .get_error_flags
= rt4803_get_error_flags
,
131 .set_suspend_voltage
= rt4803_set_suspend_voltage
,
134 static unsigned int rt4803_of_map_mode(unsigned int mode
)
137 case RT4803_AUTO_MODE
:
138 return REGULATOR_MODE_NORMAL
;
139 case RT4803_FPWM_MODE
:
140 return REGULATOR_MODE_FAST
;
142 return REGULATOR_MODE_INVALID
;
146 static const struct regmap_config rt4803_regmap_config
= {
149 .max_register
= RT4803_REG_STAT
,
152 static int rt4803_probe(struct i2c_client
*i2c
)
154 struct device
*dev
= &i2c
->dev
;
155 struct regmap
*regmap
;
156 struct regulator_desc
*desc
;
157 struct regulator_config cfg
= {};
158 struct regulator_dev
*rdev
;
162 desc
= devm_kzalloc(dev
, sizeof(*desc
), GFP_KERNEL
);
166 regmap
= devm_regmap_init_i2c(i2c
, &rt4803_regmap_config
);
168 return dev_err_probe(dev
, PTR_ERR(regmap
), "Failed to init regmap\n");
170 /* Always configure the input current limit to max 5A at initial */
171 ret
= regmap_update_bits(regmap
, RT4803_REG_ILIM
, RT4803_ILIM_MASK
, 0xff);
173 return dev_err_probe(dev
, ret
, "Failed to config ILIM to max\n");
175 vsel_act_high
= device_property_read_bool(dev
, "richtek,vsel-active-high");
177 desc
->name
= "rt4803-regulator";
178 desc
->type
= REGULATOR_VOLTAGE
;
179 desc
->owner
= THIS_MODULE
;
180 desc
->ops
= &rt4803_regulator_ops
;
181 desc
->min_uV
= RT4803_VOUT_MINUV
;
182 desc
->uV_step
= RT4803_VOUT_STEPUV
;
183 desc
->n_voltages
= RT4803_VOUT_NUM
;
184 desc
->vsel_mask
= RT4803_VSEL_MASK
;
185 desc
->of_map_mode
= rt4803_of_map_mode
;
187 desc
->vsel_reg
= RT4803_REG_VSELH
;
189 desc
->vsel_reg
= RT4803_REG_VSELL
;
192 cfg
.of_node
= dev_of_node(dev
);
193 cfg
.init_data
= of_get_regulator_init_data(dev
, dev_of_node(dev
), desc
);
195 rdev
= devm_regulator_register(dev
, desc
, &cfg
);
196 return PTR_ERR_OR_ZERO(rdev
);
199 static const struct of_device_id rt4803_device_match_table
[] = {
200 { .compatible
= "richtek,rt4803" },
203 MODULE_DEVICE_TABLE(of
, rt4803_device_match_table
);
205 static struct i2c_driver rt4803_driver
= {
208 .of_match_table
= rt4803_device_match_table
,
210 .probe
= rt4803_probe
,
212 module_i2c_driver(rt4803_driver
);
214 MODULE_DESCRIPTION("Richtek RT4803 voltage regulator driver");
215 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
216 MODULE_LICENSE("GPL");