0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/gpio.h>
0012 #include <linux/i2c.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/regmap.h>
0018 #include <linux/regulator/driver.h>
0019 #include <linux/suspend.h>
0020 #include <linux/gpio/consumer.h>
0021
0022 #define VDD_LOW_SEL 0x0D
0023 #define VDD_HIGH_SEL 0x3F
0024
0025 #define MCP16502_FLT BIT(7)
0026 #define MCP16502_DVSR GENMASK(3, 2)
0027 #define MCP16502_ENS BIT(0)
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #define MCP16502_REG_BASE(i, r) ((((i) + 1) << 4) + MCP16502_REG_##r)
0059 #define MCP16502_STAT_BASE(i) ((i) + 5)
0060
0061 #define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
0062 #define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
0063 #define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
0064
0065 #define MCP16502_MODE_AUTO_PFM 0
0066 #define MCP16502_MODE_FPWM BIT(6)
0067
0068 #define MCP16502_VSEL 0x3F
0069 #define MCP16502_EN BIT(7)
0070 #define MCP16502_MODE BIT(6)
0071
0072 #define MCP16502_MIN_REG 0x0
0073 #define MCP16502_MAX_REG 0x65
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 enum mcp16502_reg {
0084 MCP16502_REG_A,
0085 MCP16502_REG_LPM,
0086 MCP16502_REG_HIB,
0087 MCP16502_REG_HPM,
0088 MCP16502_REG_SEQ,
0089 MCP16502_REG_CFG,
0090 };
0091
0092
0093 static const unsigned int mcp16502_ramp_b1l12[] = {
0094 6250, 3125, 2083, 1563
0095 };
0096
0097
0098 static const unsigned int mcp16502_ramp_b234[] = {
0099 3125, 1563, 1042, 781
0100 };
0101
0102 static unsigned int mcp16502_of_map_mode(unsigned int mode)
0103 {
0104 if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
0105 return mode;
0106
0107 return REGULATOR_MODE_INVALID;
0108 }
0109
0110 #define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table) \
0111 [_id] = { \
0112 .name = _name, \
0113 .regulators_node = of_match_ptr("regulators"), \
0114 .id = _id, \
0115 .ops = &(_ops), \
0116 .type = REGULATOR_VOLTAGE, \
0117 .owner = THIS_MODULE, \
0118 .n_voltages = MCP16502_VSEL + 1, \
0119 .linear_ranges = _ranges, \
0120 .linear_min_sel = VDD_LOW_SEL, \
0121 .n_linear_ranges = ARRAY_SIZE(_ranges), \
0122 .of_match = of_match_ptr(_name), \
0123 .of_map_mode = mcp16502_of_map_mode, \
0124 .vsel_reg = (((_id) + 1) << 4), \
0125 .vsel_mask = MCP16502_VSEL, \
0126 .enable_reg = (((_id) + 1) << 4), \
0127 .enable_mask = MCP16502_EN, \
0128 .ramp_reg = MCP16502_REG_BASE(_id, CFG), \
0129 .ramp_mask = MCP16502_DVSR, \
0130 .ramp_delay_table = _ramp_table, \
0131 .n_ramp_values = ARRAY_SIZE(_ramp_table), \
0132 }
0133
0134 enum {
0135 BUCK1 = 0,
0136 BUCK2,
0137 BUCK3,
0138 BUCK4,
0139 LDO1,
0140 LDO2,
0141 NUM_REGULATORS
0142 };
0143
0144
0145
0146
0147
0148 struct mcp16502 {
0149 struct gpio_desc *lpm;
0150 };
0151
0152
0153
0154
0155
0156
0157 static void mcp16502_gpio_set_mode(struct mcp16502 *mcp, int mode)
0158 {
0159 switch (mode) {
0160 case MCP16502_OPMODE_ACTIVE:
0161 gpiod_set_value(mcp->lpm, 0);
0162 break;
0163 case MCP16502_OPMODE_LPM:
0164 case MCP16502_OPMODE_HIB:
0165 gpiod_set_value(mcp->lpm, 1);
0166 break;
0167 default:
0168 pr_err("%s: %d invalid\n", __func__, mode);
0169 }
0170 }
0171
0172
0173
0174
0175
0176
0177
0178 static int mcp16502_get_state_reg(struct regulator_dev *rdev, int opmode)
0179 {
0180 switch (opmode) {
0181 case MCP16502_OPMODE_ACTIVE:
0182 return MCP16502_REG_BASE(rdev_get_id(rdev), A);
0183 case MCP16502_OPMODE_LPM:
0184 return MCP16502_REG_BASE(rdev_get_id(rdev), LPM);
0185 case MCP16502_OPMODE_HIB:
0186 return MCP16502_REG_BASE(rdev_get_id(rdev), HIB);
0187 default:
0188 return -EINVAL;
0189 }
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 static unsigned int mcp16502_get_mode(struct regulator_dev *rdev)
0202 {
0203 unsigned int val;
0204 int ret, reg;
0205
0206 reg = mcp16502_get_state_reg(rdev, MCP16502_OPMODE_ACTIVE);
0207 if (reg < 0)
0208 return reg;
0209
0210 ret = regmap_read(rdev->regmap, reg, &val);
0211 if (ret)
0212 return ret;
0213
0214 switch (val & MCP16502_MODE) {
0215 case MCP16502_MODE_FPWM:
0216 return REGULATOR_MODE_NORMAL;
0217 case MCP16502_MODE_AUTO_PFM:
0218 return REGULATOR_MODE_IDLE;
0219 default:
0220 return REGULATOR_MODE_INVALID;
0221 }
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231 static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode,
0232 unsigned int op_mode)
0233 {
0234 int val;
0235 int reg;
0236
0237 reg = mcp16502_get_state_reg(rdev, op_mode);
0238 if (reg < 0)
0239 return reg;
0240
0241 switch (mode) {
0242 case REGULATOR_MODE_NORMAL:
0243 val = MCP16502_MODE_FPWM;
0244 break;
0245 case REGULATOR_MODE_IDLE:
0246 val = MCP16502_MODE_AUTO_PFM;
0247 break;
0248 default:
0249 return -EINVAL;
0250 }
0251
0252 reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val);
0253 return reg;
0254 }
0255
0256
0257
0258
0259 static int mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode)
0260 {
0261 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_ACTIVE);
0262 }
0263
0264
0265
0266
0267 static int mcp16502_get_status(struct regulator_dev *rdev)
0268 {
0269 int ret;
0270 unsigned int val;
0271
0272 ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)),
0273 &val);
0274 if (ret)
0275 return ret;
0276
0277 if (val & MCP16502_FLT)
0278 return REGULATOR_STATUS_ERROR;
0279 else if (val & MCP16502_ENS)
0280 return REGULATOR_STATUS_ON;
0281 else if (!(val & MCP16502_ENS))
0282 return REGULATOR_STATUS_OFF;
0283
0284 return REGULATOR_STATUS_UNDEFINED;
0285 }
0286
0287 static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev,
0288 unsigned int old_sel,
0289 unsigned int new_sel)
0290 {
0291 static const u8 us_ramp[] = { 8, 16, 24, 32 };
0292 int id = rdev_get_id(rdev);
0293 unsigned int uV_delta, val;
0294 int ret;
0295
0296 ret = regmap_read(rdev->regmap, MCP16502_REG_BASE(id, CFG), &val);
0297 if (ret)
0298 return ret;
0299
0300 val = (val & MCP16502_DVSR) >> 2;
0301 uV_delta = abs(new_sel * rdev->desc->linear_ranges->step -
0302 old_sel * rdev->desc->linear_ranges->step);
0303 switch (id) {
0304 case BUCK1:
0305 case LDO1:
0306 case LDO2:
0307 ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
0308 mcp16502_ramp_b1l12[val]);
0309 break;
0310
0311 case BUCK2:
0312 case BUCK3:
0313 case BUCK4:
0314 ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
0315 mcp16502_ramp_b234[val]);
0316 break;
0317
0318 default:
0319 return -EINVAL;
0320 }
0321
0322 return ret;
0323 }
0324
0325 #ifdef CONFIG_SUSPEND
0326
0327
0328
0329
0330 static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev)
0331 {
0332 switch (pm_suspend_target_state) {
0333 case PM_SUSPEND_STANDBY:
0334 return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_LPM);
0335 case PM_SUSPEND_ON:
0336 case PM_SUSPEND_MEM:
0337 return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_HIB);
0338 default:
0339 dev_err(&rdev->dev, "invalid suspend target: %d\n",
0340 pm_suspend_target_state);
0341 }
0342
0343 return -EINVAL;
0344 }
0345
0346
0347
0348
0349 static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV)
0350 {
0351 int sel = regulator_map_voltage_linear_range(rdev, uV, uV);
0352 int reg = mcp16502_suspend_get_target_reg(rdev);
0353
0354 if (sel < 0)
0355 return sel;
0356
0357 if (reg < 0)
0358 return reg;
0359
0360 return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel);
0361 }
0362
0363
0364
0365
0366 static int mcp16502_set_suspend_mode(struct regulator_dev *rdev,
0367 unsigned int mode)
0368 {
0369 switch (pm_suspend_target_state) {
0370 case PM_SUSPEND_STANDBY:
0371 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_LPM);
0372 case PM_SUSPEND_ON:
0373 case PM_SUSPEND_MEM:
0374 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_HIB);
0375 default:
0376 dev_err(&rdev->dev, "invalid suspend target: %d\n",
0377 pm_suspend_target_state);
0378 }
0379
0380 return -EINVAL;
0381 }
0382
0383
0384
0385
0386 static int mcp16502_set_suspend_enable(struct regulator_dev *rdev)
0387 {
0388 int reg = mcp16502_suspend_get_target_reg(rdev);
0389
0390 if (reg < 0)
0391 return reg;
0392
0393 return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN);
0394 }
0395
0396
0397
0398
0399 static int mcp16502_set_suspend_disable(struct regulator_dev *rdev)
0400 {
0401 int reg = mcp16502_suspend_get_target_reg(rdev);
0402
0403 if (reg < 0)
0404 return reg;
0405
0406 return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0);
0407 }
0408 #endif
0409
0410 static const struct regulator_ops mcp16502_buck_ops = {
0411 .list_voltage = regulator_list_voltage_linear_range,
0412 .map_voltage = regulator_map_voltage_linear_range,
0413 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0414 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0415 .enable = regulator_enable_regmap,
0416 .disable = regulator_disable_regmap,
0417 .is_enabled = regulator_is_enabled_regmap,
0418 .get_status = mcp16502_get_status,
0419 .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
0420 .set_ramp_delay = regulator_set_ramp_delay_regmap,
0421
0422 .set_mode = mcp16502_set_mode,
0423 .get_mode = mcp16502_get_mode,
0424
0425 #ifdef CONFIG_SUSPEND
0426 .set_suspend_voltage = mcp16502_set_suspend_voltage,
0427 .set_suspend_mode = mcp16502_set_suspend_mode,
0428 .set_suspend_enable = mcp16502_set_suspend_enable,
0429 .set_suspend_disable = mcp16502_set_suspend_disable,
0430 #endif
0431 };
0432
0433
0434
0435
0436 static const struct regulator_ops mcp16502_ldo_ops = {
0437 .list_voltage = regulator_list_voltage_linear_range,
0438 .map_voltage = regulator_map_voltage_linear_range,
0439 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0440 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0441 .enable = regulator_enable_regmap,
0442 .disable = regulator_disable_regmap,
0443 .is_enabled = regulator_is_enabled_regmap,
0444 .get_status = mcp16502_get_status,
0445 .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
0446 .set_ramp_delay = regulator_set_ramp_delay_regmap,
0447
0448 #ifdef CONFIG_SUSPEND
0449 .set_suspend_voltage = mcp16502_set_suspend_voltage,
0450 .set_suspend_enable = mcp16502_set_suspend_enable,
0451 .set_suspend_disable = mcp16502_set_suspend_disable,
0452 #endif
0453 };
0454
0455 static const struct of_device_id mcp16502_ids[] = {
0456 { .compatible = "microchip,mcp16502", },
0457 {}
0458 };
0459 MODULE_DEVICE_TABLE(of, mcp16502_ids);
0460
0461 static const struct linear_range b1l12_ranges[] = {
0462 REGULATOR_LINEAR_RANGE(1200000, VDD_LOW_SEL, VDD_HIGH_SEL, 50000),
0463 };
0464
0465 static const struct linear_range b234_ranges[] = {
0466 REGULATOR_LINEAR_RANGE(600000, VDD_LOW_SEL, VDD_HIGH_SEL, 25000),
0467 };
0468
0469 static const struct regulator_desc mcp16502_desc[] = {
0470
0471 MCP16502_REGULATOR("VDD_IO", BUCK1, b1l12_ranges, mcp16502_buck_ops,
0472 mcp16502_ramp_b1l12),
0473 MCP16502_REGULATOR("VDD_DDR", BUCK2, b234_ranges, mcp16502_buck_ops,
0474 mcp16502_ramp_b234),
0475 MCP16502_REGULATOR("VDD_CORE", BUCK3, b234_ranges, mcp16502_buck_ops,
0476 mcp16502_ramp_b234),
0477 MCP16502_REGULATOR("VDD_OTHER", BUCK4, b234_ranges, mcp16502_buck_ops,
0478 mcp16502_ramp_b234),
0479 MCP16502_REGULATOR("LDO1", LDO1, b1l12_ranges, mcp16502_ldo_ops,
0480 mcp16502_ramp_b1l12),
0481 MCP16502_REGULATOR("LDO2", LDO2, b1l12_ranges, mcp16502_ldo_ops,
0482 mcp16502_ramp_b1l12)
0483 };
0484
0485 static const struct regmap_range mcp16502_ranges[] = {
0486 regmap_reg_range(MCP16502_MIN_REG, MCP16502_MAX_REG)
0487 };
0488
0489 static const struct regmap_access_table mcp16502_yes_reg_table = {
0490 .yes_ranges = mcp16502_ranges,
0491 .n_yes_ranges = ARRAY_SIZE(mcp16502_ranges),
0492 };
0493
0494 static const struct regmap_config mcp16502_regmap_config = {
0495 .reg_bits = 8,
0496 .val_bits = 8,
0497 .max_register = MCP16502_MAX_REG,
0498 .cache_type = REGCACHE_NONE,
0499 .rd_table = &mcp16502_yes_reg_table,
0500 .wr_table = &mcp16502_yes_reg_table,
0501 };
0502
0503 static int mcp16502_probe(struct i2c_client *client)
0504 {
0505 struct regulator_config config = { };
0506 struct regulator_dev *rdev;
0507 struct device *dev;
0508 struct mcp16502 *mcp;
0509 struct regmap *rmap;
0510 int i, ret;
0511
0512 dev = &client->dev;
0513 config.dev = dev;
0514
0515 mcp = devm_kzalloc(dev, sizeof(*mcp), GFP_KERNEL);
0516 if (!mcp)
0517 return -ENOMEM;
0518
0519 rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
0520 if (IS_ERR(rmap)) {
0521 ret = PTR_ERR(rmap);
0522 dev_err(dev, "regmap init failed: %d\n", ret);
0523 return ret;
0524 }
0525
0526 i2c_set_clientdata(client, mcp);
0527 config.regmap = rmap;
0528 config.driver_data = mcp;
0529
0530 mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
0531 if (IS_ERR(mcp->lpm)) {
0532 dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
0533 return PTR_ERR(mcp->lpm);
0534 }
0535
0536 for (i = 0; i < NUM_REGULATORS; i++) {
0537 rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
0538 if (IS_ERR(rdev)) {
0539 dev_err(dev,
0540 "failed to register %s regulator %ld\n",
0541 mcp16502_desc[i].name, PTR_ERR(rdev));
0542 return PTR_ERR(rdev);
0543 }
0544 }
0545
0546 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
0547
0548 return 0;
0549 }
0550
0551 #ifdef CONFIG_PM_SLEEP
0552 static int mcp16502_suspend_noirq(struct device *dev)
0553 {
0554 struct i2c_client *client = to_i2c_client(dev);
0555 struct mcp16502 *mcp = i2c_get_clientdata(client);
0556
0557 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
0558
0559 return 0;
0560 }
0561
0562 static int mcp16502_resume_noirq(struct device *dev)
0563 {
0564 struct i2c_client *client = to_i2c_client(dev);
0565 struct mcp16502 *mcp = i2c_get_clientdata(client);
0566
0567 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
0568
0569 return 0;
0570 }
0571 #endif
0572
0573 #ifdef CONFIG_PM
0574 static const struct dev_pm_ops mcp16502_pm_ops = {
0575 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
0576 mcp16502_resume_noirq)
0577 };
0578 #endif
0579 static const struct i2c_device_id mcp16502_i2c_id[] = {
0580 { "mcp16502", 0 },
0581 { }
0582 };
0583 MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
0584
0585 static struct i2c_driver mcp16502_drv = {
0586 .probe_new = mcp16502_probe,
0587 .driver = {
0588 .name = "mcp16502-regulator",
0589 .of_match_table = of_match_ptr(mcp16502_ids),
0590 #ifdef CONFIG_PM
0591 .pm = &mcp16502_pm_ops,
0592 #endif
0593 },
0594 .id_table = mcp16502_i2c_id,
0595 };
0596
0597 module_i2c_driver(mcp16502_drv);
0598
0599 MODULE_LICENSE("GPL v2");
0600 MODULE_DESCRIPTION("MCP16502 PMIC driver");
0601 MODULE_AUTHOR("Andrei Stefanescu andrei.stefanescu@microchip.com");