xref: /openbmc/linux/drivers/regulator/rt5739.c (revision 234489ac)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Device driver for RT5739 regulator
4  *
5  * Copyright (C) 2023 Richtek Technology Corp.
6  *
7  * Author: ChiYuan Huang <cy_huang@richtek.com>
8  */
9 
10 #include <linux/bits.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/i2c.h>
13 #include <linux/kernel.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/property.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/regulator/of_regulator.h>
19 
20 #define RT5739_AUTO_MODE	0
21 #define RT5739_FPWM_MODE	1
22 
23 #define RT5739_REG_NSEL0	0x00
24 #define RT5739_REG_NSEL1	0x01
25 #define RT5739_REG_CNTL1	0x02
26 #define RT5739_REG_ID1		0x03
27 #define RT5739_REG_CNTL2	0x06
28 #define RT5739_REG_CNTL4	0x08
29 
30 #define RT5739_VSEL_MASK	GENMASK(7, 0)
31 #define RT5739_MODEVSEL1_MASK	BIT(1)
32 #define RT5739_MODEVSEL0_MASK	BIT(0)
33 #define RT5739_VID_MASK		GENMASK(7, 5)
34 #define RT5739_ACTD_MASK	BIT(7)
35 #define RT5739_ENVSEL1_MASK	BIT(1)
36 #define RT5739_ENVSEL0_MASK	BIT(0)
37 
38 #define RT5739_VOLT_MINUV	300000
39 #define RT5739_VOLT_MAXUV	1300000
40 #define RT5739_VOLT_STPUV	5000
41 #define RT5739_N_VOLTS		201
42 #define RT5739_I2CRDY_TIMEUS	1000
43 
44 static int rt5739_set_mode(struct regulator_dev *rdev, unsigned int mode)
45 {
46 	const struct regulator_desc *desc = rdev->desc;
47 	struct regmap *regmap = rdev_get_regmap(rdev);
48 	unsigned int mask, val;
49 
50 	if (desc->vsel_reg == RT5739_REG_NSEL0)
51 		mask = RT5739_MODEVSEL0_MASK;
52 	else
53 		mask = RT5739_MODEVSEL1_MASK;
54 
55 	switch (mode) {
56 	case REGULATOR_MODE_FAST:
57 		val = mask;
58 		break;
59 	case REGULATOR_MODE_NORMAL:
60 		val = 0;
61 		break;
62 	default:
63 		return -EINVAL;
64 	}
65 
66 	return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val);
67 }
68 
69 static unsigned int rt5739_get_mode(struct regulator_dev *rdev)
70 {
71 	const struct regulator_desc *desc = rdev->desc;
72 	struct regmap *regmap = rdev_get_regmap(rdev);
73 	unsigned int mask, val;
74 	int ret;
75 
76 	if (desc->vsel_reg == RT5739_REG_NSEL0)
77 		mask = RT5739_MODEVSEL0_MASK;
78 	else
79 		mask = RT5739_MODEVSEL1_MASK;
80 
81 	ret = regmap_read(regmap, RT5739_REG_CNTL1, &val);
82 	if (ret)
83 		return REGULATOR_MODE_INVALID;
84 
85 	if (val & mask)
86 		return REGULATOR_MODE_FAST;
87 
88 	return REGULATOR_MODE_NORMAL;
89 }
90 
91 static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV)
92 {
93 	const struct regulator_desc *desc = rdev->desc;
94 	struct regmap *regmap = rdev_get_regmap(rdev);
95 	unsigned int reg, vsel;
96 
97 	if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV)
98 		return -EINVAL;
99 
100 	if (desc->vsel_reg == RT5739_REG_NSEL0)
101 		reg = RT5739_REG_NSEL1;
102 	else
103 		reg = RT5739_REG_NSEL0;
104 
105 	vsel = (uV - RT5739_VOLT_MINUV) / RT5739_VOLT_STPUV;
106 	return regmap_write(regmap, reg, vsel);
107 }
108 
109 static int rt5739_set_suspend_enable(struct regulator_dev *rdev)
110 {
111 	const struct regulator_desc *desc = rdev->desc;
112 	struct regmap *regmap = rdev_get_regmap(rdev);
113 	unsigned int mask;
114 
115 	if (desc->vsel_reg == RT5739_REG_NSEL0)
116 		mask = RT5739_ENVSEL1_MASK;
117 	else
118 		mask = RT5739_ENVSEL0_MASK;
119 
120 	return regmap_update_bits(regmap, desc->enable_reg, mask, mask);
121 }
122 
123 static int rt5739_set_suspend_disable(struct regulator_dev *rdev)
124 {
125 	const struct regulator_desc *desc = rdev->desc;
126 	struct regmap *regmap = rdev_get_regmap(rdev);
127 	unsigned int mask;
128 
129 	if (desc->vsel_reg == RT5739_REG_NSEL0)
130 		mask = RT5739_ENVSEL1_MASK;
131 	else
132 		mask = RT5739_ENVSEL0_MASK;
133 
134 	return regmap_update_bits(regmap, desc->enable_reg, mask, 0);
135 }
136 
137 static int rt5739_set_suspend_mode(struct regulator_dev *rdev,
138 				   unsigned int mode)
139 {
140 	const struct regulator_desc *desc = rdev->desc;
141 	struct regmap *regmap = rdev_get_regmap(rdev);
142 	unsigned int mask, val;
143 
144 	if (desc->vsel_reg == RT5739_REG_NSEL0)
145 		mask = RT5739_MODEVSEL1_MASK;
146 	else
147 		mask = RT5739_MODEVSEL0_MASK;
148 
149 	switch (mode) {
150 	case REGULATOR_MODE_FAST:
151 		val = mask;
152 		break;
153 	case REGULATOR_MODE_NORMAL:
154 		val = 0;
155 		break;
156 	default:
157 		return -EINVAL;
158 	}
159 
160 	return regmap_update_bits(regmap, RT5739_REG_CNTL1, mask, val);
161 }
162 
163 static const struct regulator_ops rt5739_regulator_ops = {
164 	.list_voltage = regulator_list_voltage_linear,
165 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
166 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
167 	.enable	= regulator_enable_regmap,
168 	.disable = regulator_disable_regmap,
169 	.is_enabled = regulator_is_enabled_regmap,
170 	.set_active_discharge = regulator_set_active_discharge_regmap,
171 	.set_mode = rt5739_set_mode,
172 	.get_mode = rt5739_get_mode,
173 	.set_suspend_voltage = rt5739_set_suspend_voltage,
174 	.set_suspend_enable = rt5739_set_suspend_enable,
175 	.set_suspend_disable = rt5739_set_suspend_disable,
176 	.set_suspend_mode = rt5739_set_suspend_mode,
177 };
178 
179 static unsigned int rt5739_of_map_mode(unsigned int mode)
180 {
181 	switch (mode) {
182 	case RT5739_AUTO_MODE:
183 		return REGULATOR_MODE_NORMAL;
184 	case RT5739_FPWM_MODE:
185 		return REGULATOR_MODE_FAST;
186 	default:
187 		return REGULATOR_MODE_INVALID;
188 	}
189 }
190 
191 static void rt5739_init_regulator_desc(struct regulator_desc *desc,
192 				       bool vsel_active_high)
193 {
194 	/* Fixed */
195 	desc->name = "rt5739-regulator";
196 	desc->owner = THIS_MODULE;
197 	desc->ops = &rt5739_regulator_ops;
198 	desc->n_voltages = RT5739_N_VOLTS;
199 	desc->min_uV = RT5739_VOLT_MINUV;
200 	desc->uV_step = RT5739_VOLT_STPUV;
201 	desc->vsel_mask = RT5739_VSEL_MASK;
202 	desc->enable_reg = RT5739_REG_CNTL2;
203 	desc->active_discharge_reg = RT5739_REG_CNTL1;
204 	desc->active_discharge_mask = RT5739_ACTD_MASK;
205 	desc->active_discharge_on = RT5739_ACTD_MASK;
206 	desc->of_map_mode = rt5739_of_map_mode;
207 
208 	/* Assigned by vsel level */
209 	if (vsel_active_high) {
210 		desc->vsel_reg = RT5739_REG_NSEL1;
211 		desc->enable_mask = RT5739_ENVSEL1_MASK;
212 	} else {
213 		desc->vsel_reg = RT5739_REG_NSEL0;
214 		desc->enable_mask = RT5739_ENVSEL0_MASK;
215 	}
216 }
217 
218 static const struct regmap_config rt5739_regmap_config = {
219 	.name = "rt5739",
220 	.reg_bits = 8,
221 	.val_bits = 8,
222 	.max_register = RT5739_REG_CNTL4,
223 };
224 
225 static int rt5739_probe(struct i2c_client *i2c)
226 {
227 	struct device *dev = &i2c->dev;
228 	struct regulator_desc *desc;
229 	struct regmap *regmap;
230 	struct gpio_desc *enable_gpio;
231 	struct regulator_config cfg = {};
232 	struct regulator_dev *rdev;
233 	bool vsel_acth;
234 	unsigned int vid;
235 	int ret;
236 
237 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
238 	if (!desc)
239 		return -ENOMEM;
240 
241 	enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
242 	if (IS_ERR(enable_gpio))
243 		return dev_err_probe(dev, PTR_ERR(enable_gpio), "Failed to get 'enable' gpio\n");
244 	else if (enable_gpio)
245 		usleep_range(RT5739_I2CRDY_TIMEUS, RT5739_I2CRDY_TIMEUS + 1000);
246 
247 	regmap = devm_regmap_init_i2c(i2c, &rt5739_regmap_config);
248 	if (IS_ERR(regmap))
249 		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n");
250 
251 	ret = regmap_read(regmap, RT5739_REG_ID1, &vid);
252 	if (ret)
253 		return dev_err_probe(dev, ret, "Failed to read VID\n");
254 
255 	/* RT5739: (VID & MASK) must be 0 */
256 	if (vid & RT5739_VID_MASK)
257 		return dev_err_probe(dev, -ENODEV, "Incorrect VID (0x%02x)\n", vid);
258 
259 	vsel_acth = device_property_read_bool(dev, "richtek,vsel-active-high");
260 
261 	rt5739_init_regulator_desc(desc, vsel_acth);
262 
263 	cfg.dev = dev;
264 	cfg.of_node = dev_of_node(dev);
265 	cfg.init_data = of_get_regulator_init_data(dev, dev_of_node(dev), desc);
266 	rdev = devm_regulator_register(dev, desc, &cfg);
267 	if (IS_ERR(rdev))
268 		return dev_err_probe(dev, PTR_ERR(rdev), "Failed to register regulator\n");
269 
270 	return 0;
271 }
272 
273 static const struct of_device_id rt5739_device_table[] = {
274 	{ .compatible = "richtek,rt5739" },
275 	{ /* sentinel */ }
276 };
277 MODULE_DEVICE_TABLE(of, rt5739_device_table);
278 
279 static struct i2c_driver rt5739_driver = {
280 	.driver = {
281 		.name = "rt5739",
282 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
283 		.of_match_table = rt5739_device_table,
284 	},
285 	.probe_new = rt5739_probe,
286 };
287 module_i2c_driver(rt5739_driver);
288 
289 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
290 MODULE_DESCRIPTION("Richtek RT5739 regulator driver");
291 MODULE_LICENSE("GPL");
292