linux/drivers/regulator/mcp16502.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// MCP16502 PMIC driver
   4//
   5// Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries
   6//
   7// Author: Andrei Stefanescu <andrei.stefanescu@microchip.com>
   8//
   9// Inspired from tps65086-regulator.c
  10
  11#include <linux/gpio.h>
  12#include <linux/i2c.h>
  13#include <linux/init.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/regmap.h>
  18#include <linux/regulator/driver.h>
  19#include <linux/suspend.h>
  20#include <linux/gpio/consumer.h>
  21
  22#define VDD_LOW_SEL 0x0D
  23#define VDD_HIGH_SEL 0x3F
  24
  25#define MCP16502_FLT            BIT(7)
  26#define MCP16502_DVSR           GENMASK(3, 2)
  27#define MCP16502_ENS            BIT(0)
  28
  29/*
  30 * The PMIC has four sets of registers corresponding to four power modes:
  31 * Performance, Active, Low-power, Hibernate.
  32 *
  33 * Registers:
  34 * Each regulator has a register for each power mode. To access a register
  35 * for a specific regulator and mode BASE_* and OFFSET_* need to be added.
  36 *
  37 * Operating modes:
  38 * In order for the PMIC to transition to operating modes it has to be
  39 * controlled via GPIO lines called LPM and HPM.
  40 *
  41 * The registers are fully configurable such that you can put all regulators in
  42 * a low-power state while the PMIC is in Active mode. They are supposed to be
  43 * configured at startup and then simply transition to/from a global low-power
  44 * state by setting the GPIO lpm pin high/low.
  45 *
  46 * This driver keeps the PMIC in Active mode, Low-power state is set for the
  47 * regulators by enabling/disabling operating mode (FPWM or Auto PFM).
  48 *
  49 * The PMIC's Low-power and Hibernate modes are used during standby/suspend.
  50 * To enter standby/suspend the PMIC will go to Low-power mode. From there, it
  51 * will transition to Hibernate when the PWRHLD line is set to low by the MPU.
  52 */
  53
  54/*
  55 * This function is useful for iterating over all regulators and accessing their
  56 * registers in a generic way or accessing a regulator device by its id.
  57 */
  58#define MCP16502_REG_BASE(i, r) ((((i) + 1) << 4) + MCP16502_REG_##r)
  59#define MCP16502_STAT_BASE(i) ((i) + 5)
  60
  61#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
  62#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
  63#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
  64
  65#define MCP16502_MODE_AUTO_PFM 0
  66#define MCP16502_MODE_FPWM BIT(6)
  67
  68#define MCP16502_VSEL 0x3F
  69#define MCP16502_EN BIT(7)
  70#define MCP16502_MODE BIT(6)
  71
  72#define MCP16502_MIN_REG 0x0
  73#define MCP16502_MAX_REG 0x65
  74
  75/**
  76 * enum mcp16502_reg - MCP16502 regulators's registers
  77 * @MCP16502_REG_A: active state register
  78 * @MCP16502_REG_LPM: low power mode state register
  79 * @MCP16502_REG_HIB: hibernate state register
  80 * @MCP16502_REG_SEQ: startup sequence register
  81 * @MCP16502_REG_CFG: configuration register
  82 */
  83enum mcp16502_reg {
  84        MCP16502_REG_A,
  85        MCP16502_REG_LPM,
  86        MCP16502_REG_HIB,
  87        MCP16502_REG_HPM,
  88        MCP16502_REG_SEQ,
  89        MCP16502_REG_CFG,
  90};
  91
  92/* Ramp delay (uV/us) for buck1, ldo1, ldo2. */
  93static const unsigned int mcp16502_ramp_b1l12[] = {
  94        6250, 3125, 2083, 1563
  95};
  96
  97/* Ramp delay (uV/us) for buck2, buck3, buck4. */
  98static const unsigned int mcp16502_ramp_b234[] = {
  99        3125, 1563, 1042, 781
 100};
 101
 102static unsigned int mcp16502_of_map_mode(unsigned int mode)
 103{
 104        if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
 105                return mode;
 106
 107        return REGULATOR_MODE_INVALID;
 108}
 109
 110#define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table)      \
 111        [_id] = {                                                       \
 112                .name                   = _name,                        \
 113                .regulators_node        = of_match_ptr("regulators"),   \
 114                .id                     = _id,                          \
 115                .ops                    = &(_ops),                      \
 116                .type                   = REGULATOR_VOLTAGE,            \
 117                .owner                  = THIS_MODULE,                  \
 118                .n_voltages             = MCP16502_VSEL + 1,            \
 119                .linear_ranges          = _ranges,                      \
 120                .linear_min_sel         = VDD_LOW_SEL,                  \
 121                .n_linear_ranges        = ARRAY_SIZE(_ranges),          \
 122                .of_match               = of_match_ptr(_name),          \
 123                .of_map_mode            = mcp16502_of_map_mode,         \
 124                .vsel_reg               = (((_id) + 1) << 4),           \
 125                .vsel_mask              = MCP16502_VSEL,                \
 126                .enable_reg             = (((_id) + 1) << 4),           \
 127                .enable_mask            = MCP16502_EN,                  \
 128                .ramp_reg               = MCP16502_REG_BASE(_id, CFG),  \
 129                .ramp_mask              = MCP16502_DVSR,                \
 130                .ramp_delay_table       = _ramp_table,                  \
 131                .n_ramp_values          = ARRAY_SIZE(_ramp_table),      \
 132        }
 133
 134enum {
 135        BUCK1 = 0,
 136        BUCK2,
 137        BUCK3,
 138        BUCK4,
 139        LDO1,
 140        LDO2,
 141        NUM_REGULATORS
 142};
 143
 144/*
 145 * struct mcp16502 - PMIC representation
 146 * @lpm: LPM GPIO descriptor
 147 */
 148struct mcp16502 {
 149        struct gpio_desc *lpm;
 150};
 151
 152/*
 153 * mcp16502_gpio_set_mode() - set the GPIO corresponding value
 154 *
 155 * Used to prepare transitioning into hibernate or resuming from it.
 156 */
 157static void mcp16502_gpio_set_mode(struct mcp16502 *mcp, int mode)
 158{
 159        switch (mode) {
 160        case MCP16502_OPMODE_ACTIVE:
 161                gpiod_set_value(mcp->lpm, 0);
 162                break;
 163        case MCP16502_OPMODE_LPM:
 164        case MCP16502_OPMODE_HIB:
 165                gpiod_set_value(mcp->lpm, 1);
 166                break;
 167        default:
 168                pr_err("%s: %d invalid\n", __func__, mode);
 169        }
 170}
 171
 172/*
 173 * mcp16502_get_reg() - get the PMIC's state configuration register for opmode
 174 *
 175 * @rdev: the regulator whose register we are searching
 176 * @opmode: the PMIC's operating mode ACTIVE, Low-power, Hibernate
 177 */
 178static int mcp16502_get_state_reg(struct regulator_dev *rdev, int opmode)
 179{
 180        switch (opmode) {
 181        case MCP16502_OPMODE_ACTIVE:
 182                return MCP16502_REG_BASE(rdev_get_id(rdev), A);
 183        case MCP16502_OPMODE_LPM:
 184                return MCP16502_REG_BASE(rdev_get_id(rdev), LPM);
 185        case MCP16502_OPMODE_HIB:
 186                return MCP16502_REG_BASE(rdev_get_id(rdev), HIB);
 187        default:
 188                return -EINVAL;
 189        }
 190}
 191
 192/*
 193 * mcp16502_get_mode() - return the current operating mode of a regulator
 194 *
 195 * Note: all functions that are not part of entering/exiting standby/suspend
 196 *       use the Active mode registers.
 197 *
 198 * Note: this is different from the PMIC's operatig mode, it is the
 199 *       MODE bit from the regulator's register.
 200 */
 201static unsigned int mcp16502_get_mode(struct regulator_dev *rdev)
 202{
 203        unsigned int val;
 204        int ret, reg;
 205
 206        reg = mcp16502_get_state_reg(rdev, MCP16502_OPMODE_ACTIVE);
 207        if (reg < 0)
 208                return reg;
 209
 210        ret = regmap_read(rdev->regmap, reg, &val);
 211        if (ret)
 212                return ret;
 213
 214        switch (val & MCP16502_MODE) {
 215        case MCP16502_MODE_FPWM:
 216                return REGULATOR_MODE_NORMAL;
 217        case MCP16502_MODE_AUTO_PFM:
 218                return REGULATOR_MODE_IDLE;
 219        default:
 220                return REGULATOR_MODE_INVALID;
 221        }
 222}
 223
 224/*
 225 * _mcp16502_set_mode() - helper for set_mode and set_suspend_mode
 226 *
 227 * @rdev: the regulator for which we are setting the mode
 228 * @mode: the regulator's mode (the one from MODE bit)
 229 * @opmode: the PMIC's operating mode: Active/Low-power/Hibernate
 230 */
 231static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode,
 232                              unsigned int op_mode)
 233{
 234        int val;
 235        int reg;
 236
 237        reg = mcp16502_get_state_reg(rdev, op_mode);
 238        if (reg < 0)
 239                return reg;
 240
 241        switch (mode) {
 242        case REGULATOR_MODE_NORMAL:
 243                val = MCP16502_MODE_FPWM;
 244                break;
 245        case REGULATOR_MODE_IDLE:
 246                val = MCP16502_MODE_AUTO_PFM;
 247                break;
 248        default:
 249                return -EINVAL;
 250        }
 251
 252        reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val);
 253        return reg;
 254}
 255
 256/*
 257 * mcp16502_set_mode() - regulator_ops set_mode
 258 */
 259static int mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode)
 260{
 261        return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_ACTIVE);
 262}
 263
 264/*
 265 * mcp16502_get_status() - regulator_ops get_status
 266 */
 267static int mcp16502_get_status(struct regulator_dev *rdev)
 268{
 269        int ret;
 270        unsigned int val;
 271
 272        ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)),
 273                          &val);
 274        if (ret)
 275                return ret;
 276
 277        if (val & MCP16502_FLT)
 278                return REGULATOR_STATUS_ERROR;
 279        else if (val & MCP16502_ENS)
 280                return REGULATOR_STATUS_ON;
 281        else if (!(val & MCP16502_ENS))
 282                return REGULATOR_STATUS_OFF;
 283
 284        return REGULATOR_STATUS_UNDEFINED;
 285}
 286
 287static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev,
 288                                         unsigned int old_sel,
 289                                         unsigned int new_sel)
 290{
 291        static const u8 us_ramp[] = { 8, 16, 24, 32 };
 292        int id = rdev_get_id(rdev);
 293        unsigned int uV_delta, val;
 294        int ret;
 295
 296        ret = regmap_read(rdev->regmap, MCP16502_REG_BASE(id, CFG), &val);
 297        if (ret)
 298                return ret;
 299
 300        val = (val & MCP16502_DVSR) >> 2;
 301        uV_delta = abs(new_sel * rdev->desc->linear_ranges->step -
 302                       old_sel * rdev->desc->linear_ranges->step);
 303        switch (id) {
 304        case BUCK1:
 305        case LDO1:
 306        case LDO2:
 307                ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
 308                                        mcp16502_ramp_b1l12[val]);
 309                break;
 310
 311        case BUCK2:
 312        case BUCK3:
 313        case BUCK4:
 314                ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
 315                                        mcp16502_ramp_b234[val]);
 316                break;
 317
 318        default:
 319                return -EINVAL;
 320        }
 321
 322        return ret;
 323}
 324
 325#ifdef CONFIG_SUSPEND
 326/*
 327 * mcp16502_suspend_get_target_reg() - get the reg of the target suspend PMIC
 328 *                                     mode
 329 */
 330static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev)
 331{
 332        switch (pm_suspend_target_state) {
 333        case PM_SUSPEND_STANDBY:
 334                return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_LPM);
 335        case PM_SUSPEND_ON:
 336        case PM_SUSPEND_MEM:
 337                return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_HIB);
 338        default:
 339                dev_err(&rdev->dev, "invalid suspend target: %d\n",
 340                        pm_suspend_target_state);
 341        }
 342
 343        return -EINVAL;
 344}
 345
 346/*
 347 * mcp16502_set_suspend_voltage() - regulator_ops set_suspend_voltage
 348 */
 349static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 350{
 351        int sel = regulator_map_voltage_linear_range(rdev, uV, uV);
 352        int reg = mcp16502_suspend_get_target_reg(rdev);
 353
 354        if (sel < 0)
 355                return sel;
 356
 357        if (reg < 0)
 358                return reg;
 359
 360        return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel);
 361}
 362
 363/*
 364 * mcp16502_set_suspend_mode() - regulator_ops set_suspend_mode
 365 */
 366static int mcp16502_set_suspend_mode(struct regulator_dev *rdev,
 367                                     unsigned int mode)
 368{
 369        switch (pm_suspend_target_state) {
 370        case PM_SUSPEND_STANDBY:
 371                return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_LPM);
 372        case PM_SUSPEND_ON:
 373        case PM_SUSPEND_MEM:
 374                return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_HIB);
 375        default:
 376                dev_err(&rdev->dev, "invalid suspend target: %d\n",
 377                        pm_suspend_target_state);
 378        }
 379
 380        return -EINVAL;
 381}
 382
 383/*
 384 * mcp16502_set_suspend_enable() - regulator_ops set_suspend_enable
 385 */
 386static int mcp16502_set_suspend_enable(struct regulator_dev *rdev)
 387{
 388        int reg = mcp16502_suspend_get_target_reg(rdev);
 389
 390        if (reg < 0)
 391                return reg;
 392
 393        return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN);
 394}
 395
 396/*
 397 * mcp16502_set_suspend_disable() - regulator_ops set_suspend_disable
 398 */
 399static int mcp16502_set_suspend_disable(struct regulator_dev *rdev)
 400{
 401        int reg = mcp16502_suspend_get_target_reg(rdev);
 402
 403        if (reg < 0)
 404                return reg;
 405
 406        return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0);
 407}
 408#endif /* CONFIG_SUSPEND */
 409
 410static const struct regulator_ops mcp16502_buck_ops = {
 411        .list_voltage                   = regulator_list_voltage_linear_range,
 412        .map_voltage                    = regulator_map_voltage_linear_range,
 413        .get_voltage_sel                = regulator_get_voltage_sel_regmap,
 414        .set_voltage_sel                = regulator_set_voltage_sel_regmap,
 415        .enable                         = regulator_enable_regmap,
 416        .disable                        = regulator_disable_regmap,
 417        .is_enabled                     = regulator_is_enabled_regmap,
 418        .get_status                     = mcp16502_get_status,
 419        .set_voltage_time_sel           = mcp16502_set_voltage_time_sel,
 420        .set_ramp_delay                 = regulator_set_ramp_delay_regmap,
 421
 422        .set_mode                       = mcp16502_set_mode,
 423        .get_mode                       = mcp16502_get_mode,
 424
 425#ifdef CONFIG_SUSPEND
 426        .set_suspend_voltage            = mcp16502_set_suspend_voltage,
 427        .set_suspend_mode               = mcp16502_set_suspend_mode,
 428        .set_suspend_enable             = mcp16502_set_suspend_enable,
 429        .set_suspend_disable            = mcp16502_set_suspend_disable,
 430#endif /* CONFIG_SUSPEND */
 431};
 432
 433/*
 434 * LDOs cannot change operating modes.
 435 */
 436static const struct regulator_ops mcp16502_ldo_ops = {
 437        .list_voltage                   = regulator_list_voltage_linear_range,
 438        .map_voltage                    = regulator_map_voltage_linear_range,
 439        .get_voltage_sel                = regulator_get_voltage_sel_regmap,
 440        .set_voltage_sel                = regulator_set_voltage_sel_regmap,
 441        .enable                         = regulator_enable_regmap,
 442        .disable                        = regulator_disable_regmap,
 443        .is_enabled                     = regulator_is_enabled_regmap,
 444        .get_status                     = mcp16502_get_status,
 445        .set_voltage_time_sel           = mcp16502_set_voltage_time_sel,
 446        .set_ramp_delay                 = regulator_set_ramp_delay_regmap,
 447
 448#ifdef CONFIG_SUSPEND
 449        .set_suspend_voltage            = mcp16502_set_suspend_voltage,
 450        .set_suspend_enable             = mcp16502_set_suspend_enable,
 451        .set_suspend_disable            = mcp16502_set_suspend_disable,
 452#endif /* CONFIG_SUSPEND */
 453};
 454
 455static const struct of_device_id mcp16502_ids[] = {
 456        { .compatible = "microchip,mcp16502", },
 457        {}
 458};
 459MODULE_DEVICE_TABLE(of, mcp16502_ids);
 460
 461static const struct linear_range b1l12_ranges[] = {
 462        REGULATOR_LINEAR_RANGE(1200000, VDD_LOW_SEL, VDD_HIGH_SEL, 50000),
 463};
 464
 465static const struct linear_range b234_ranges[] = {
 466        REGULATOR_LINEAR_RANGE(600000, VDD_LOW_SEL, VDD_HIGH_SEL, 25000),
 467};
 468
 469static const struct regulator_desc mcp16502_desc[] = {
 470        /* MCP16502_REGULATOR(_name, _id, ranges, regulator_ops, ramp_table) */
 471        MCP16502_REGULATOR("VDD_IO", BUCK1, b1l12_ranges, mcp16502_buck_ops,
 472                           mcp16502_ramp_b1l12),
 473        MCP16502_REGULATOR("VDD_DDR", BUCK2, b234_ranges, mcp16502_buck_ops,
 474                           mcp16502_ramp_b234),
 475        MCP16502_REGULATOR("VDD_CORE", BUCK3, b234_ranges, mcp16502_buck_ops,
 476                           mcp16502_ramp_b234),
 477        MCP16502_REGULATOR("VDD_OTHER", BUCK4, b234_ranges, mcp16502_buck_ops,
 478                           mcp16502_ramp_b234),
 479        MCP16502_REGULATOR("LDO1", LDO1, b1l12_ranges, mcp16502_ldo_ops,
 480                           mcp16502_ramp_b1l12),
 481        MCP16502_REGULATOR("LDO2", LDO2, b1l12_ranges, mcp16502_ldo_ops,
 482                           mcp16502_ramp_b1l12)
 483};
 484
 485static const struct regmap_range mcp16502_ranges[] = {
 486        regmap_reg_range(MCP16502_MIN_REG, MCP16502_MAX_REG)
 487};
 488
 489static const struct regmap_access_table mcp16502_yes_reg_table = {
 490        .yes_ranges = mcp16502_ranges,
 491        .n_yes_ranges = ARRAY_SIZE(mcp16502_ranges),
 492};
 493
 494static const struct regmap_config mcp16502_regmap_config = {
 495        .reg_bits       = 8,
 496        .val_bits       = 8,
 497        .max_register   = MCP16502_MAX_REG,
 498        .cache_type     = REGCACHE_NONE,
 499        .rd_table       = &mcp16502_yes_reg_table,
 500        .wr_table       = &mcp16502_yes_reg_table,
 501};
 502
 503static int mcp16502_probe(struct i2c_client *client)
 504{
 505        struct regulator_config config = { };
 506        struct regulator_dev *rdev;
 507        struct device *dev;
 508        struct mcp16502 *mcp;
 509        struct regmap *rmap;
 510        int i, ret;
 511
 512        dev = &client->dev;
 513        config.dev = dev;
 514
 515        mcp = devm_kzalloc(dev, sizeof(*mcp), GFP_KERNEL);
 516        if (!mcp)
 517                return -ENOMEM;
 518
 519        rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
 520        if (IS_ERR(rmap)) {
 521                ret = PTR_ERR(rmap);
 522                dev_err(dev, "regmap init failed: %d\n", ret);
 523                return ret;
 524        }
 525
 526        i2c_set_clientdata(client, mcp);
 527        config.regmap = rmap;
 528        config.driver_data = mcp;
 529
 530        mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
 531        if (IS_ERR(mcp->lpm)) {
 532                dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
 533                return PTR_ERR(mcp->lpm);
 534        }
 535
 536        for (i = 0; i < NUM_REGULATORS; i++) {
 537                rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
 538                if (IS_ERR(rdev)) {
 539                        dev_err(dev,
 540                                "failed to register %s regulator %ld\n",
 541                                mcp16502_desc[i].name, PTR_ERR(rdev));
 542                        return PTR_ERR(rdev);
 543                }
 544        }
 545
 546        mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
 547
 548        return 0;
 549}
 550
 551#ifdef CONFIG_PM_SLEEP
 552static int mcp16502_suspend_noirq(struct device *dev)
 553{
 554        struct i2c_client *client = to_i2c_client(dev);
 555        struct mcp16502 *mcp = i2c_get_clientdata(client);
 556
 557        mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
 558
 559        return 0;
 560}
 561
 562static int mcp16502_resume_noirq(struct device *dev)
 563{
 564        struct i2c_client *client = to_i2c_client(dev);
 565        struct mcp16502 *mcp = i2c_get_clientdata(client);
 566
 567        mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
 568
 569        return 0;
 570}
 571#endif
 572
 573#ifdef CONFIG_PM
 574static const struct dev_pm_ops mcp16502_pm_ops = {
 575        SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
 576                                      mcp16502_resume_noirq)
 577};
 578#endif
 579static const struct i2c_device_id mcp16502_i2c_id[] = {
 580        { "mcp16502", 0 },
 581        { }
 582};
 583MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
 584
 585static struct i2c_driver mcp16502_drv = {
 586        .probe_new      = mcp16502_probe,
 587        .driver         = {
 588                .name   = "mcp16502-regulator",
 589                .of_match_table = of_match_ptr(mcp16502_ids),
 590#ifdef CONFIG_PM
 591                .pm = &mcp16502_pm_ops,
 592#endif
 593        },
 594        .id_table       = mcp16502_i2c_id,
 595};
 596
 597module_i2c_driver(mcp16502_drv);
 598
 599MODULE_LICENSE("GPL v2");
 600MODULE_DESCRIPTION("MCP16502 PMIC driver");
 601MODULE_AUTHOR("Andrei Stefanescu andrei.stefanescu@microchip.com");
 602