linux/drivers/regulator/qcom-rpmh-regulator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2018, The Linux Foundation. All rights reserved.
   3
   4#define pr_fmt(fmt) "%s: " fmt, __func__
   5
   6#include <linux/err.h>
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/of.h>
  10#include <linux/of_device.h>
  11#include <linux/platform_device.h>
  12#include <linux/slab.h>
  13#include <linux/string.h>
  14#include <linux/regulator/driver.h>
  15#include <linux/regulator/machine.h>
  16#include <linux/regulator/of_regulator.h>
  17
  18#include <soc/qcom/cmd-db.h>
  19#include <soc/qcom/rpmh.h>
  20
  21#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
  22
  23/**
  24 * enum rpmh_regulator_type - supported RPMh accelerator types
  25 * %VRM:        RPMh VRM accelerator which supports voting on enable, voltage,
  26 *              and mode of LDO, SMPS, and BOB type PMIC regulators.
  27 * %XOB:        RPMh XOB accelerator which supports voting on the enable state
  28 *              of PMIC regulators.
  29 */
  30enum rpmh_regulator_type {
  31        VRM,
  32        XOB,
  33};
  34
  35#define RPMH_REGULATOR_REG_VRM_VOLTAGE          0x0
  36#define RPMH_REGULATOR_REG_ENABLE               0x4
  37#define RPMH_REGULATOR_REG_VRM_MODE             0x8
  38
  39#define PMIC4_LDO_MODE_RETENTION                4
  40#define PMIC4_LDO_MODE_LPM                      5
  41#define PMIC4_LDO_MODE_HPM                      7
  42
  43#define PMIC4_SMPS_MODE_RETENTION               4
  44#define PMIC4_SMPS_MODE_PFM                     5
  45#define PMIC4_SMPS_MODE_AUTO                    6
  46#define PMIC4_SMPS_MODE_PWM                     7
  47
  48#define PMIC4_BOB_MODE_PASS                     0
  49#define PMIC4_BOB_MODE_PFM                      1
  50#define PMIC4_BOB_MODE_AUTO                     2
  51#define PMIC4_BOB_MODE_PWM                      3
  52
  53/**
  54 * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
  55 * @regulator_type:             RPMh accelerator type used to manage this
  56 *                              regulator
  57 * @ops:                        Pointer to regulator ops callback structure
  58 * @voltage_range:              The single range of voltages supported by this
  59 *                              PMIC regulator type
  60 * @n_voltages:                 The number of unique voltage set points defined
  61 *                              by voltage_range
  62 * @hpm_min_load_uA:            Minimum load current in microamps that requires
  63 *                              high power mode (HPM) operation.  This is used
  64 *                              for LDO hardware type regulators only.
  65 * @pmic_mode_map:              Array indexed by regulator framework mode
  66 *                              containing PMIC hardware modes.  Must be large
  67 *                              enough to index all framework modes supported
  68 *                              by this regulator hardware type.
  69 * @of_map_mode:                Maps an RPMH_REGULATOR_MODE_* mode value defined
  70 *                              in device tree to a regulator framework mode
  71 */
  72struct rpmh_vreg_hw_data {
  73        enum rpmh_regulator_type                regulator_type;
  74        const struct regulator_ops              *ops;
  75        const struct regulator_linear_range     voltage_range;
  76        int                                     n_voltages;
  77        int                                     hpm_min_load_uA;
  78        const int                               *pmic_mode_map;
  79        unsigned int                          (*of_map_mode)(unsigned int mode);
  80};
  81
  82/**
  83 * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
  84 *              single regulator device
  85 * @dev:                        Device pointer for the top-level PMIC RPMh
  86 *                              regulator parent device.  This is used as a
  87 *                              handle in RPMh write requests.
  88 * @addr:                       Base address of the regulator resource within
  89 *                              an RPMh accelerator
  90 * @rdesc:                      Regulator descriptor
  91 * @hw_data:                    PMIC regulator configuration data for this RPMh
  92 *                              regulator
  93 * @always_wait_for_ack:        Boolean flag indicating if a request must always
  94 *                              wait for an ACK from RPMh before continuing even
  95 *                              if it corresponds to a strictly lower power
  96 *                              state (e.g. enabled --> disabled).
  97 * @enabled:                    Flag indicating if the regulator is enabled or
  98 *                              not
  99 * @bypassed:                   Boolean indicating if the regulator is in
 100 *                              bypass (pass-through) mode or not.  This is
 101 *                              only used by BOB rpmh-regulator resources.
 102 * @voltage_selector:           Selector used for get_voltage_sel() and
 103 *                              set_voltage_sel() callbacks
 104 * @mode:                       RPMh VRM regulator current framework mode
 105 */
 106struct rpmh_vreg {
 107        struct device                   *dev;
 108        u32                             addr;
 109        struct regulator_desc           rdesc;
 110        const struct rpmh_vreg_hw_data  *hw_data;
 111        bool                            always_wait_for_ack;
 112
 113        int                             enabled;
 114        bool                            bypassed;
 115        int                             voltage_selector;
 116        unsigned int                    mode;
 117};
 118
 119/**
 120 * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
 121 * @name:                       Name for the regulator which also corresponds
 122 *                              to the device tree subnode name of the regulator
 123 * @resource_name:              RPMh regulator resource name format string.
 124 *                              This must include exactly one field: '%s' which
 125 *                              is filled at run-time with the PMIC ID provided
 126 *                              by device tree property qcom,pmic-id.  Example:
 127 *                              "ldo%s1" for RPMh resource "ldoa1".
 128 * @supply_name:                Parent supply regulator name
 129 * @hw_data:                    Configuration data for this PMIC regulator type
 130 */
 131struct rpmh_vreg_init_data {
 132        const char                      *name;
 133        const char                      *resource_name;
 134        const char                      *supply_name;
 135        const struct rpmh_vreg_hw_data  *hw_data;
 136};
 137
 138/**
 139 * rpmh_regulator_send_request() - send the request to RPMh
 140 * @vreg:               Pointer to the RPMh regulator
 141 * @cmd:                Pointer to the RPMh command to send
 142 * @wait_for_ack:       Boolean indicating if execution must wait until the
 143 *                      request has been acknowledged as complete
 144 *
 145 * Return: 0 on success, errno on failure
 146 */
 147static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
 148                        struct tcs_cmd *cmd, bool wait_for_ack)
 149{
 150        int ret;
 151
 152        if (wait_for_ack || vreg->always_wait_for_ack)
 153                ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
 154        else
 155                ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
 156                                        1);
 157
 158        return ret;
 159}
 160
 161static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
 162                                unsigned int selector, bool wait_for_ack)
 163{
 164        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 165        struct tcs_cmd cmd = {
 166                .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
 167        };
 168        int ret;
 169
 170        /* VRM voltage control register is set with voltage in millivolts. */
 171        cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
 172                                                        selector), 1000);
 173
 174        ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
 175        if (!ret)
 176                vreg->voltage_selector = selector;
 177
 178        return ret;
 179}
 180
 181static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
 182                                        unsigned int selector)
 183{
 184        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 185
 186        if (vreg->enabled == -EINVAL) {
 187                /*
 188                 * Cache the voltage and send it later when the regulator is
 189                 * enabled or disabled.
 190                 */
 191                vreg->voltage_selector = selector;
 192                return 0;
 193        }
 194
 195        return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
 196                                        selector > vreg->voltage_selector);
 197}
 198
 199static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
 200{
 201        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 202
 203        return vreg->voltage_selector;
 204}
 205
 206static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
 207{
 208        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 209
 210        return vreg->enabled;
 211}
 212
 213static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
 214                                        bool enable)
 215{
 216        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 217        struct tcs_cmd cmd = {
 218                .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
 219                .data = enable,
 220        };
 221        int ret;
 222
 223        if (vreg->enabled == -EINVAL &&
 224            vreg->voltage_selector != -ENOTRECOVERABLE) {
 225                ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
 226                                                vreg->voltage_selector, true);
 227                if (ret < 0)
 228                        return ret;
 229        }
 230
 231        ret = rpmh_regulator_send_request(vreg, &cmd, enable);
 232        if (!ret)
 233                vreg->enabled = enable;
 234
 235        return ret;
 236}
 237
 238static int rpmh_regulator_enable(struct regulator_dev *rdev)
 239{
 240        return rpmh_regulator_set_enable_state(rdev, true);
 241}
 242
 243static int rpmh_regulator_disable(struct regulator_dev *rdev)
 244{
 245        return rpmh_regulator_set_enable_state(rdev, false);
 246}
 247
 248static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
 249                                        unsigned int mode, bool bypassed)
 250{
 251        struct tcs_cmd cmd = {
 252                .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
 253        };
 254        int pmic_mode;
 255
 256        if (mode > REGULATOR_MODE_STANDBY)
 257                return -EINVAL;
 258
 259        pmic_mode = vreg->hw_data->pmic_mode_map[mode];
 260        if (pmic_mode < 0)
 261                return pmic_mode;
 262
 263        if (bypassed)
 264                cmd.data = PMIC4_BOB_MODE_PASS;
 265        else
 266                cmd.data = pmic_mode;
 267
 268        return rpmh_regulator_send_request(vreg, &cmd, true);
 269}
 270
 271static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
 272                                        unsigned int mode)
 273{
 274        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 275        int ret;
 276
 277        if (mode == vreg->mode)
 278                return 0;
 279
 280        ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
 281        if (!ret)
 282                vreg->mode = mode;
 283
 284        return ret;
 285}
 286
 287static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
 288{
 289        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 290
 291        return vreg->mode;
 292}
 293
 294/**
 295 * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
 296 *              current requested
 297 * @rdev:               Regulator device pointer for the rpmh-regulator
 298 * @load_uA:            Aggregated load current in microamps
 299 *
 300 * This function is used in the regulator_ops for VRM type RPMh regulator
 301 * devices.
 302 *
 303 * Return: 0 on success, errno on failure
 304 */
 305static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
 306{
 307        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 308        unsigned int mode;
 309
 310        if (load_uA >= vreg->hw_data->hpm_min_load_uA)
 311                mode = REGULATOR_MODE_NORMAL;
 312        else
 313                mode = REGULATOR_MODE_IDLE;
 314
 315        return rpmh_regulator_vrm_set_mode(rdev, mode);
 316}
 317
 318static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
 319                                bool enable)
 320{
 321        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 322        int ret;
 323
 324        if (vreg->bypassed == enable)
 325                return 0;
 326
 327        ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
 328        if (!ret)
 329                vreg->bypassed = enable;
 330
 331        return ret;
 332}
 333
 334static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
 335                                bool *enable)
 336{
 337        struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
 338
 339        *enable = vreg->bypassed;
 340
 341        return 0;
 342}
 343
 344static const struct regulator_ops rpmh_regulator_vrm_ops = {
 345        .enable                 = rpmh_regulator_enable,
 346        .disable                = rpmh_regulator_disable,
 347        .is_enabled             = rpmh_regulator_is_enabled,
 348        .set_voltage_sel        = rpmh_regulator_vrm_set_voltage_sel,
 349        .get_voltage_sel        = rpmh_regulator_vrm_get_voltage_sel,
 350        .list_voltage           = regulator_list_voltage_linear_range,
 351        .set_mode               = rpmh_regulator_vrm_set_mode,
 352        .get_mode               = rpmh_regulator_vrm_get_mode,
 353};
 354
 355static const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
 356        .enable                 = rpmh_regulator_enable,
 357        .disable                = rpmh_regulator_disable,
 358        .is_enabled             = rpmh_regulator_is_enabled,
 359        .set_voltage_sel        = rpmh_regulator_vrm_set_voltage_sel,
 360        .get_voltage_sel        = rpmh_regulator_vrm_get_voltage_sel,
 361        .list_voltage           = regulator_list_voltage_linear_range,
 362        .set_mode               = rpmh_regulator_vrm_set_mode,
 363        .get_mode               = rpmh_regulator_vrm_get_mode,
 364        .set_load               = rpmh_regulator_vrm_set_load,
 365};
 366
 367static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
 368        .enable                 = rpmh_regulator_enable,
 369        .disable                = rpmh_regulator_disable,
 370        .is_enabled             = rpmh_regulator_is_enabled,
 371        .set_voltage_sel        = rpmh_regulator_vrm_set_voltage_sel,
 372        .get_voltage_sel        = rpmh_regulator_vrm_get_voltage_sel,
 373        .list_voltage           = regulator_list_voltage_linear_range,
 374        .set_mode               = rpmh_regulator_vrm_set_mode,
 375        .get_mode               = rpmh_regulator_vrm_get_mode,
 376        .set_bypass             = rpmh_regulator_vrm_set_bypass,
 377        .get_bypass             = rpmh_regulator_vrm_get_bypass,
 378};
 379
 380static const struct regulator_ops rpmh_regulator_xob_ops = {
 381        .enable                 = rpmh_regulator_enable,
 382        .disable                = rpmh_regulator_disable,
 383        .is_enabled             = rpmh_regulator_is_enabled,
 384};
 385
 386/**
 387 * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
 388 * vreg:                Pointer to the individual rpmh-regulator resource
 389 * dev:                 Pointer to the top level rpmh-regulator PMIC device
 390 * node:                Pointer to the individual rpmh-regulator resource
 391 *                      device node
 392 * pmic_id:             String used to identify the top level rpmh-regulator
 393 *                      PMIC device on the board
 394 * pmic_rpmh_data:      Pointer to a null-terminated array of rpmh-regulator
 395 *                      resources defined for the top level PMIC device
 396 *
 397 * Return: 0 on success, errno on failure
 398 */
 399static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
 400                        struct device_node *node, const char *pmic_id,
 401                        const struct rpmh_vreg_init_data *pmic_rpmh_data)
 402{
 403        struct regulator_config reg_config = {};
 404        char rpmh_resource_name[20] = "";
 405        const struct rpmh_vreg_init_data *rpmh_data;
 406        struct regulator_init_data *init_data;
 407        struct regulator_dev *rdev;
 408        int ret;
 409
 410        vreg->dev = dev;
 411
 412        for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
 413                if (!strcmp(rpmh_data->name, node->name))
 414                        break;
 415
 416        if (!rpmh_data->name) {
 417                dev_err(dev, "Unknown regulator %s\n", node->name);
 418                return -EINVAL;
 419        }
 420
 421        scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
 422                rpmh_data->resource_name, pmic_id);
 423
 424        vreg->addr = cmd_db_read_addr(rpmh_resource_name);
 425        if (!vreg->addr) {
 426                dev_err(dev, "%s: could not find RPMh address for resource %s\n",
 427                        node->name, rpmh_resource_name);
 428                return -ENODEV;
 429        }
 430
 431        vreg->rdesc.name = rpmh_data->name;
 432        vreg->rdesc.supply_name = rpmh_data->supply_name;
 433        vreg->hw_data = rpmh_data->hw_data;
 434
 435        vreg->enabled = -EINVAL;
 436        vreg->voltage_selector = -ENOTRECOVERABLE;
 437        vreg->mode = REGULATOR_MODE_INVALID;
 438
 439        if (rpmh_data->hw_data->n_voltages) {
 440                vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
 441                vreg->rdesc.n_linear_ranges = 1;
 442                vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
 443        }
 444
 445        vreg->always_wait_for_ack = of_property_read_bool(node,
 446                                                "qcom,always-wait-for-ack");
 447
 448        vreg->rdesc.owner       = THIS_MODULE;
 449        vreg->rdesc.type        = REGULATOR_VOLTAGE;
 450        vreg->rdesc.ops         = vreg->hw_data->ops;
 451        vreg->rdesc.of_map_mode = vreg->hw_data->of_map_mode;
 452
 453        init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
 454        if (!init_data)
 455                return -ENOMEM;
 456
 457        if (rpmh_data->hw_data->regulator_type == XOB &&
 458            init_data->constraints.min_uV &&
 459            init_data->constraints.min_uV == init_data->constraints.max_uV) {
 460                vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
 461                vreg->rdesc.n_voltages = 1;
 462        }
 463
 464        reg_config.dev          = dev;
 465        reg_config.init_data    = init_data;
 466        reg_config.of_node      = node;
 467        reg_config.driver_data  = vreg;
 468
 469        rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
 470        if (IS_ERR(rdev)) {
 471                ret = PTR_ERR(rdev);
 472                dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
 473                        node->name, ret);
 474                return ret;
 475        }
 476
 477        dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
 478                node->name, rpmh_resource_name, vreg->addr);
 479
 480        return 0;
 481}
 482
 483static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
 484        [REGULATOR_MODE_INVALID] = -EINVAL,
 485        [REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
 486        [REGULATOR_MODE_IDLE]    = PMIC4_LDO_MODE_LPM,
 487        [REGULATOR_MODE_NORMAL]  = PMIC4_LDO_MODE_HPM,
 488        [REGULATOR_MODE_FAST]    = -EINVAL,
 489};
 490
 491static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
 492{
 493        unsigned int mode;
 494
 495        switch (rpmh_mode) {
 496        case RPMH_REGULATOR_MODE_HPM:
 497                mode = REGULATOR_MODE_NORMAL;
 498                break;
 499        case RPMH_REGULATOR_MODE_LPM:
 500                mode = REGULATOR_MODE_IDLE;
 501                break;
 502        case RPMH_REGULATOR_MODE_RET:
 503                mode = REGULATOR_MODE_STANDBY;
 504                break;
 505        default:
 506                mode = REGULATOR_MODE_INVALID;
 507        }
 508
 509        return mode;
 510}
 511
 512static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
 513        [REGULATOR_MODE_INVALID] = -EINVAL,
 514        [REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
 515        [REGULATOR_MODE_IDLE]    = PMIC4_SMPS_MODE_PFM,
 516        [REGULATOR_MODE_NORMAL]  = PMIC4_SMPS_MODE_AUTO,
 517        [REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
 518};
 519
 520static unsigned int
 521rpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
 522{
 523        unsigned int mode;
 524
 525        switch (rpmh_mode) {
 526        case RPMH_REGULATOR_MODE_HPM:
 527                mode = REGULATOR_MODE_FAST;
 528                break;
 529        case RPMH_REGULATOR_MODE_AUTO:
 530                mode = REGULATOR_MODE_NORMAL;
 531                break;
 532        case RPMH_REGULATOR_MODE_LPM:
 533                mode = REGULATOR_MODE_IDLE;
 534                break;
 535        case RPMH_REGULATOR_MODE_RET:
 536                mode = REGULATOR_MODE_STANDBY;
 537                break;
 538        default:
 539                mode = REGULATOR_MODE_INVALID;
 540        }
 541
 542        return mode;
 543}
 544
 545static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
 546        [REGULATOR_MODE_INVALID] = -EINVAL,
 547        [REGULATOR_MODE_STANDBY] = -EINVAL,
 548        [REGULATOR_MODE_IDLE]    = PMIC4_BOB_MODE_PFM,
 549        [REGULATOR_MODE_NORMAL]  = PMIC4_BOB_MODE_AUTO,
 550        [REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
 551};
 552
 553static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
 554{
 555        unsigned int mode;
 556
 557        switch (rpmh_mode) {
 558        case RPMH_REGULATOR_MODE_HPM:
 559                mode = REGULATOR_MODE_FAST;
 560                break;
 561        case RPMH_REGULATOR_MODE_AUTO:
 562                mode = REGULATOR_MODE_NORMAL;
 563                break;
 564        case RPMH_REGULATOR_MODE_LPM:
 565                mode = REGULATOR_MODE_IDLE;
 566                break;
 567        default:
 568                mode = REGULATOR_MODE_INVALID;
 569        }
 570
 571        return mode;
 572}
 573
 574static const struct rpmh_vreg_hw_data pmic4_pldo = {
 575        .regulator_type = VRM,
 576        .ops = &rpmh_regulator_vrm_drms_ops,
 577        .voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
 578        .n_voltages = 256,
 579        .hpm_min_load_uA = 10000,
 580        .pmic_mode_map = pmic_mode_map_pmic4_ldo,
 581        .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
 582};
 583
 584static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
 585        .regulator_type = VRM,
 586        .ops = &rpmh_regulator_vrm_drms_ops,
 587        .voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
 588        .n_voltages = 128,
 589        .hpm_min_load_uA = 10000,
 590        .pmic_mode_map = pmic_mode_map_pmic4_ldo,
 591        .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
 592};
 593
 594static const struct rpmh_vreg_hw_data pmic4_nldo = {
 595        .regulator_type = VRM,
 596        .ops = &rpmh_regulator_vrm_drms_ops,
 597        .voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
 598        .n_voltages = 128,
 599        .hpm_min_load_uA = 30000,
 600        .pmic_mode_map = pmic_mode_map_pmic4_ldo,
 601        .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
 602};
 603
 604static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
 605        .regulator_type = VRM,
 606        .ops = &rpmh_regulator_vrm_ops,
 607        .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
 608        .n_voltages = 216,
 609        .pmic_mode_map = pmic_mode_map_pmic4_smps,
 610        .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
 611};
 612
 613static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
 614        .regulator_type = VRM,
 615        .ops = &rpmh_regulator_vrm_ops,
 616        .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
 617        .n_voltages = 259,
 618        .pmic_mode_map = pmic_mode_map_pmic4_smps,
 619        .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
 620};
 621
 622static const struct rpmh_vreg_hw_data pmic4_bob = {
 623        .regulator_type = VRM,
 624        .ops = &rpmh_regulator_vrm_bypass_ops,
 625        .voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
 626        .n_voltages = 84,
 627        .pmic_mode_map = pmic_mode_map_pmic4_bob,
 628        .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
 629};
 630
 631static const struct rpmh_vreg_hw_data pmic4_lvs = {
 632        .regulator_type = XOB,
 633        .ops = &rpmh_regulator_xob_ops,
 634        /* LVS hardware does not support voltage or mode configuration. */
 635};
 636
 637#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
 638{ \
 639        .name           = _name, \
 640        .resource_name  = _resource_name, \
 641        .hw_data        = _hw_data, \
 642        .supply_name    = _supply_name, \
 643}
 644
 645static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
 646        RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
 647        RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
 648        RPMH_VREG("smps3",  "smp%s3",  &pmic4_hfsmps3,   "vdd-s3"),
 649        RPMH_VREG("smps4",  "smp%s4",  &pmic4_hfsmps3,   "vdd-s4"),
 650        RPMH_VREG("smps5",  "smp%s5",  &pmic4_hfsmps3,   "vdd-s5"),
 651        RPMH_VREG("smps6",  "smp%s6",  &pmic4_ftsmps426, "vdd-s6"),
 652        RPMH_VREG("smps7",  "smp%s7",  &pmic4_ftsmps426, "vdd-s7"),
 653        RPMH_VREG("smps8",  "smp%s8",  &pmic4_ftsmps426, "vdd-s8"),
 654        RPMH_VREG("smps9",  "smp%s9",  &pmic4_ftsmps426, "vdd-s9"),
 655        RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
 656        RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
 657        RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
 658        RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
 659        RPMH_VREG("ldo1",   "ldo%s1",  &pmic4_nldo,      "vdd-l1-l27"),
 660        RPMH_VREG("ldo2",   "ldo%s2",  &pmic4_nldo,      "vdd-l2-l8-l17"),
 661        RPMH_VREG("ldo3",   "ldo%s3",  &pmic4_nldo,      "vdd-l3-l11"),
 662        RPMH_VREG("ldo4",   "ldo%s4",  &pmic4_nldo,      "vdd-l4-l5"),
 663        RPMH_VREG("ldo5",   "ldo%s5",  &pmic4_nldo,      "vdd-l4-l5"),
 664        RPMH_VREG("ldo6",   "ldo%s6",  &pmic4_pldo,      "vdd-l6"),
 665        RPMH_VREG("ldo7",   "ldo%s7",  &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
 666        RPMH_VREG("ldo8",   "ldo%s8",  &pmic4_nldo,      "vdd-l2-l8-l17"),
 667        RPMH_VREG("ldo9",   "ldo%s9",  &pmic4_pldo,      "vdd-l9"),
 668        RPMH_VREG("ldo10",  "ldo%s10", &pmic4_pldo,      "vdd-l10-l23-l25"),
 669        RPMH_VREG("ldo11",  "ldo%s11", &pmic4_nldo,      "vdd-l3-l11"),
 670        RPMH_VREG("ldo12",  "ldo%s12", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
 671        RPMH_VREG("ldo13",  "ldo%s13", &pmic4_pldo,      "vdd-l13-l19-l21"),
 672        RPMH_VREG("ldo14",  "ldo%s14", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
 673        RPMH_VREG("ldo15",  "ldo%s15", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
 674        RPMH_VREG("ldo16",  "ldo%s16", &pmic4_pldo,      "vdd-l16-l28"),
 675        RPMH_VREG("ldo17",  "ldo%s17", &pmic4_nldo,      "vdd-l2-l8-l17"),
 676        RPMH_VREG("ldo18",  "ldo%s18", &pmic4_pldo,      "vdd-l18-l22"),
 677        RPMH_VREG("ldo19",  "ldo%s19", &pmic4_pldo,      "vdd-l13-l19-l21"),
 678        RPMH_VREG("ldo20",  "ldo%s20", &pmic4_pldo,      "vdd-l20-l24"),
 679        RPMH_VREG("ldo21",  "ldo%s21", &pmic4_pldo,      "vdd-l13-l19-l21"),
 680        RPMH_VREG("ldo22",  "ldo%s22", &pmic4_pldo,      "vdd-l18-l22"),
 681        RPMH_VREG("ldo23",  "ldo%s23", &pmic4_pldo,      "vdd-l10-l23-l25"),
 682        RPMH_VREG("ldo24",  "ldo%s24", &pmic4_pldo,      "vdd-l20-l24"),
 683        RPMH_VREG("ldo25",  "ldo%s25", &pmic4_pldo,      "vdd-l10-l23-l25"),
 684        RPMH_VREG("ldo26",  "ldo%s26", &pmic4_nldo,      "vdd-l26"),
 685        RPMH_VREG("ldo27",  "ldo%s27", &pmic4_nldo,      "vdd-l1-l27"),
 686        RPMH_VREG("ldo28",  "ldo%s28", &pmic4_pldo,      "vdd-l16-l28"),
 687        RPMH_VREG("lvs1",   "vs%s1",   &pmic4_lvs,       "vin-lvs-1-2"),
 688        RPMH_VREG("lvs2",   "vs%s2",   &pmic4_lvs,       "vin-lvs-1-2"),
 689        {},
 690};
 691
 692static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
 693        RPMH_VREG("bob",    "bob%s1",  &pmic4_bob,       "vdd-bob"),
 694        {},
 695};
 696
 697static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
 698        RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
 699        RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
 700        RPMH_VREG("smps3",  "smp%s3",  &pmic4_ftsmps426, "vdd-s3"),
 701        RPMH_VREG("smps4",  "smp%s4",  &pmic4_ftsmps426, "vdd-s4"),
 702        {},
 703};
 704
 705static int rpmh_regulator_probe(struct platform_device *pdev)
 706{
 707        struct device *dev = &pdev->dev;
 708        const struct rpmh_vreg_init_data *vreg_data;
 709        struct device_node *node;
 710        struct rpmh_vreg *vreg;
 711        const char *pmic_id;
 712        int ret;
 713
 714        vreg_data = of_device_get_match_data(dev);
 715        if (!vreg_data)
 716                return -ENODEV;
 717
 718        ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
 719        if (ret < 0) {
 720                dev_err(dev, "qcom,pmic-id missing in DT node\n");
 721                return ret;
 722        }
 723
 724        for_each_available_child_of_node(dev->of_node, node) {
 725                vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
 726                if (!vreg) {
 727                        of_node_put(node);
 728                        return -ENOMEM;
 729                }
 730
 731                ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
 732                                                vreg_data);
 733                if (ret < 0) {
 734                        of_node_put(node);
 735                        return ret;
 736                }
 737        }
 738
 739        return 0;
 740}
 741
 742static const struct of_device_id rpmh_regulator_match_table[] = {
 743        {
 744                .compatible = "qcom,pm8998-rpmh-regulators",
 745                .data = pm8998_vreg_data,
 746        },
 747        {
 748                .compatible = "qcom,pmi8998-rpmh-regulators",
 749                .data = pmi8998_vreg_data,
 750        },
 751        {
 752                .compatible = "qcom,pm8005-rpmh-regulators",
 753                .data = pm8005_vreg_data,
 754        },
 755        {}
 756};
 757MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
 758
 759static struct platform_driver rpmh_regulator_driver = {
 760        .driver = {
 761                .name = "qcom-rpmh-regulator",
 762                .of_match_table = of_match_ptr(rpmh_regulator_match_table),
 763        },
 764        .probe = rpmh_regulator_probe,
 765};
 766module_platform_driver(rpmh_regulator_driver);
 767
 768MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
 769MODULE_LICENSE("GPL v2");
 770