Merge branch 'next' into for-linus
[linux-2.6-block.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             0x29
34 #define LM3632_VBOOST_MIN               4500000
35 #define LM3632_VLDO_MIN                 4000000
36
37 /* Common */
38 #define LM363X_STEP_50mV                50000
39 #define LM363X_STEP_500mV               500000
40
41 static const int ldo_cont_enable_time[] = {
42         0, 2000, 5000, 10000, 20000, 50000, 100000, 200000,
43 };
44
45 static int lm363x_regulator_enable_time(struct regulator_dev *rdev)
46 {
47         enum lm363x_regulator_id id = rdev_get_id(rdev);
48         unsigned int val, addr, mask;
49
50         switch (id) {
51         case LM3631_LDO_CONT:
52                 addr = LM3631_REG_ENTIME_VCONT;
53                 mask = LM3631_ENTIME_CONT_MASK;
54                 break;
55         case LM3631_LDO_OREF:
56                 addr = LM3631_REG_ENTIME_VOREF;
57                 mask = LM3631_ENTIME_MASK;
58                 break;
59         case LM3631_LDO_POS:
60                 addr = LM3631_REG_ENTIME_VPOS;
61                 mask = LM3631_ENTIME_MASK;
62                 break;
63         case LM3631_LDO_NEG:
64                 addr = LM3631_REG_ENTIME_VNEG;
65                 mask = LM3631_ENTIME_MASK;
66                 break;
67         default:
68                 return 0;
69         }
70
71         if (regmap_read(rdev->regmap, addr, &val))
72                 return -EINVAL;
73
74         val = (val & mask) >> LM3631_ENTIME_SHIFT;
75
76         if (id == LM3631_LDO_CONT)
77                 return ldo_cont_enable_time[val];
78         else
79                 return ENABLE_TIME_USEC * val;
80 }
81
82 static const struct regulator_ops lm363x_boost_voltage_table_ops = {
83         .list_voltage     = regulator_list_voltage_linear,
84         .set_voltage_sel  = regulator_set_voltage_sel_regmap,
85         .get_voltage_sel  = regulator_get_voltage_sel_regmap,
86 };
87
88 static const struct regulator_ops lm363x_regulator_voltage_table_ops = {
89         .list_voltage     = regulator_list_voltage_linear,
90         .set_voltage_sel  = regulator_set_voltage_sel_regmap,
91         .get_voltage_sel  = regulator_get_voltage_sel_regmap,
92         .enable           = regulator_enable_regmap,
93         .disable          = regulator_disable_regmap,
94         .is_enabled       = regulator_is_enabled_regmap,
95         .enable_time      = lm363x_regulator_enable_time,
96 };
97
98 static const struct regulator_desc lm363x_regulator_desc[] = {
99         /* LM3631 */
100         {
101                 .name           = "vboost",
102                 .of_match       = "vboost",
103                 .id             = LM3631_BOOST,
104                 .ops            = &lm363x_boost_voltage_table_ops,
105                 .n_voltages     = LM3631_BOOST_VSEL_MAX + 1,
106                 .min_uV         = LM3631_VBOOST_MIN,
107                 .uV_step        = LM363X_STEP_50mV,
108                 .type           = REGULATOR_VOLTAGE,
109                 .owner          = THIS_MODULE,
110                 .vsel_reg       = LM3631_REG_VOUT_BOOST,
111                 .vsel_mask      = LM3631_VOUT_MASK,
112         },
113         {
114                 .name           = "ldo_cont",
115                 .of_match       = "vcont",
116                 .id             = LM3631_LDO_CONT,
117                 .ops            = &lm363x_regulator_voltage_table_ops,
118                 .n_voltages     = LM3631_CONT_VSEL_MAX + 1,
119                 .min_uV         = LM3631_VCONT_MIN,
120                 .uV_step        = LM363X_STEP_500mV,
121                 .type           = REGULATOR_VOLTAGE,
122                 .owner          = THIS_MODULE,
123                 .vsel_reg       = LM3631_REG_VOUT_CONT,
124                 .vsel_mask      = LM3631_VOUT_CONT_MASK,
125                 .enable_reg     = LM3631_REG_LDO_CTRL2,
126                 .enable_mask    = LM3631_EN_CONT_MASK,
127         },
128         {
129                 .name           = "ldo_oref",
130                 .of_match       = "voref",
131                 .id             = LM3631_LDO_OREF,
132                 .ops            = &lm363x_regulator_voltage_table_ops,
133                 .n_voltages     = LM3631_LDO_VSEL_MAX + 1,
134                 .min_uV         = LM3631_VLDO_MIN,
135                 .uV_step        = LM363X_STEP_50mV,
136                 .type           = REGULATOR_VOLTAGE,
137                 .owner          = THIS_MODULE,
138                 .vsel_reg       = LM3631_REG_VOUT_OREF,
139                 .vsel_mask      = LM3631_VOUT_MASK,
140                 .enable_reg     = LM3631_REG_LDO_CTRL1,
141                 .enable_mask    = LM3631_EN_OREF_MASK,
142         },
143         {
144                 .name           = "ldo_vpos",
145                 .of_match       = "vpos",
146                 .id             = LM3631_LDO_POS,
147                 .ops            = &lm363x_regulator_voltage_table_ops,
148                 .n_voltages     = LM3631_LDO_VSEL_MAX + 1,
149                 .min_uV         = LM3631_VLDO_MIN,
150                 .uV_step        = LM363X_STEP_50mV,
151                 .type           = REGULATOR_VOLTAGE,
152                 .owner          = THIS_MODULE,
153                 .vsel_reg       = LM3631_REG_VOUT_POS,
154                 .vsel_mask      = LM3631_VOUT_MASK,
155                 .enable_reg     = LM3631_REG_LDO_CTRL1,
156                 .enable_mask    = LM3631_EN_VPOS_MASK,
157         },
158         {
159                 .name           = "ldo_vneg",
160                 .of_match       = "vneg",
161                 .id             = LM3631_LDO_NEG,
162                 .ops            = &lm363x_regulator_voltage_table_ops,
163                 .n_voltages     = LM3631_LDO_VSEL_MAX + 1,
164                 .min_uV         = LM3631_VLDO_MIN,
165                 .uV_step        = LM363X_STEP_50mV,
166                 .type           = REGULATOR_VOLTAGE,
167                 .owner          = THIS_MODULE,
168                 .vsel_reg       = LM3631_REG_VOUT_NEG,
169                 .vsel_mask      = LM3631_VOUT_MASK,
170                 .enable_reg     = LM3631_REG_LDO_CTRL1,
171                 .enable_mask    = LM3631_EN_VNEG_MASK,
172         },
173         /* LM3632 */
174         {
175                 .name           = "vboost",
176                 .of_match       = "vboost",
177                 .id             = LM3632_BOOST,
178                 .ops            = &lm363x_boost_voltage_table_ops,
179                 .n_voltages     = LM3632_BOOST_VSEL_MAX + 1,
180                 .min_uV         = LM3632_VBOOST_MIN,
181                 .uV_step        = LM363X_STEP_50mV,
182                 .type           = REGULATOR_VOLTAGE,
183                 .owner          = THIS_MODULE,
184                 .vsel_reg       = LM3632_REG_VOUT_BOOST,
185                 .vsel_mask      = LM3632_VOUT_MASK,
186         },
187         {
188                 .name           = "ldo_vpos",
189                 .of_match       = "vpos",
190                 .id             = LM3632_LDO_POS,
191                 .ops            = &lm363x_regulator_voltage_table_ops,
192                 .n_voltages     = LM3632_LDO_VSEL_MAX + 1,
193                 .min_uV         = LM3632_VLDO_MIN,
194                 .uV_step        = LM363X_STEP_50mV,
195                 .type           = REGULATOR_VOLTAGE,
196                 .owner          = THIS_MODULE,
197                 .vsel_reg       = LM3632_REG_VOUT_POS,
198                 .vsel_mask      = LM3632_VOUT_MASK,
199                 .enable_reg     = LM3632_REG_BIAS_CONFIG,
200                 .enable_mask    = LM3632_EN_VPOS_MASK,
201         },
202         {
203                 .name           = "ldo_vneg",
204                 .of_match       = "vneg",
205                 .id             = LM3632_LDO_NEG,
206                 .ops            = &lm363x_regulator_voltage_table_ops,
207                 .n_voltages     = LM3632_LDO_VSEL_MAX + 1,
208                 .min_uV         = LM3632_VLDO_MIN,
209                 .uV_step        = LM363X_STEP_50mV,
210                 .type           = REGULATOR_VOLTAGE,
211                 .owner          = THIS_MODULE,
212                 .vsel_reg       = LM3632_REG_VOUT_NEG,
213                 .vsel_mask      = LM3632_VOUT_MASK,
214                 .enable_reg     = LM3632_REG_BIAS_CONFIG,
215                 .enable_mask    = LM3632_EN_VNEG_MASK,
216         },
217 };
218
219 static struct gpio_desc *lm363x_regulator_of_get_enable_gpio(struct device *dev, int id)
220 {
221         /*
222          * Check LCM_EN1/2_GPIO is configured.
223          * Those pins are used for enabling VPOS/VNEG LDOs.
224          * Do not use devm* here: the regulator core takes over the
225          * lifecycle management of the GPIO descriptor.
226          */
227         switch (id) {
228         case LM3632_LDO_POS:
229                 return gpiod_get_index_optional(dev, "enable", 0,
230                                 GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
231         case LM3632_LDO_NEG:
232                 return gpiod_get_index_optional(dev, "enable", 1,
233                                 GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
234         default:
235                 return NULL;
236         }
237 }
238
239 static int lm363x_regulator_probe(struct platform_device *pdev)
240 {
241         struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);
242         struct regmap *regmap = lmu->regmap;
243         struct regulator_config cfg = { };
244         struct regulator_dev *rdev;
245         struct device *dev = &pdev->dev;
246         int id = pdev->id;
247         struct gpio_desc *gpiod;
248         int ret;
249
250         cfg.dev = dev;
251         cfg.regmap = regmap;
252
253         /*
254          * LM3632 LDOs can be controlled by external pin.
255          * Register update is required if the pin is used.
256          */
257         gpiod = lm363x_regulator_of_get_enable_gpio(dev, id);
258         if (IS_ERR(gpiod))
259                 return PTR_ERR(gpiod);
260
261         if (gpiod) {
262                 cfg.ena_gpiod = gpiod;
263
264                 ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG,
265                                          LM3632_EXT_EN_MASK,
266                                          LM3632_EXT_EN_MASK);
267                 if (ret) {
268                         gpiod_put(gpiod);
269                         dev_err(dev, "External pin err: %d\n", ret);
270                         return ret;
271                 }
272         }
273
274         rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg);
275         if (IS_ERR(rdev)) {
276                 ret = PTR_ERR(rdev);
277                 dev_err(dev, "[%d] regulator register err: %d\n", id, ret);
278                 return ret;
279         }
280
281         return 0;
282 }
283
284 static struct platform_driver lm363x_regulator_driver = {
285         .probe = lm363x_regulator_probe,
286         .driver = {
287                 .name = "lm363x-regulator",
288         },
289 };
290
291 module_platform_driver(lm363x_regulator_driver);
292
293 MODULE_DESCRIPTION("TI LM363X Regulator Driver");
294 MODULE_AUTHOR("Milo Kim");
295 MODULE_LICENSE("GPL v2");
296 MODULE_ALIAS("platform:lm363x-regulator");