]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/regulator/hi6421-regulator.c
Merge tag 'configfs-for-4.10' of git://git.infradead.org/users/hch/configfs
[karo-tx-linux.git] / drivers / regulator / hi6421-regulator.c
1 /*
2  * Device driver for regulators in Hi6421 IC
3  *
4  * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
5  *              http://www.hisilicon.com
6  * Copyright (c) <2013-2014> Linaro Ltd.
7  *              http://www.linaro.org
8  *
9  * Author: Guodong Xu <guodong.xu@linaro.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/slab.h>
17 #include <linux/device.h>
18 #include <linux/module.h>
19 #include <linux/err.h>
20 #include <linux/platform_device.h>
21 #include <linux/of.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/driver.h>
24 #include <linux/regulator/machine.h>
25 #include <linux/regulator/of_regulator.h>
26 #include <linux/mfd/hi6421-pmic.h>
27
28 /*
29  * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device
30  * @lock: mutex to serialize regulator enable
31  */
32 struct hi6421_regulator_pdata {
33         struct mutex lock;
34 };
35
36 /*
37  * struct hi6421_regulator_info - hi6421 regulator information
38  * @desc: regulator description
39  * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep
40  * @eco_microamp: eco mode load upper limit (in uA), valid for LDOs only
41  */
42 struct hi6421_regulator_info {
43         struct regulator_desc   desc;
44         u8              mode_mask;
45         u32             eco_microamp;
46 };
47
48 /* HI6421 regulators */
49 enum hi6421_regulator_id {
50         HI6421_LDO0,
51         HI6421_LDO1,
52         HI6421_LDO2,
53         HI6421_LDO3,
54         HI6421_LDO4,
55         HI6421_LDO5,
56         HI6421_LDO6,
57         HI6421_LDO7,
58         HI6421_LDO8,
59         HI6421_LDO9,
60         HI6421_LDO10,
61         HI6421_LDO11,
62         HI6421_LDO12,
63         HI6421_LDO13,
64         HI6421_LDO14,
65         HI6421_LDO15,
66         HI6421_LDO16,
67         HI6421_LDO17,
68         HI6421_LDO18,
69         HI6421_LDO19,
70         HI6421_LDO20,
71         HI6421_LDOAUDIO,
72         HI6421_BUCK0,
73         HI6421_BUCK1,
74         HI6421_BUCK2,
75         HI6421_BUCK3,
76         HI6421_BUCK4,
77         HI6421_BUCK5,
78         HI6421_NUM_REGULATORS,
79 };
80
81 #define HI6421_REGULATOR_OF_MATCH(_name, id)                            \
82 {                                                                       \
83         .name = #_name,                                                 \
84         .driver_data = (void *) HI6421_##id,                            \
85 }
86
87 static struct of_regulator_match hi6421_regulator_match[] = {
88         HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0),
89         HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1),
90         HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2),
91         HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3),
92         HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4),
93         HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5),
94         HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6),
95         HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7),
96         HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8),
97         HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9),
98         HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10),
99         HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11),
100         HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12),
101         HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13),
102         HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14),
103         HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15),
104         HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16),
105         HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17),
106         HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18),
107         HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19),
108         HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20),
109         HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO),
110         HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0),
111         HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1),
112         HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2),
113         HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3),
114         HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4),
115         HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5),
116 };
117
118 /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */
119 static const unsigned int ldo_0_voltages[] = {
120         1500000, 1800000, 2400000, 2500000,
121         2600000, 2700000, 2850000, 3000000,
122 };
123
124 /* LDO 8, 15 have same voltage table. */
125 static const unsigned int ldo_8_voltages[] = {
126         1500000, 1800000, 2400000, 2600000,
127         2700000, 2850000, 3000000, 3300000,
128 };
129
130 /* Ranges are sorted in ascending order. */
131 static const struct regulator_linear_range ldo_audio_volt_range[] = {
132         REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000),
133         REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000),
134 };
135
136 static const unsigned int buck_3_voltages[] = {
137          950000, 1050000, 1100000, 1117000,
138         1134000, 1150000, 1167000, 1200000,
139 };
140
141 static const unsigned int buck_4_voltages[] = {
142         1150000, 1200000, 1250000, 1350000,
143         1700000, 1800000, 1900000, 2000000,
144 };
145
146 static const unsigned int buck_5_voltages[] = {
147         1150000, 1200000, 1250000, 1350000,
148         1600000, 1700000, 1800000, 1900000,
149 };
150
151 static const struct regulator_ops hi6421_ldo_ops;
152 static const struct regulator_ops hi6421_ldo_linear_ops;
153 static const struct regulator_ops hi6421_ldo_linear_range_ops;
154 static const struct regulator_ops hi6421_buck012_ops;
155 static const struct regulator_ops hi6421_buck345_ops;
156
157 #define HI6421_LDO_ENABLE_TIME (350)
158 /*
159  * _id - LDO id name string
160  * v_table - voltage table
161  * vreg - voltage select register
162  * vmask - voltage select mask
163  * ereg - enable register
164  * emask - enable mask
165  * odelay - off/on delay time in uS
166  * ecomask - eco mode mask
167  * ecoamp - eco mode load uppler limit in uA
168  */
169 #define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask,              \
170                    odelay, ecomask, ecoamp)                             \
171         [HI6421_##_id] = {                                              \
172                 .desc = {                                               \
173                         .name           = #_id,                         \
174                         .ops            = &hi6421_ldo_ops,              \
175                         .type           = REGULATOR_VOLTAGE,            \
176                         .id             = HI6421_##_id,                 \
177                         .owner          = THIS_MODULE,                  \
178                         .n_voltages     = ARRAY_SIZE(v_table),          \
179                         .volt_table     = v_table,                      \
180                         .vsel_reg       = HI6421_REG_TO_BUS_ADDR(vreg), \
181                         .vsel_mask      = vmask,                        \
182                         .enable_reg     = HI6421_REG_TO_BUS_ADDR(ereg), \
183                         .enable_mask    = emask,                        \
184                         .enable_time    = HI6421_LDO_ENABLE_TIME,       \
185                         .off_on_delay   = odelay,                       \
186                 },                                                      \
187                 .mode_mask              = ecomask,                      \
188                 .eco_microamp           = ecoamp,                       \
189         }
190
191 /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step
192  *
193  * _id - LDO id name string
194  * _min_uV - minimum voltage supported in uV
195  * n_volt - number of votages available
196  * vstep - voltage increase in each linear step in uV
197  * vreg - voltage select register
198  * vmask - voltage select mask
199  * ereg - enable register
200  * emask - enable mask
201  * odelay - off/on delay time in uS
202  * ecomask - eco mode mask
203  * ecoamp - eco mode load uppler limit in uA
204  */
205 #define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask,     \
206                           ereg, emask, odelay, ecomask, ecoamp)         \
207         [HI6421_##_id] = {                                              \
208                 .desc = {                                               \
209                         .name           = #_id,                         \
210                         .ops            = &hi6421_ldo_linear_ops,       \
211                         .type           = REGULATOR_VOLTAGE,            \
212                         .id             = HI6421_##_id,                 \
213                         .owner          = THIS_MODULE,                  \
214                         .min_uV         = _min_uV,                      \
215                         .n_voltages     = n_volt,                       \
216                         .uV_step        = vstep,                        \
217                         .vsel_reg       = HI6421_REG_TO_BUS_ADDR(vreg), \
218                         .vsel_mask      = vmask,                        \
219                         .enable_reg     = HI6421_REG_TO_BUS_ADDR(ereg), \
220                         .enable_mask    = emask,                        \
221                         .enable_time    = HI6421_LDO_ENABLE_TIME,       \
222                         .off_on_delay   = odelay,                       \
223                 },                                                      \
224                 .mode_mask              = ecomask,                      \
225                 .eco_microamp           = ecoamp,                       \
226         }
227
228 /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges
229  *
230  * _id - LDO id name string
231  * n_volt - number of votages available
232  * volt_ranges - array of regulator_linear_range
233  * vstep - voltage increase in each linear step in uV
234  * vreg - voltage select register
235  * vmask - voltage select mask
236  * ereg - enable register
237  * emask - enable mask
238  * odelay - off/on delay time in uS
239  * ecomask - eco mode mask
240  * ecoamp - eco mode load uppler limit in uA
241  */
242 #define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask,  \
243                                 ereg, emask, odelay, ecomask, ecoamp)   \
244         [HI6421_##_id] = {                                              \
245                 .desc = {                                               \
246                         .name           = #_id,                         \
247                         .ops            = &hi6421_ldo_linear_range_ops, \
248                         .type           = REGULATOR_VOLTAGE,            \
249                         .id             = HI6421_##_id,                 \
250                         .owner          = THIS_MODULE,                  \
251                         .n_voltages     = n_volt,                       \
252                         .linear_ranges  = volt_ranges,                  \
253                         .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
254                         .vsel_reg       = HI6421_REG_TO_BUS_ADDR(vreg), \
255                         .vsel_mask      = vmask,                        \
256                         .enable_reg     = HI6421_REG_TO_BUS_ADDR(ereg), \
257                         .enable_mask    = emask,                        \
258                         .enable_time    = HI6421_LDO_ENABLE_TIME,       \
259                         .off_on_delay   = odelay,                       \
260                 },                                                      \
261                 .mode_mask              = ecomask,                      \
262                 .eco_microamp           = ecoamp,                       \
263         }
264
265 /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step
266  *
267  * _id - BUCK0/1/2 id name string
268  * vreg - voltage select register
269  * vmask - voltage select mask
270  * ereg - enable register
271  * emask - enable mask
272  * sleepmask - mask of sleep mode
273  * etime - enable time
274  * odelay - off/on delay time in uS
275  */
276 #define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask,        \
277                         etime, odelay)                                  \
278         [HI6421_##_id] = {                                              \
279                 .desc = {                                               \
280                         .name           = #_id,                         \
281                         .ops            = &hi6421_buck012_ops,          \
282                         .type           = REGULATOR_VOLTAGE,            \
283                         .id             = HI6421_##_id,                 \
284                         .owner          = THIS_MODULE,                  \
285                         .min_uV         = 700000,                       \
286                         .n_voltages     = 128,                          \
287                         .uV_step        = 7086,                         \
288                         .vsel_reg       = HI6421_REG_TO_BUS_ADDR(vreg), \
289                         .vsel_mask      = vmask,                        \
290                         .enable_reg     = HI6421_REG_TO_BUS_ADDR(ereg), \
291                         .enable_mask    = emask,                        \
292                         .enable_time    = etime,                        \
293                         .off_on_delay   = odelay,                       \
294                 },                                                      \
295                 .mode_mask              = sleepmask,                    \
296         }
297
298 /* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception
299  *  that it supports SLEEP mode, so has different .ops.
300  *
301  * _id - LDO id name string
302  * v_table - voltage table
303  * vreg - voltage select register
304  * vmask - voltage select mask
305  * ereg - enable register
306  * emask - enable mask
307  * odelay - off/on delay time in uS
308  * sleepmask - mask of sleep mode
309  */
310 #define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask,          \
311                         odelay, sleepmask)                              \
312         [HI6421_##_id] = {                                              \
313                 .desc = {                                               \
314                         .name           = #_id,                         \
315                         .ops            = &hi6421_buck345_ops,          \
316                         .type           = REGULATOR_VOLTAGE,            \
317                         .id             = HI6421_##_id,                 \
318                         .owner          = THIS_MODULE,                  \
319                         .n_voltages     = ARRAY_SIZE(v_table),          \
320                         .volt_table     = v_table,                      \
321                         .vsel_reg       = HI6421_REG_TO_BUS_ADDR(vreg), \
322                         .vsel_mask      = vmask,                        \
323                         .enable_reg     = HI6421_REG_TO_BUS_ADDR(ereg), \
324                         .enable_mask    = emask,                        \
325                         .enable_time    = HI6421_LDO_ENABLE_TIME,       \
326                         .off_on_delay   = odelay,                       \
327                 },                                                      \
328                 .mode_mask              = sleepmask,                    \
329         }
330
331 /* HI6421 regulator information */
332 static struct hi6421_regulator_info
333                 hi6421_regulator_info[HI6421_NUM_REGULATORS] = {
334         HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10,
335                    10000, 0x20, 8000),
336         HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10,
337                           10000, 0x20, 5000),
338         HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10,
339                           20000, 0x20, 8000),
340         HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10,
341                           20000, 0x20, 8000),
342         HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10,
343                    20000, 0x20, 8000),
344         HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10,
345                    20000, 0x20, 8000),
346         HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10,
347                    20000, 0x20, 8000),
348         HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10,
349                    20000, 0x20, 5000),
350         HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10,
351                    20000, 0x20, 8000),
352         HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10,
353                    40000, 0x20, 8000),
354         HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10,
355                    40000, 0x20, 8000),
356         HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10,
357                    40000, 0x20, 8000),
358         HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10,
359                    40000, 0x20, 8000),
360         HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10,
361                    40000, 0x20, 8000),
362         HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10,
363                    40000, 0x20, 8000),
364         HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10,
365                    40000, 0x20, 8000),
366         HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10,
367                    40000, 0x20, 8000),
368         HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10,
369                    40000, 0x20, 8000),
370         HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10,
371                    40000, 0x20, 8000),
372         HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10,
373                    40000, 0x20, 8000),
374         HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10,
375                    40000, 0x20, 8000),
376         HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36,
377                                 0x70, 0x36, 0x01, 40000, 0x02, 5000),
378         HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000),
379         HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000),
380         HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100),
381         HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01,
382                        20000, 0x10),
383         HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01,
384                        20000, 0x10),
385         HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01,
386                        20000, 0x10),
387 };
388
389 static int hi6421_regulator_enable(struct regulator_dev *rdev)
390 {
391         struct hi6421_regulator_pdata *pdata;
392
393         pdata = dev_get_drvdata(rdev->dev.parent);
394         /* hi6421 spec requires regulator enablement must be serialized:
395          *  - Because when BUCK, LDO switching from off to on, it will have
396          *    a huge instantaneous current; so you can not turn on two or
397          *    more LDO or BUCKs simultaneously, or it may burn the chip.
398          */
399         mutex_lock(&pdata->lock);
400
401         /* call regulator regmap helper */
402         regulator_enable_regmap(rdev);
403
404         mutex_unlock(&pdata->lock);
405         return 0;
406 }
407
408 static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
409 {
410         struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
411         u32 reg_val;
412
413         regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
414         if (reg_val & info->mode_mask)
415                 return REGULATOR_MODE_IDLE;
416
417         return REGULATOR_MODE_NORMAL;
418 }
419
420 static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev)
421 {
422         struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
423         u32 reg_val;
424
425         regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
426         if (reg_val & info->mode_mask)
427                 return REGULATOR_MODE_STANDBY;
428
429         return REGULATOR_MODE_NORMAL;
430 }
431
432 static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev,
433                                                 unsigned int mode)
434 {
435         struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
436         u32 new_mode;
437
438         switch (mode) {
439         case REGULATOR_MODE_NORMAL:
440                 new_mode = 0;
441                 break;
442         case REGULATOR_MODE_IDLE:
443                 new_mode = info->mode_mask;
444                 break;
445         default:
446                 return -EINVAL;
447         }
448
449         /* set mode */
450         regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
451                            info->mode_mask, new_mode);
452
453         return 0;
454 }
455
456 static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
457                                                 unsigned int mode)
458 {
459         struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
460         u32 new_mode;
461
462         switch (mode) {
463         case REGULATOR_MODE_NORMAL:
464                 new_mode = 0;
465                 break;
466         case REGULATOR_MODE_STANDBY:
467                 new_mode = info->mode_mask;
468                 break;
469         default:
470                 return -EINVAL;
471         }
472
473         /* set mode */
474         regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
475                            info->mode_mask, new_mode);
476
477         return 0;
478 }
479
480 static unsigned int
481 hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev,
482                         int input_uV, int output_uV, int load_uA)
483 {
484         struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
485
486         if (load_uA > info->eco_microamp)
487                 return REGULATOR_MODE_NORMAL;
488
489         return REGULATOR_MODE_IDLE;
490 }
491
492 static const struct regulator_ops hi6421_ldo_ops = {
493         .is_enabled = regulator_is_enabled_regmap,
494         .enable = hi6421_regulator_enable,
495         .disable = regulator_disable_regmap,
496         .list_voltage = regulator_list_voltage_table,
497         .map_voltage = regulator_map_voltage_ascend,
498         .get_voltage_sel = regulator_get_voltage_sel_regmap,
499         .set_voltage_sel = regulator_set_voltage_sel_regmap,
500         .get_mode = hi6421_regulator_ldo_get_mode,
501         .set_mode = hi6421_regulator_ldo_set_mode,
502         .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
503 };
504
505 static const struct regulator_ops hi6421_ldo_linear_ops = {
506         .is_enabled = regulator_is_enabled_regmap,
507         .enable = hi6421_regulator_enable,
508         .disable = regulator_disable_regmap,
509         .list_voltage = regulator_list_voltage_linear,
510         .map_voltage = regulator_map_voltage_linear,
511         .get_voltage_sel = regulator_get_voltage_sel_regmap,
512         .set_voltage_sel = regulator_set_voltage_sel_regmap,
513         .get_mode = hi6421_regulator_ldo_get_mode,
514         .set_mode = hi6421_regulator_ldo_set_mode,
515         .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
516 };
517
518 static const struct regulator_ops hi6421_ldo_linear_range_ops = {
519         .is_enabled = regulator_is_enabled_regmap,
520         .enable = hi6421_regulator_enable,
521         .disable = regulator_disable_regmap,
522         .list_voltage = regulator_list_voltage_linear_range,
523         .map_voltage = regulator_map_voltage_linear_range,
524         .get_voltage_sel = regulator_get_voltage_sel_regmap,
525         .set_voltage_sel = regulator_set_voltage_sel_regmap,
526         .get_mode = hi6421_regulator_ldo_get_mode,
527         .set_mode = hi6421_regulator_ldo_set_mode,
528         .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
529 };
530
531 static const struct regulator_ops hi6421_buck012_ops = {
532         .is_enabled = regulator_is_enabled_regmap,
533         .enable = hi6421_regulator_enable,
534         .disable = regulator_disable_regmap,
535         .list_voltage = regulator_list_voltage_linear,
536         .map_voltage = regulator_map_voltage_linear,
537         .get_voltage_sel = regulator_get_voltage_sel_regmap,
538         .set_voltage_sel = regulator_set_voltage_sel_regmap,
539         .get_mode = hi6421_regulator_buck_get_mode,
540         .set_mode = hi6421_regulator_buck_set_mode,
541 };
542
543 static const struct regulator_ops hi6421_buck345_ops = {
544         .is_enabled = regulator_is_enabled_regmap,
545         .enable = hi6421_regulator_enable,
546         .disable = regulator_disable_regmap,
547         .list_voltage = regulator_list_voltage_table,
548         .map_voltage = regulator_map_voltage_ascend,
549         .get_voltage_sel = regulator_get_voltage_sel_regmap,
550         .set_voltage_sel = regulator_set_voltage_sel_regmap,
551         .get_mode = hi6421_regulator_buck_get_mode,
552         .set_mode = hi6421_regulator_buck_set_mode,
553 };
554
555 static int hi6421_regulator_register(struct platform_device *pdev,
556                                      struct regmap *rmap,
557                                      struct regulator_init_data *init_data,
558                                      int id, struct device_node *np)
559 {
560         struct hi6421_regulator_info *info = NULL;
561         struct regulator_config config = { };
562         struct regulator_dev *rdev;
563
564         /* assign per-regulator data */
565         info = &hi6421_regulator_info[id];
566
567         config.dev = &pdev->dev;
568         config.init_data = init_data;
569         config.driver_data = info;
570         config.regmap = rmap;
571         config.of_node = np;
572
573         /* register regulator with framework */
574         rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
575         if (IS_ERR(rdev)) {
576                 dev_err(&pdev->dev, "failed to register regulator %s\n",
577                         info->desc.name);
578                 return PTR_ERR(rdev);
579         }
580
581         return 0;
582 }
583
584 static int hi6421_regulator_probe(struct platform_device *pdev)
585 {
586         struct device *dev = &pdev->dev;
587         struct device_node *np;
588         struct hi6421_pmic *pmic;
589         struct hi6421_regulator_pdata *pdata;
590         int i, ret = 0;
591
592         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
593         if (!pdata)
594                 return -ENOMEM;
595         mutex_init(&pdata->lock);
596         platform_set_drvdata(pdev, pdata);
597
598         np = of_get_child_by_name(dev->parent->of_node, "regulators");
599         if (!np)
600                 return -ENODEV;
601
602         ret = of_regulator_match(dev, np,
603                                  hi6421_regulator_match,
604                                  ARRAY_SIZE(hi6421_regulator_match));
605         of_node_put(np);
606         if (ret < 0) {
607                 dev_err(dev, "Error parsing regulator init data: %d\n", ret);
608                 return ret;
609         }
610
611         pmic = dev_get_drvdata(dev->parent);
612
613         for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) {
614                 ret = hi6421_regulator_register(pdev, pmic->regmap,
615                         hi6421_regulator_match[i].init_data, i,
616                         hi6421_regulator_match[i].of_node);
617                 if (ret)
618                         return ret;
619         }
620
621         return 0;
622 }
623
624 static struct platform_driver hi6421_regulator_driver = {
625         .driver = {
626                 .name   = "hi6421-regulator",
627         },
628         .probe  = hi6421_regulator_probe,
629 };
630 module_platform_driver(hi6421_regulator_driver);
631
632 MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
633 MODULE_DESCRIPTION("Hi6421 regulator driver");
634 MODULE_LICENSE("GPL v2");