xref: /linux/drivers/regulator/rt4803.c (revision 26ba30221c03364d6ed9910be8da4c1fd871b07b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 Richtek Technology Corp.
4  *
5  * Author: ChiYuan Huang <cy_huang@richtek.com>
6  */
7 
8 #include <linux/i2c.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/property.h>
12 #include <linux/regmap.h>
13 #include <linux/regulator/driver.h>
14 #include <linux/regulator/of_regulator.h>
15 
16 #define RT4803_AUTO_MODE	1
17 #define RT4803_FPWM_MODE	2
18 
19 #define RT4803_REG_CONFIG	0x01
20 #define RT4803_REG_VSELL	0x02
21 #define RT4803_REG_VSELH	0x03
22 #define RT4803_REG_ILIM		0x04
23 #define RT4803_REG_STAT		0x05
24 
25 #define RT4803_MODE_MASK	GENMASK(1, 0)
26 #define RT4803_VSEL_MASK	GENMASK(4, 0)
27 #define RT4803_ILIM_MASK	GENMASK(3, 0)
28 #define RT4803_TSD_MASK		BIT(7)
29 #define RT4803_HOTDIE_MASK	BIT(6)
30 #define RT4803_FAULT_MASK	BIT(1)
31 #define RT4803_PGOOD_MASK	BIT(0)
32 
33 #define RT4803_VOUT_MINUV	2850000
34 #define RT4803_VOUT_STEPUV	50000
35 #define RT4803_VOUT_NUM		32
36 
37 static int rt4803_set_mode(struct regulator_dev *rdev, unsigned int mode)
38 {
39 	struct regmap *regmap = rdev_get_regmap(rdev);
40 	unsigned int modeval;
41 
42 	switch (mode) {
43 	case REGULATOR_MODE_NORMAL:
44 		modeval = RT4803_AUTO_MODE;
45 		break;
46 	case REGULATOR_MODE_FAST:
47 		modeval = RT4803_FPWM_MODE;
48 		break;
49 	default:
50 		return -EINVAL;
51 	}
52 
53 	modeval <<= ffs(RT4803_MODE_MASK) - 1;
54 
55 	return regmap_update_bits(regmap, RT4803_REG_CONFIG, RT4803_MODE_MASK, modeval);
56 }
57 
58 static unsigned int rt4803_get_mode(struct regulator_dev *rdev)
59 {
60 	struct regmap *regmap = rdev_get_regmap(rdev);
61 	unsigned int modeval;
62 	int ret;
63 
64 	ret = regmap_read(regmap, RT4803_REG_CONFIG, &modeval);
65 	if (ret)
66 		return REGULATOR_MODE_INVALID;
67 
68 	modeval >>= ffs(RT4803_MODE_MASK) - 1;
69 
70 	switch (modeval) {
71 	case RT4803_AUTO_MODE:
72 		return REGULATOR_MODE_NORMAL;
73 	case RT4803_FPWM_MODE:
74 		return REGULATOR_MODE_FAST;
75 	default:
76 		return REGULATOR_MODE_INVALID;
77 	}
78 }
79 
80 static int rt4803_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
81 {
82 	struct regmap *regmap = rdev_get_regmap(rdev);
83 	unsigned int state, events = 0;
84 	int ret;
85 
86 	ret = regmap_read(regmap, RT4803_REG_STAT, &state);
87 	if (ret)
88 		return ret;
89 
90 	if (state & RT4803_PGOOD_MASK)
91 		goto out_error_flag;
92 
93 	if (state & RT4803_FAULT_MASK)
94 		events |= REGULATOR_ERROR_FAIL;
95 
96 	if (state & RT4803_HOTDIE_MASK)
97 		events |= REGULATOR_ERROR_OVER_TEMP_WARN;
98 
99 	if (state & RT4803_TSD_MASK)
100 		events |= REGULATOR_ERROR_OVER_TEMP;
101 
102 out_error_flag:
103 	*flags = events;
104 	return 0;
105 }
106 
107 static int rt4803_set_suspend_voltage(struct regulator_dev *rdev, int uV)
108 {
109 	struct regmap *regmap = rdev_get_regmap(rdev);
110 	unsigned int reg, vsel;
111 
112 	if (rdev->desc->vsel_reg == RT4803_REG_VSELL)
113 		reg = RT4803_REG_VSELH;
114 	else
115 		reg = RT4803_REG_VSELL;
116 
117 	vsel = (uV - rdev->desc->min_uV) / rdev->desc->uV_step;
118 	vsel <<= ffs(RT4803_VSEL_MASK) - 1;
119 
120 	return regmap_update_bits(regmap, reg, RT4803_VSEL_MASK, vsel);
121 }
122 
123 static const struct regulator_ops rt4803_regulator_ops = {
124 	.list_voltage = regulator_list_voltage_linear,
125 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
126 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
127 	.set_mode = rt4803_set_mode,
128 	.get_mode = rt4803_get_mode,
129 	.get_error_flags = rt4803_get_error_flags,
130 	.set_suspend_voltage = rt4803_set_suspend_voltage,
131 };
132 
133 static unsigned int rt4803_of_map_mode(unsigned int mode)
134 {
135 	switch (mode) {
136 	case RT4803_AUTO_MODE:
137 		return REGULATOR_MODE_NORMAL;
138 	case RT4803_FPWM_MODE:
139 		return REGULATOR_MODE_FAST;
140 	default:
141 		return REGULATOR_MODE_INVALID;
142 	}
143 }
144 
145 static const struct regmap_config rt4803_regmap_config = {
146 	.reg_bits = 8,
147 	.val_bits = 8,
148 	.max_register = RT4803_REG_STAT,
149 };
150 
151 static int rt4803_probe(struct i2c_client *i2c)
152 {
153 	struct device *dev = &i2c->dev;
154 	struct regmap *regmap;
155 	struct regulator_desc *desc;
156 	struct regulator_config cfg = {};
157 	struct regulator_dev *rdev;
158 	bool vsel_act_high;
159 	int ret;
160 
161 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
162 	if (!desc)
163 		return -ENOMEM;
164 
165 	regmap = devm_regmap_init_i2c(i2c, &rt4803_regmap_config);
166 	if (IS_ERR(regmap))
167 		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
168 
169 	/* Always configure the input current limit to max 5A at initial */
170 	ret = regmap_update_bits(regmap, RT4803_REG_ILIM, RT4803_ILIM_MASK, 0xff);
171 	if (ret)
172 		return dev_err_probe(dev, ret, "Failed to config ILIM to max\n");
173 
174 	vsel_act_high = device_property_read_bool(dev, "richtek,vsel-active-high");
175 
176 	desc->name = "rt4803-regulator";
177 	desc->type = REGULATOR_VOLTAGE;
178 	desc->owner = THIS_MODULE;
179 	desc->ops = &rt4803_regulator_ops;
180 	desc->min_uV = RT4803_VOUT_MINUV;
181 	desc->uV_step = RT4803_VOUT_STEPUV;
182 	desc->n_voltages = RT4803_VOUT_NUM;
183 	desc->vsel_mask = RT4803_VSEL_MASK;
184 	desc->of_map_mode = rt4803_of_map_mode;
185 	if (vsel_act_high)
186 		desc->vsel_reg = RT4803_REG_VSELH;
187 	else
188 		desc->vsel_reg = RT4803_REG_VSELL;
189 
190 	cfg.dev = dev;
191 	cfg.of_node = dev_of_node(dev);
192 	cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc);
193 
194 	rdev = devm_regulator_register(dev, desc, &cfg);
195 	return PTR_ERR_OR_ZERO(rdev);
196 }
197 
198 static const struct of_device_id rt4803_device_match_table[] = {
199 	{ .compatible = "richtek,rt4803" },
200 	{}
201 };
202 MODULE_DEVICE_TABLE(of, rt4803_device_match_table);
203 
204 static struct i2c_driver rt4803_driver = {
205 	.driver = {
206 		.name = "rt4803",
207 		.of_match_table = rt4803_device_match_table,
208 	},
209 	.probe = rt4803_probe,
210 };
211 module_i2c_driver(rt4803_driver);
212 
213 MODULE_DESCRIPTION("Richtek RT4803 voltage regulator driver");
214 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
215 MODULE_LICENSE("GPL");
216