Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[platform/kernel/linux-starfive.git] / drivers / regulator / lm363x-regulator.c
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");