0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0026
0027
0028 struct hi6421_regulator_pdata {
0029 struct mutex lock;
0030 };
0031
0032
0033
0034
0035
0036
0037
0038 struct hi6421_regulator_info {
0039 struct regulator_desc desc;
0040 u8 mode_mask;
0041 u32 eco_microamp;
0042 };
0043
0044
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
0078 static const unsigned int ldo_0_voltages[] = {
0079 1500000, 1800000, 2400000, 2500000,
0080 2600000, 2700000, 2850000, 3000000,
0081 };
0082
0083
0084 static const unsigned int ldo_8_voltages[] = {
0085 1500000, 1800000, 2400000, 2600000,
0086 2700000, 2850000, 3000000, 3300000,
0087 };
0088
0089
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
0119
0120
0121
0122
0123
0124
0125
0126
0127
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
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
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
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
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
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
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
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
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
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
0372
0373
0374
0375
0376 mutex_lock(&pdata->lock);
0377
0378
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, ®_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, ®_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
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
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
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");