xref: /linux/drivers/regulator/lm363x-regulator.c (revision 8ccd54fe45713cd458015b5b08d6098545e70543)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * TI LM363X Regulator Driver
4  *
5  * Copyright 2015 Texas Instruments
6  *
7  * Author: Milo Kim <milo.kim@ti.com>
8  */
9 
10 #include <linux/err.h>
11 #include <linux/kernel.h>
12 #include <linux/mfd/ti-lmu.h>
13 #include <linux/mfd/ti-lmu-register.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/platform_device.h>
18 #include <linux/regulator/driver.h>
19 #include <linux/regulator/of_regulator.h>
20 #include <linux/slab.h>
21 
22 /* LM3631 */
23 #define LM3631_BOOST_VSEL_MAX		0x25
24 #define LM3631_LDO_VSEL_MAX		0x28
25 #define LM3631_CONT_VSEL_MAX		0x03
26 #define LM3631_VBOOST_MIN		4500000
27 #define LM3631_VCONT_MIN		1800000
28 #define LM3631_VLDO_MIN			4000000
29 #define ENABLE_TIME_USEC		1000
30 
31 /* LM3632 */
32 #define LM3632_BOOST_VSEL_MAX		0x26
33 #define LM3632_LDO_VSEL_MAX		0x28
34 #define LM3632_VBOOST_MIN		4500000
35 #define LM3632_VLDO_MIN			4000000
36 
37 /* LM36274 */
38 #define LM36274_BOOST_VSEL_MAX		0x3f
39 #define LM36274_LDO_VSEL_MAX		0x32
40 #define LM36274_VOLTAGE_MIN		4000000
41 
42 /* Common */
43 #define LM363X_STEP_50mV		50000
44 #define LM363X_STEP_500mV		500000
45 
46 static const int ldo_cont_enable_time[] = {
47 	0, 2000, 5000, 10000, 20000, 50000, 100000, 200000,
48 };
49 
50 static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
51 {
52 	enum lm363x_regulator_id id = rdev_get_id(rdev);
53 	unsigned int val, addr, mask;
54 
55 	switch (id) {
56 	case LM3631_LDO_CONT:
57 		addr = LM3631_REG_ENTIME_VCONT;
58 		mask = LM3631_ENTIME_CONT_MASK;
59 		break;
60 	case LM3631_LDO_OREF:
61 		addr = LM3631_REG_ENTIME_VOREF;
62 		mask = LM3631_ENTIME_MASK;
63 		break;
64 	case LM3631_LDO_POS:
65 		addr = LM3631_REG_ENTIME_VPOS;
66 		mask = LM3631_ENTIME_MASK;
67 		break;
68 	case LM3631_LDO_NEG:
69 		addr = LM3631_REG_ENTIME_VNEG;
70 		mask = LM3631_ENTIME_MASK;
71 		break;
72 	default:
73 		return 0;
74 	}
75 
76 	if (regmap_read(rdev->regmap, addr, &val))
77 		return -EINVAL;
78 
79 	val = (val & mask) >> LM3631_ENTIME_SHIFT;
80 
81 	if (id == LM3631_LDO_CONT)
82 		return ldo_cont_enable_time[val];
83 	else
84 		return ENABLE_TIME_USEC * val;
85 }
86 
87 static const struct regulator_ops lm363x_boost_voltage_table_ops = {
88 	.list_voltage     = regulator_list_voltage_linear,
89 	.set_voltage_sel  = regulator_set_voltage_sel_regmap,
90 	.get_voltage_sel  = regulator_get_voltage_sel_regmap,
91 };
92 
93 static const struct regulator_ops lm363x_regulator_voltage_table_ops = {
94 	.list_voltage     = regulator_list_voltage_linear,
95 	.set_voltage_sel  = regulator_set_voltage_sel_regmap,
96 	.get_voltage_sel  = regulator_get_voltage_sel_regmap,
97 	.enable           = regulator_enable_regmap,
98 	.disable          = regulator_disable_regmap,
99 	.is_enabled       = regulator_is_enabled_regmap,
100 	.enable_time      = lm363x_regulator_enable_time,
101 };
102 
103 static const struct regulator_desc lm363x_regulator_desc[] = {
104 	/* LM3631 */
105 	{
106 		.name           = "vboost",
107 		.of_match	= "vboost",
108 		.id             = LM3631_BOOST,
109 		.ops            = &lm363x_boost_voltage_table_ops,
110 		.n_voltages     = LM3631_BOOST_VSEL_MAX + 1,
111 		.min_uV         = LM3631_VBOOST_MIN,
112 		.uV_step        = LM363X_STEP_50mV,
113 		.type           = REGULATOR_VOLTAGE,
114 		.owner          = THIS_MODULE,
115 		.vsel_reg       = LM3631_REG_VOUT_BOOST,
116 		.vsel_mask      = LM3631_VOUT_MASK,
117 	},
118 	{
119 		.name           = "ldo_cont",
120 		.of_match	= "vcont",
121 		.id             = LM3631_LDO_CONT,
122 		.ops            = &lm363x_regulator_voltage_table_ops,
123 		.n_voltages     = LM3631_CONT_VSEL_MAX + 1,
124 		.min_uV         = LM3631_VCONT_MIN,
125 		.uV_step        = LM363X_STEP_500mV,
126 		.type           = REGULATOR_VOLTAGE,
127 		.owner          = THIS_MODULE,
128 		.vsel_reg       = LM3631_REG_VOUT_CONT,
129 		.vsel_mask      = LM3631_VOUT_CONT_MASK,
130 		.enable_reg     = LM3631_REG_LDO_CTRL2,
131 		.enable_mask    = LM3631_EN_CONT_MASK,
132 	},
133 	{
134 		.name           = "ldo_oref",
135 		.of_match	= "voref",
136 		.id             = LM3631_LDO_OREF,
137 		.ops            = &lm363x_regulator_voltage_table_ops,
138 		.n_voltages     = LM3631_LDO_VSEL_MAX + 1,
139 		.min_uV         = LM3631_VLDO_MIN,
140 		.uV_step        = LM363X_STEP_50mV,
141 		.type           = REGULATOR_VOLTAGE,
142 		.owner          = THIS_MODULE,
143 		.vsel_reg       = LM3631_REG_VOUT_OREF,
144 		.vsel_mask      = LM3631_VOUT_MASK,
145 		.enable_reg     = LM3631_REG_LDO_CTRL1,
146 		.enable_mask    = LM3631_EN_OREF_MASK,
147 	},
148 	{
149 		.name           = "ldo_vpos",
150 		.of_match	= "vpos",
151 		.id             = LM3631_LDO_POS,
152 		.ops            = &lm363x_regulator_voltage_table_ops,
153 		.n_voltages     = LM3631_LDO_VSEL_MAX + 1,
154 		.min_uV         = LM3631_VLDO_MIN,
155 		.uV_step        = LM363X_STEP_50mV,
156 		.type           = REGULATOR_VOLTAGE,
157 		.owner          = THIS_MODULE,
158 		.vsel_reg       = LM3631_REG_VOUT_POS,
159 		.vsel_mask      = LM3631_VOUT_MASK,
160 		.enable_reg     = LM3631_REG_LDO_CTRL1,
161 		.enable_mask    = LM3631_EN_VPOS_MASK,
162 	},
163 	{
164 		.name           = "ldo_vneg",
165 		.of_match	= "vneg",
166 		.id             = LM3631_LDO_NEG,
167 		.ops            = &lm363x_regulator_voltage_table_ops,
168 		.n_voltages     = LM3631_LDO_VSEL_MAX + 1,
169 		.min_uV         = LM3631_VLDO_MIN,
170 		.uV_step        = LM363X_STEP_50mV,
171 		.type           = REGULATOR_VOLTAGE,
172 		.owner          = THIS_MODULE,
173 		.vsel_reg       = LM3631_REG_VOUT_NEG,
174 		.vsel_mask      = LM3631_VOUT_MASK,
175 		.enable_reg     = LM3631_REG_LDO_CTRL1,
176 		.enable_mask    = LM3631_EN_VNEG_MASK,
177 	},
178 	/* LM3632 */
179 	{
180 		.name           = "vboost",
181 		.of_match	= "vboost",
182 		.id             = LM3632_BOOST,
183 		.ops            = &lm363x_boost_voltage_table_ops,
184 		.n_voltages     = LM3632_BOOST_VSEL_MAX + 1,
185 		.min_uV         = LM3632_VBOOST_MIN,
186 		.uV_step        = LM363X_STEP_50mV,
187 		.type           = REGULATOR_VOLTAGE,
188 		.owner          = THIS_MODULE,
189 		.vsel_reg       = LM3632_REG_VOUT_BOOST,
190 		.vsel_mask      = LM3632_VOUT_MASK,
191 	},
192 	{
193 		.name           = "ldo_vpos",
194 		.of_match	= "vpos",
195 		.id             = LM3632_LDO_POS,
196 		.ops            = &lm363x_regulator_voltage_table_ops,
197 		.n_voltages     = LM3632_LDO_VSEL_MAX + 1,
198 		.min_uV         = LM3632_VLDO_MIN,
199 		.uV_step        = LM363X_STEP_50mV,
200 		.type           = REGULATOR_VOLTAGE,
201 		.owner          = THIS_MODULE,
202 		.vsel_reg       = LM3632_REG_VOUT_POS,
203 		.vsel_mask      = LM3632_VOUT_MASK,
204 		.enable_reg     = LM3632_REG_BIAS_CONFIG,
205 		.enable_mask    = LM3632_EN_VPOS_MASK,
206 	},
207 	{
208 		.name           = "ldo_vneg",
209 		.of_match	= "vneg",
210 		.id             = LM3632_LDO_NEG,
211 		.ops            = &lm363x_regulator_voltage_table_ops,
212 		.n_voltages     = LM3632_LDO_VSEL_MAX + 1,
213 		.min_uV         = LM3632_VLDO_MIN,
214 		.uV_step        = LM363X_STEP_50mV,
215 		.type           = REGULATOR_VOLTAGE,
216 		.owner          = THIS_MODULE,
217 		.vsel_reg       = LM3632_REG_VOUT_NEG,
218 		.vsel_mask      = LM3632_VOUT_MASK,
219 		.enable_reg     = LM3632_REG_BIAS_CONFIG,
220 		.enable_mask    = LM3632_EN_VNEG_MASK,
221 	},
222 
223 	/* LM36274 */
224 	{
225 		.name           = "vboost",
226 		.of_match	= "vboost",
227 		.id             = LM36274_BOOST,
228 		.ops            = &lm363x_boost_voltage_table_ops,
229 		.n_voltages     = LM36274_BOOST_VSEL_MAX + 1,
230 		.min_uV         = LM36274_VOLTAGE_MIN,
231 		.uV_step        = LM363X_STEP_50mV,
232 		.type           = REGULATOR_VOLTAGE,
233 		.owner          = THIS_MODULE,
234 		.vsel_reg       = LM36274_REG_VOUT_BOOST,
235 		.vsel_mask      = LM36274_VOUT_MASK,
236 	},
237 	{
238 		.name           = "ldo_vpos",
239 		.of_match	= "vpos",
240 		.id             = LM36274_LDO_POS,
241 		.ops            = &lm363x_regulator_voltage_table_ops,
242 		.n_voltages     = LM36274_LDO_VSEL_MAX + 1,
243 		.min_uV         = LM36274_VOLTAGE_MIN,
244 		.uV_step        = LM363X_STEP_50mV,
245 		.type           = REGULATOR_VOLTAGE,
246 		.owner          = THIS_MODULE,
247 		.vsel_reg       = LM36274_REG_VOUT_POS,
248 		.vsel_mask      = LM36274_VOUT_MASK,
249 		.enable_reg     = LM36274_REG_BIAS_CONFIG_1,
250 		.enable_mask    = LM36274_EN_VPOS_MASK,
251 	},
252 	{
253 		.name           = "ldo_vneg",
254 		.of_match	= "vneg",
255 		.id             = LM36274_LDO_NEG,
256 		.ops            = &lm363x_regulator_voltage_table_ops,
257 		.n_voltages     = LM36274_LDO_VSEL_MAX + 1,
258 		.min_uV         = LM36274_VOLTAGE_MIN,
259 		.uV_step        = LM363X_STEP_50mV,
260 		.type           = REGULATOR_VOLTAGE,
261 		.owner          = THIS_MODULE,
262 		.vsel_reg       = LM36274_REG_VOUT_NEG,
263 		.vsel_mask      = LM36274_VOUT_MASK,
264 		.enable_reg     = LM36274_REG_BIAS_CONFIG_1,
265 		.enable_mask    = LM36274_EN_VNEG_MASK,
266 	},
267 };
268 
269 static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev, int id)
270 {
271 	/*
272 	 * Check LCM_EN1/2_GPIO is configured.
273 	 * Those pins are used for enabling VPOS/VNEG LDOs.
274 	 * Do not use devm* here: the regulator core takes over the
275 	 * lifecycle management of the GPIO descriptor.
276 	 */
277 	switch (id) {
278 	case LM3632_LDO_POS:
279 	case LM36274_LDO_POS:
280 		return gpiod_get_index_optional(dev, "enable", 0,
281 				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
282 	case LM3632_LDO_NEG:
283 	case LM36274_LDO_NEG:
284 		return gpiod_get_index_optional(dev, "enable", 1,
285 				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
286 	default:
287 		return NULL;
288 	}
289 }
290 
291 static int lm363x_regulator_set_ext_en(struct regmap *regmap, int id)
292 {
293 	int ext_en_mask = 0;
294 
295 	switch (id) {
296 	case LM3632_LDO_POS:
297 	case LM3632_LDO_NEG:
298 		ext_en_mask = LM3632_EXT_EN_MASK;
299 		break;
300 	case LM36274_LDO_POS:
301 	case LM36274_LDO_NEG:
302 		ext_en_mask = LM36274_EXT_EN_MASK;
303 		break;
304 	default:
305 		return -ENODEV;
306 	}
307 
308 	return regmap_update_bits(regmap, lm363x_regulator_desc[id].enable_reg,
309 				 ext_en_mask, ext_en_mask);
310 }
311 
312 static int lm363x_regulator_probe(struct platform_device *pdev)
313 {
314 	struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
315 	struct regmap *regmap = lmu->regmap;
316 	struct regulator_config cfg = { };
317 	struct regulator_dev *rdev;
318 	struct device *dev = &pdev->dev;
319 	int id = pdev->id;
320 	struct gpio_desc *gpiod;
321 	int ret;
322 
323 	cfg.dev = dev;
324 	cfg.regmap = regmap;
325 
326 	/*
327 	 * LM3632 LDOs can be controlled by external pin.
328 	 * Register update is required if the pin is used.
329 	 */
330 	gpiod = lm363x_regulator_of_get_enable_gpio(dev, id);
331 	if (IS_ERR(gpiod))
332 		return PTR_ERR(gpiod);
333 
334 	if (gpiod) {
335 		cfg.ena_gpiod = gpiod;
336 		ret = lm363x_regulator_set_ext_en(regmap, id);
337 		if (ret) {
338 			gpiod_put(gpiod);
339 			dev_err(dev, "External pin err: %d\n", ret);
340 			return ret;
341 		}
342 	}
343 
344 	rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg);
345 	if (IS_ERR(rdev)) {
346 		ret = PTR_ERR(rdev);
347 		dev_err(dev, "[%d] regulator register err: %d\n", id, ret);
348 		return ret;
349 	}
350 
351 	return 0;
352 }
353 
354 static struct platform_driver lm363x_regulator_driver = {
355 	.probe = lm363x_regulator_probe,
356 	.driver = {
357 		.name = "lm363x-regulator",
358 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
359 	},
360 };
361 
362 module_platform_driver(lm363x_regulator_driver);
363 
364 MODULE_DESCRIPTION("TI LM363X Regulator Driver");
365 MODULE_AUTHOR("Milo Kim");
366 MODULE_LICENSE("GPL v2");
367 MODULE_ALIAS("platform:lm363x-regulator");
368