Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Device driver for regulators in Hi6421 IC
0004 //
0005 // Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
0006 //              http://www.hisilicon.com
0007 // Copyright (c) <2013-2014> Linaro Ltd.
0008 //              https://www.linaro.org
0009 //
0010 // Author: Guodong Xu <guodong.xu@linaro.org>
0011 
0012 #include <linux/slab.h>
0013 #include <linux/device.h>
0014 #include <linux/module.h>
0015 #include <linux/err.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/of.h>
0018 #include <linux/regmap.h>
0019 #include <linux/regulator/driver.h>
0020 #include <linux/regulator/machine.h>
0021 #include <linux/regulator/of_regulator.h>
0022 #include <linux/mfd/hi6421-pmic.h>
0023 
0024 /*
0025  * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device
0026  * @lock: mutex to serialize regulator enable
0027  */
0028 struct hi6421_regulator_pdata {
0029     struct mutex lock;
0030 };
0031 
0032 /*
0033  * struct hi6421_regulator_info - hi6421 regulator information
0034  * @desc: regulator description
0035  * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep
0036  * @eco_microamp: eco mode load upper limit (in uA), valid for LDOs only
0037  */
0038 struct hi6421_regulator_info {
0039     struct regulator_desc   desc;
0040     u8      mode_mask;
0041     u32     eco_microamp;
0042 };
0043 
0044 /* HI6421 regulators */
0045 enum hi6421_regulator_id {
0046     HI6421_LDO0,
0047     HI6421_LDO1,
0048     HI6421_LDO2,
0049     HI6421_LDO3,
0050     HI6421_LDO4,
0051     HI6421_LDO5,
0052     HI6421_LDO6,
0053     HI6421_LDO7,
0054     HI6421_LDO8,
0055     HI6421_LDO9,
0056     HI6421_LDO10,
0057     HI6421_LDO11,
0058     HI6421_LDO12,
0059     HI6421_LDO13,
0060     HI6421_LDO14,
0061     HI6421_LDO15,
0062     HI6421_LDO16,
0063     HI6421_LDO17,
0064     HI6421_LDO18,
0065     HI6421_LDO19,
0066     HI6421_LDO20,
0067     HI6421_LDOAUDIO,
0068     HI6421_BUCK0,
0069     HI6421_BUCK1,
0070     HI6421_BUCK2,
0071     HI6421_BUCK3,
0072     HI6421_BUCK4,
0073     HI6421_BUCK5,
0074     HI6421_NUM_REGULATORS,
0075 };
0076 
0077 /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */
0078 static const unsigned int ldo_0_voltages[] = {
0079     1500000, 1800000, 2400000, 2500000,
0080     2600000, 2700000, 2850000, 3000000,
0081 };
0082 
0083 /* LDO 8, 15 have same voltage table. */
0084 static const unsigned int ldo_8_voltages[] = {
0085     1500000, 1800000, 2400000, 2600000,
0086     2700000, 2850000, 3000000, 3300000,
0087 };
0088 
0089 /* Ranges are sorted in ascending order. */
0090 static const struct linear_range ldo_audio_volt_range[] = {
0091     REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000),
0092     REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000),
0093 };
0094 
0095 static const unsigned int buck_3_voltages[] = {
0096      950000, 1050000, 1100000, 1117000,
0097     1134000, 1150000, 1167000, 1200000,
0098 };
0099 
0100 static const unsigned int buck_4_voltages[] = {
0101     1150000, 1200000, 1250000, 1350000,
0102     1700000, 1800000, 1900000, 2000000,
0103 };
0104 
0105 static const unsigned int buck_5_voltages[] = {
0106     1150000, 1200000, 1250000, 1350000,
0107     1600000, 1700000, 1800000, 1900000,
0108 };
0109 
0110 static const struct regulator_ops hi6421_ldo_ops;
0111 static const struct regulator_ops hi6421_ldo_linear_ops;
0112 static const struct regulator_ops hi6421_ldo_linear_range_ops;
0113 static const struct regulator_ops hi6421_buck012_ops;
0114 static const struct regulator_ops hi6421_buck345_ops;
0115 
0116 #define HI6421_LDO_ENABLE_TIME (350)
0117 /*
0118  * _id - LDO id name string
0119  * _match - of match name string
0120  * v_table - voltage table
0121  * vreg - voltage select register
0122  * vmask - voltage select mask
0123  * ereg - enable register
0124  * emask - enable mask
0125  * odelay - off/on delay time in uS
0126  * ecomask - eco mode mask
0127  * ecoamp - eco mode load uppler limit in uA
0128  */
0129 #define HI6421_LDO(_id, _match, v_table, vreg, vmask, ereg, emask,  \
0130            odelay, ecomask, ecoamp)             \
0131     [HI6421_##_id] = {                      \
0132         .desc = {                       \
0133             .name       = #_id,             \
0134             .of_match        = of_match_ptr(#_match),   \
0135             .regulators_node = of_match_ptr("regulators"),  \
0136             .ops        = &hi6421_ldo_ops,      \
0137             .type       = REGULATOR_VOLTAGE,        \
0138             .id     = HI6421_##_id,         \
0139             .owner      = THIS_MODULE,          \
0140             .n_voltages = ARRAY_SIZE(v_table),      \
0141             .volt_table = v_table,          \
0142             .vsel_reg   = HI6421_REG_TO_BUS_ADDR(vreg), \
0143             .vsel_mask  = vmask,            \
0144             .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
0145             .enable_mask    = emask,            \
0146             .enable_time    = HI6421_LDO_ENABLE_TIME,   \
0147             .off_on_delay   = odelay,           \
0148         },                          \
0149         .mode_mask      = ecomask,          \
0150         .eco_microamp       = ecoamp,           \
0151     }
0152 
0153 /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step
0154  *
0155  * _id - LDO id name string
0156  * _match - of match name string
0157  * _min_uV - minimum voltage supported in uV
0158  * n_volt - number of votages available
0159  * vstep - voltage increase in each linear step in uV
0160  * vreg - voltage select register
0161  * vmask - voltage select mask
0162  * ereg - enable register
0163  * emask - enable mask
0164  * odelay - off/on delay time in uS
0165  * ecomask - eco mode mask
0166  * ecoamp - eco mode load uppler limit in uA
0167  */
0168 #define HI6421_LDO_LINEAR(_id, _match, _min_uV, n_volt, vstep, vreg, vmask,\
0169               ereg, emask, odelay, ecomask, ecoamp)     \
0170     [HI6421_##_id] = {                      \
0171         .desc = {                       \
0172             .name       = #_id,             \
0173             .of_match        = of_match_ptr(#_match),   \
0174             .regulators_node = of_match_ptr("regulators"),  \
0175             .ops        = &hi6421_ldo_linear_ops,   \
0176             .type       = REGULATOR_VOLTAGE,        \
0177             .id     = HI6421_##_id,         \
0178             .owner      = THIS_MODULE,          \
0179             .min_uV     = _min_uV,          \
0180             .n_voltages = n_volt,           \
0181             .uV_step    = vstep,            \
0182             .vsel_reg   = HI6421_REG_TO_BUS_ADDR(vreg), \
0183             .vsel_mask  = vmask,            \
0184             .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
0185             .enable_mask    = emask,            \
0186             .enable_time    = HI6421_LDO_ENABLE_TIME,   \
0187             .off_on_delay   = odelay,           \
0188         },                          \
0189         .mode_mask      = ecomask,          \
0190         .eco_microamp       = ecoamp,           \
0191     }
0192 
0193 /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges
0194  *
0195  * _id - LDO id name string
0196  * _match - of match name string
0197  * n_volt - number of votages available
0198  * volt_ranges - array of linear_range
0199  * vstep - voltage increase in each linear step in uV
0200  * vreg - voltage select register
0201  * vmask - voltage select mask
0202  * ereg - enable register
0203  * emask - enable mask
0204  * odelay - off/on delay time in uS
0205  * ecomask - eco mode mask
0206  * ecoamp - eco mode load uppler limit in uA
0207  */
0208 #define HI6421_LDO_LINEAR_RANGE(_id, _match, n_volt, volt_ranges, vreg, vmask,\
0209                 ereg, emask, odelay, ecomask, ecoamp)   \
0210     [HI6421_##_id] = {                      \
0211         .desc = {                       \
0212             .name       = #_id,             \
0213             .of_match        = of_match_ptr(#_match),   \
0214             .regulators_node = of_match_ptr("regulators"),  \
0215             .ops        = &hi6421_ldo_linear_range_ops, \
0216             .type       = REGULATOR_VOLTAGE,        \
0217             .id     = HI6421_##_id,         \
0218             .owner      = THIS_MODULE,          \
0219             .n_voltages = n_volt,           \
0220             .linear_ranges  = volt_ranges,          \
0221             .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
0222             .vsel_reg   = HI6421_REG_TO_BUS_ADDR(vreg), \
0223             .vsel_mask  = vmask,            \
0224             .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
0225             .enable_mask    = emask,            \
0226             .enable_time    = HI6421_LDO_ENABLE_TIME,   \
0227             .off_on_delay   = odelay,           \
0228         },                          \
0229         .mode_mask      = ecomask,          \
0230         .eco_microamp       = ecoamp,           \
0231     }
0232 
0233 /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step
0234  *
0235  * _id - BUCK0/1/2 id name string
0236  * _match - of match name string
0237  * vreg - voltage select register
0238  * vmask - voltage select mask
0239  * ereg - enable register
0240  * emask - enable mask
0241  * sleepmask - mask of sleep mode
0242  * etime - enable time
0243  * odelay - off/on delay time in uS
0244  */
0245 #define HI6421_BUCK012(_id, _match, vreg, vmask, ereg, emask, sleepmask,\
0246             etime, odelay)                  \
0247     [HI6421_##_id] = {                      \
0248         .desc = {                       \
0249             .name       = #_id,             \
0250             .of_match        = of_match_ptr(#_match),   \
0251             .regulators_node = of_match_ptr("regulators"),  \
0252             .ops        = &hi6421_buck012_ops,      \
0253             .type       = REGULATOR_VOLTAGE,        \
0254             .id     = HI6421_##_id,         \
0255             .owner      = THIS_MODULE,          \
0256             .min_uV     = 700000,           \
0257             .n_voltages = 128,              \
0258             .uV_step    = 7086,             \
0259             .vsel_reg   = HI6421_REG_TO_BUS_ADDR(vreg), \
0260             .vsel_mask  = vmask,            \
0261             .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
0262             .enable_mask    = emask,            \
0263             .enable_time    = etime,            \
0264             .off_on_delay   = odelay,           \
0265         },                          \
0266         .mode_mask      = sleepmask,            \
0267     }
0268 
0269 /* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception
0270  *  that it supports SLEEP mode, so has different .ops.
0271  *
0272  * _id - LDO id name string
0273  * _match - of match name string
0274  * v_table - voltage table
0275  * vreg - voltage select register
0276  * vmask - voltage select mask
0277  * ereg - enable register
0278  * emask - enable mask
0279  * odelay - off/on delay time in uS
0280  * sleepmask - mask of sleep mode
0281  */
0282 #define HI6421_BUCK345(_id, _match, v_table, vreg, vmask, ereg, emask,  \
0283             odelay, sleepmask)              \
0284     [HI6421_##_id] = {                      \
0285         .desc = {                       \
0286             .name       = #_id,             \
0287             .of_match        = of_match_ptr(#_match),   \
0288             .regulators_node = of_match_ptr("regulators"),  \
0289             .ops        = &hi6421_buck345_ops,      \
0290             .type       = REGULATOR_VOLTAGE,        \
0291             .id     = HI6421_##_id,         \
0292             .owner      = THIS_MODULE,          \
0293             .n_voltages = ARRAY_SIZE(v_table),      \
0294             .volt_table = v_table,          \
0295             .vsel_reg   = HI6421_REG_TO_BUS_ADDR(vreg), \
0296             .vsel_mask  = vmask,            \
0297             .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \
0298             .enable_mask    = emask,            \
0299             .enable_time    = HI6421_LDO_ENABLE_TIME,   \
0300             .off_on_delay   = odelay,           \
0301         },                          \
0302         .mode_mask      = sleepmask,            \
0303     }
0304 
0305 /* HI6421 regulator information */
0306 static struct hi6421_regulator_info
0307         hi6421_regulator_info[HI6421_NUM_REGULATORS] = {
0308     HI6421_LDO(LDO0, hi6421_vout0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10,
0309            10000, 0x20, 8000),
0310     HI6421_LDO_LINEAR(LDO1, hi6421_vout1, 1700000, 4, 100000, 0x21, 0x03,
0311               0x21, 0x10, 10000, 0x20, 5000),
0312     HI6421_LDO_LINEAR(LDO2, hi6421_vout2, 1050000, 8, 50000, 0x22, 0x07,
0313               0x22, 0x10, 20000, 0x20, 8000),
0314     HI6421_LDO_LINEAR(LDO3, hi6421_vout3, 1050000, 8, 50000, 0x23, 0x07,
0315               0x23, 0x10, 20000, 0x20, 8000),
0316     HI6421_LDO(LDO4, hi6421_vout4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10,
0317            20000, 0x20, 8000),
0318     HI6421_LDO(LDO5, hi6421_vout5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10,
0319            20000, 0x20, 8000),
0320     HI6421_LDO(LDO6, hi6421_vout6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10,
0321            20000, 0x20, 8000),
0322     HI6421_LDO(LDO7, hi6421_vout7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10,
0323            20000, 0x20, 5000),
0324     HI6421_LDO(LDO8, hi6421_vout8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10,
0325            20000, 0x20, 8000),
0326     HI6421_LDO(LDO9, hi6421_vout9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10,
0327            40000, 0x20, 8000),
0328     HI6421_LDO(LDO10, hi6421_vout10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10,
0329            40000, 0x20, 8000),
0330     HI6421_LDO(LDO11, hi6421_vout11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10,
0331            40000, 0x20, 8000),
0332     HI6421_LDO(LDO12, hi6421_vout12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10,
0333            40000, 0x20, 8000),
0334     HI6421_LDO(LDO13, hi6421_vout13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10,
0335            40000, 0x20, 8000),
0336     HI6421_LDO(LDO14, hi6421_vout14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10,
0337            40000, 0x20, 8000),
0338     HI6421_LDO(LDO15, hi6421_vout15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10,
0339            40000, 0x20, 8000),
0340     HI6421_LDO(LDO16, hi6421_vout16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10,
0341            40000, 0x20, 8000),
0342     HI6421_LDO(LDO17, hi6421_vout17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10,
0343            40000, 0x20, 8000),
0344     HI6421_LDO(LDO18, hi6421_vout18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10,
0345            40000, 0x20, 8000),
0346     HI6421_LDO(LDO19, hi6421_vout19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10,
0347            40000, 0x20, 8000),
0348     HI6421_LDO(LDO20, hi6421_vout20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10,
0349            40000, 0x20, 8000),
0350     HI6421_LDO_LINEAR_RANGE(LDOAUDIO, hi6421_vout_audio, 8,
0351                 ldo_audio_volt_range, 0x36, 0x70, 0x36, 0x01,
0352                 40000, 0x02, 5000),
0353     HI6421_BUCK012(BUCK0, hi6421_buck0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400,
0354                20000),
0355     HI6421_BUCK012(BUCK1, hi6421_buck1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400,
0356                20000),
0357     HI6421_BUCK012(BUCK2, hi6421_buck2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350,
0358                100),
0359     HI6421_BUCK345(BUCK3, hi6421_buck3, buck_3_voltages, 0x13, 0x07, 0x12,
0360                0x01, 20000, 0x10),
0361     HI6421_BUCK345(BUCK4, hi6421_buck4, buck_4_voltages, 0x15, 0x07, 0x14,
0362                0x01, 20000, 0x10),
0363     HI6421_BUCK345(BUCK5, hi6421_buck5, buck_5_voltages, 0x17, 0x07, 0x16,
0364                0x01, 20000, 0x10),
0365 };
0366 
0367 static int hi6421_regulator_enable(struct regulator_dev *rdev)
0368 {
0369     struct hi6421_regulator_pdata *pdata = rdev_get_drvdata(rdev);
0370 
0371     /* hi6421 spec requires regulator enablement must be serialized:
0372      *  - Because when BUCK, LDO switching from off to on, it will have
0373      *    a huge instantaneous current; so you can not turn on two or
0374      *    more LDO or BUCKs simultaneously, or it may burn the chip.
0375      */
0376     mutex_lock(&pdata->lock);
0377 
0378     /* call regulator regmap helper */
0379     regulator_enable_regmap(rdev);
0380 
0381     mutex_unlock(&pdata->lock);
0382     return 0;
0383 }
0384 
0385 static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
0386 {
0387     struct hi6421_regulator_info *info;
0388     unsigned int reg_val;
0389 
0390     info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
0391     regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
0392     if (reg_val & info->mode_mask)
0393         return REGULATOR_MODE_IDLE;
0394 
0395     return REGULATOR_MODE_NORMAL;
0396 }
0397 
0398 static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev)
0399 {
0400     struct hi6421_regulator_info *info;
0401     unsigned int reg_val;
0402 
0403     info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
0404     regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
0405     if (reg_val & info->mode_mask)
0406         return REGULATOR_MODE_STANDBY;
0407 
0408     return REGULATOR_MODE_NORMAL;
0409 }
0410 
0411 static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev,
0412                         unsigned int mode)
0413 {
0414     struct hi6421_regulator_info *info;
0415     unsigned int new_mode;
0416 
0417     info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
0418     switch (mode) {
0419     case REGULATOR_MODE_NORMAL:
0420         new_mode = 0;
0421         break;
0422     case REGULATOR_MODE_IDLE:
0423         new_mode = info->mode_mask;
0424         break;
0425     default:
0426         return -EINVAL;
0427     }
0428 
0429     /* set mode */
0430     regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0431                info->mode_mask, new_mode);
0432 
0433     return 0;
0434 }
0435 
0436 static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
0437                         unsigned int mode)
0438 {
0439     struct hi6421_regulator_info *info;
0440     unsigned int new_mode;
0441 
0442     info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
0443     switch (mode) {
0444     case REGULATOR_MODE_NORMAL:
0445         new_mode = 0;
0446         break;
0447     case REGULATOR_MODE_STANDBY:
0448         new_mode = info->mode_mask;
0449         break;
0450     default:
0451         return -EINVAL;
0452     }
0453 
0454     /* set mode */
0455     regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0456                info->mode_mask, new_mode);
0457 
0458     return 0;
0459 }
0460 
0461 static unsigned int
0462 hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev,
0463             int input_uV, int output_uV, int load_uA)
0464 {
0465     struct hi6421_regulator_info *info;
0466 
0467     info = container_of(rdev->desc, struct hi6421_regulator_info, desc);
0468 
0469     if (load_uA > info->eco_microamp)
0470         return REGULATOR_MODE_NORMAL;
0471 
0472     return REGULATOR_MODE_IDLE;
0473 }
0474 
0475 static const struct regulator_ops hi6421_ldo_ops = {
0476     .is_enabled = regulator_is_enabled_regmap,
0477     .enable = hi6421_regulator_enable,
0478     .disable = regulator_disable_regmap,
0479     .list_voltage = regulator_list_voltage_table,
0480     .map_voltage = regulator_map_voltage_ascend,
0481     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0482     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0483     .get_mode = hi6421_regulator_ldo_get_mode,
0484     .set_mode = hi6421_regulator_ldo_set_mode,
0485     .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
0486 };
0487 
0488 static const struct regulator_ops hi6421_ldo_linear_ops = {
0489     .is_enabled = regulator_is_enabled_regmap,
0490     .enable = hi6421_regulator_enable,
0491     .disable = regulator_disable_regmap,
0492     .list_voltage = regulator_list_voltage_linear,
0493     .map_voltage = regulator_map_voltage_linear,
0494     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0495     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0496     .get_mode = hi6421_regulator_ldo_get_mode,
0497     .set_mode = hi6421_regulator_ldo_set_mode,
0498     .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
0499 };
0500 
0501 static const struct regulator_ops hi6421_ldo_linear_range_ops = {
0502     .is_enabled = regulator_is_enabled_regmap,
0503     .enable = hi6421_regulator_enable,
0504     .disable = regulator_disable_regmap,
0505     .list_voltage = regulator_list_voltage_linear_range,
0506     .map_voltage = regulator_map_voltage_linear_range,
0507     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0508     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0509     .get_mode = hi6421_regulator_ldo_get_mode,
0510     .set_mode = hi6421_regulator_ldo_set_mode,
0511     .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode,
0512 };
0513 
0514 static const struct regulator_ops hi6421_buck012_ops = {
0515     .is_enabled = regulator_is_enabled_regmap,
0516     .enable = hi6421_regulator_enable,
0517     .disable = regulator_disable_regmap,
0518     .list_voltage = regulator_list_voltage_linear,
0519     .map_voltage = regulator_map_voltage_linear,
0520     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0521     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0522     .get_mode = hi6421_regulator_buck_get_mode,
0523     .set_mode = hi6421_regulator_buck_set_mode,
0524 };
0525 
0526 static const struct regulator_ops hi6421_buck345_ops = {
0527     .is_enabled = regulator_is_enabled_regmap,
0528     .enable = hi6421_regulator_enable,
0529     .disable = regulator_disable_regmap,
0530     .list_voltage = regulator_list_voltage_table,
0531     .map_voltage = regulator_map_voltage_ascend,
0532     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0533     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0534     .get_mode = hi6421_regulator_buck_get_mode,
0535     .set_mode = hi6421_regulator_buck_set_mode,
0536 };
0537 
0538 static int hi6421_regulator_probe(struct platform_device *pdev)
0539 {
0540     struct hi6421_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
0541     struct hi6421_regulator_pdata *pdata;
0542     struct hi6421_regulator_info *info;
0543     struct regulator_config config = { };
0544     struct regulator_dev *rdev;
0545     int i;
0546 
0547     pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0548     if (!pdata)
0549         return -ENOMEM;
0550     mutex_init(&pdata->lock);
0551 
0552     for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) {
0553         /* assign per-regulator data */
0554         info = &hi6421_regulator_info[i];
0555 
0556         config.dev = pdev->dev.parent;
0557         config.driver_data = pdata;
0558         config.regmap = pmic->regmap;
0559 
0560         rdev = devm_regulator_register(&pdev->dev, &info->desc,
0561                            &config);
0562         if (IS_ERR(rdev)) {
0563             dev_err(&pdev->dev, "failed to register regulator %s\n",
0564                 info->desc.name);
0565             return PTR_ERR(rdev);
0566         }
0567     }
0568 
0569     return 0;
0570 }
0571 
0572 static const struct platform_device_id hi6421_regulator_table[] = {
0573     { .name = "hi6421-regulator" },
0574     {},
0575 };
0576 MODULE_DEVICE_TABLE(platform, hi6421_regulator_table);
0577 
0578 static struct platform_driver hi6421_regulator_driver = {
0579     .id_table = hi6421_regulator_table,
0580     .driver = {
0581         .name   = "hi6421-regulator",
0582     },
0583     .probe  = hi6421_regulator_probe,
0584 };
0585 module_platform_driver(hi6421_regulator_driver);
0586 
0587 MODULE_AUTHOR("Guodong Xu <guodong.xu@linaro.org>");
0588 MODULE_DESCRIPTION("Hi6421 regulator driver");
0589 MODULE_LICENSE("GPL v2");