linux/drivers/regulator/qcom_rpm-regulator.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014, Sony Mobile Communications AB.
   3 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 and
   7 * only version 2 as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/platform_device.h>
  17#include <linux/of.h>
  18#include <linux/of_device.h>
  19#include <linux/regulator/driver.h>
  20#include <linux/regulator/machine.h>
  21#include <linux/regulator/of_regulator.h>
  22#include <linux/mfd/qcom_rpm.h>
  23
  24#include <dt-bindings/mfd/qcom-rpm.h>
  25
  26#define MAX_REQUEST_LEN 2
  27
  28struct request_member {
  29        int             word;
  30        unsigned int    mask;
  31        int             shift;
  32};
  33
  34struct rpm_reg_parts {
  35        struct request_member mV;               /* used if voltage is in mV */
  36        struct request_member uV;               /* used if voltage is in uV */
  37        struct request_member ip;               /* peak current in mA */
  38        struct request_member pd;               /* pull down enable */
  39        struct request_member ia;               /* average current in mA */
  40        struct request_member fm;               /* force mode */
  41        struct request_member pm;               /* power mode */
  42        struct request_member pc;               /* pin control */
  43        struct request_member pf;               /* pin function */
  44        struct request_member enable_state;     /* NCP and switch */
  45        struct request_member comp_mode;        /* NCP */
  46        struct request_member freq;             /* frequency: NCP and SMPS */
  47        struct request_member freq_clk_src;     /* clock source: SMPS */
  48        struct request_member hpm;              /* switch: control OCP and SS */
  49        int request_len;
  50};
  51
  52#define FORCE_MODE_IS_2_BITS(reg) \
  53        (((reg)->parts->fm.mask >> (reg)->parts->fm.shift) == 3)
  54
  55struct qcom_rpm_reg {
  56        struct qcom_rpm *rpm;
  57
  58        struct mutex lock;
  59        struct device *dev;
  60        struct regulator_desc desc;
  61        const struct rpm_reg_parts *parts;
  62
  63        int resource;
  64        u32 val[MAX_REQUEST_LEN];
  65
  66        int uV;
  67        int is_enabled;
  68
  69        bool supports_force_mode_auto;
  70        bool supports_force_mode_bypass;
  71};
  72
  73static const struct rpm_reg_parts rpm8660_ldo_parts = {
  74        .request_len    = 2,
  75        .mV             = { 0, 0x00000FFF,  0 },
  76        .ip             = { 0, 0x00FFF000, 12 },
  77        .fm             = { 0, 0x03000000, 24 },
  78        .pc             = { 0, 0x3C000000, 26 },
  79        .pf             = { 0, 0xC0000000, 30 },
  80        .pd             = { 1, 0x00000001,  0 },
  81        .ia             = { 1, 0x00001FFE,  1 },
  82};
  83
  84static const struct rpm_reg_parts rpm8660_smps_parts = {
  85        .request_len    = 2,
  86        .mV             = { 0, 0x00000FFF,  0 },
  87        .ip             = { 0, 0x00FFF000, 12 },
  88        .fm             = { 0, 0x03000000, 24 },
  89        .pc             = { 0, 0x3C000000, 26 },
  90        .pf             = { 0, 0xC0000000, 30 },
  91        .pd             = { 1, 0x00000001,  0 },
  92        .ia             = { 1, 0x00001FFE,  1 },
  93        .freq           = { 1, 0x001FE000, 13 },
  94        .freq_clk_src   = { 1, 0x00600000, 21 },
  95};
  96
  97static const struct rpm_reg_parts rpm8660_switch_parts = {
  98        .request_len    = 1,
  99        .enable_state   = { 0, 0x00000001,  0 },
 100        .pd             = { 0, 0x00000002,  1 },
 101        .pc             = { 0, 0x0000003C,  2 },
 102        .pf             = { 0, 0x000000C0,  6 },
 103        .hpm            = { 0, 0x00000300,  8 },
 104};
 105
 106static const struct rpm_reg_parts rpm8660_ncp_parts = {
 107        .request_len    = 1,
 108        .mV             = { 0, 0x00000FFF,  0 },
 109        .enable_state   = { 0, 0x00001000, 12 },
 110        .comp_mode      = { 0, 0x00002000, 13 },
 111        .freq           = { 0, 0x003FC000, 14 },
 112};
 113
 114static const struct rpm_reg_parts rpm8960_ldo_parts = {
 115        .request_len    = 2,
 116        .uV             = { 0, 0x007FFFFF,  0 },
 117        .pd             = { 0, 0x00800000, 23 },
 118        .pc             = { 0, 0x0F000000, 24 },
 119        .pf             = { 0, 0xF0000000, 28 },
 120        .ip             = { 1, 0x000003FF,  0 },
 121        .ia             = { 1, 0x000FFC00, 10 },
 122        .fm             = { 1, 0x00700000, 20 },
 123};
 124
 125static const struct rpm_reg_parts rpm8960_smps_parts = {
 126        .request_len    = 2,
 127        .uV             = { 0, 0x007FFFFF,  0 },
 128        .pd             = { 0, 0x00800000, 23 },
 129        .pc             = { 0, 0x0F000000, 24 },
 130        .pf             = { 0, 0xF0000000, 28 },
 131        .ip             = { 1, 0x000003FF,  0 },
 132        .ia             = { 1, 0x000FFC00, 10 },
 133        .fm             = { 1, 0x00700000, 20 },
 134        .pm             = { 1, 0x00800000, 23 },
 135        .freq           = { 1, 0x1F000000, 24 },
 136        .freq_clk_src   = { 1, 0x60000000, 29 },
 137};
 138
 139static const struct rpm_reg_parts rpm8960_switch_parts = {
 140        .request_len    = 1,
 141        .enable_state   = { 0, 0x00000001,  0 },
 142        .pd             = { 0, 0x00000002,  1 },
 143        .pc             = { 0, 0x0000003C,  2 },
 144        .pf             = { 0, 0x000003C0,  6 },
 145        .hpm            = { 0, 0x00000C00, 10 },
 146};
 147
 148static const struct rpm_reg_parts rpm8960_ncp_parts = {
 149        .request_len    = 1,
 150        .uV             = { 0, 0x007FFFFF,  0 },
 151        .enable_state   = { 0, 0x00800000, 23 },
 152        .comp_mode      = { 0, 0x01000000, 24 },
 153        .freq           = { 0, 0x3E000000, 25 },
 154};
 155
 156/*
 157 * Physically available PMIC regulator voltage ranges
 158 */
 159static const struct regulator_linear_range pldo_ranges[] = {
 160        REGULATOR_LINEAR_RANGE( 750000,   0,  59, 12500),
 161        REGULATOR_LINEAR_RANGE(1500000,  60, 123, 25000),
 162        REGULATOR_LINEAR_RANGE(3100000, 124, 160, 50000),
 163};
 164
 165static const struct regulator_linear_range nldo_ranges[] = {
 166        REGULATOR_LINEAR_RANGE( 750000,   0,  63, 12500),
 167};
 168
 169static const struct regulator_linear_range nldo1200_ranges[] = {
 170        REGULATOR_LINEAR_RANGE( 375000,   0,  59,  6250),
 171        REGULATOR_LINEAR_RANGE( 750000,  60, 123, 12500),
 172};
 173
 174static const struct regulator_linear_range smps_ranges[] = {
 175        REGULATOR_LINEAR_RANGE( 375000,   0,  29, 12500),
 176        REGULATOR_LINEAR_RANGE( 750000,  30,  89, 12500),
 177        REGULATOR_LINEAR_RANGE(1500000,  90, 153, 25000),
 178};
 179
 180static const struct regulator_linear_range ftsmps_ranges[] = {
 181        REGULATOR_LINEAR_RANGE( 350000,   0,   6, 50000),
 182        REGULATOR_LINEAR_RANGE( 700000,   7,  63, 12500),
 183        REGULATOR_LINEAR_RANGE(1500000,  64, 100, 50000),
 184};
 185
 186static const struct regulator_linear_range smb208_ranges[] = {
 187        REGULATOR_LINEAR_RANGE( 375000,   0,  29, 12500),
 188        REGULATOR_LINEAR_RANGE( 750000,  30,  89, 12500),
 189        REGULATOR_LINEAR_RANGE(1500000,  90, 153, 25000),
 190        REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000),
 191};
 192
 193static const struct regulator_linear_range ncp_ranges[] = {
 194        REGULATOR_LINEAR_RANGE(1500000,   0,  31, 50000),
 195};
 196
 197static int rpm_reg_write(struct qcom_rpm_reg *vreg,
 198                         const struct request_member *req,
 199                         const int value)
 200{
 201        if (WARN_ON((value << req->shift) & ~req->mask))
 202                return -EINVAL;
 203
 204        vreg->val[req->word] &= ~req->mask;
 205        vreg->val[req->word] |= value << req->shift;
 206
 207        return qcom_rpm_write(vreg->rpm,
 208                              QCOM_RPM_ACTIVE_STATE,
 209                              vreg->resource,
 210                              vreg->val,
 211                              vreg->parts->request_len);
 212}
 213
 214static int rpm_reg_set_mV_sel(struct regulator_dev *rdev,
 215                              unsigned selector)
 216{
 217        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 218        const struct rpm_reg_parts *parts = vreg->parts;
 219        const struct request_member *req = &parts->mV;
 220        int ret = 0;
 221        int uV;
 222
 223        if (req->mask == 0)
 224                return -EINVAL;
 225
 226        uV = regulator_list_voltage_linear_range(rdev, selector);
 227        if (uV < 0)
 228                return uV;
 229
 230        mutex_lock(&vreg->lock);
 231        if (vreg->is_enabled)
 232                ret = rpm_reg_write(vreg, req, uV / 1000);
 233
 234        if (!ret)
 235                vreg->uV = uV;
 236        mutex_unlock(&vreg->lock);
 237
 238        return ret;
 239}
 240
 241static int rpm_reg_set_uV_sel(struct regulator_dev *rdev,
 242                              unsigned selector)
 243{
 244        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 245        const struct rpm_reg_parts *parts = vreg->parts;
 246        const struct request_member *req = &parts->uV;
 247        int ret = 0;
 248        int uV;
 249
 250        if (req->mask == 0)
 251                return -EINVAL;
 252
 253        uV = regulator_list_voltage_linear_range(rdev, selector);
 254        if (uV < 0)
 255                return uV;
 256
 257        mutex_lock(&vreg->lock);
 258        if (vreg->is_enabled)
 259                ret = rpm_reg_write(vreg, req, uV);
 260
 261        if (!ret)
 262                vreg->uV = uV;
 263        mutex_unlock(&vreg->lock);
 264
 265        return ret;
 266}
 267
 268static int rpm_reg_get_voltage(struct regulator_dev *rdev)
 269{
 270        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 271
 272        return vreg->uV;
 273}
 274
 275static int rpm_reg_mV_enable(struct regulator_dev *rdev)
 276{
 277        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 278        const struct rpm_reg_parts *parts = vreg->parts;
 279        const struct request_member *req = &parts->mV;
 280        int ret;
 281
 282        if (req->mask == 0)
 283                return -EINVAL;
 284
 285        mutex_lock(&vreg->lock);
 286        ret = rpm_reg_write(vreg, req, vreg->uV / 1000);
 287        if (!ret)
 288                vreg->is_enabled = 1;
 289        mutex_unlock(&vreg->lock);
 290
 291        return ret;
 292}
 293
 294static int rpm_reg_uV_enable(struct regulator_dev *rdev)
 295{
 296        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 297        const struct rpm_reg_parts *parts = vreg->parts;
 298        const struct request_member *req = &parts->uV;
 299        int ret;
 300
 301        if (req->mask == 0)
 302                return -EINVAL;
 303
 304        mutex_lock(&vreg->lock);
 305        ret = rpm_reg_write(vreg, req, vreg->uV);
 306        if (!ret)
 307                vreg->is_enabled = 1;
 308        mutex_unlock(&vreg->lock);
 309
 310        return ret;
 311}
 312
 313static int rpm_reg_switch_enable(struct regulator_dev *rdev)
 314{
 315        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 316        const struct rpm_reg_parts *parts = vreg->parts;
 317        const struct request_member *req = &parts->enable_state;
 318        int ret;
 319
 320        if (req->mask == 0)
 321                return -EINVAL;
 322
 323        mutex_lock(&vreg->lock);
 324        ret = rpm_reg_write(vreg, req, 1);
 325        if (!ret)
 326                vreg->is_enabled = 1;
 327        mutex_unlock(&vreg->lock);
 328
 329        return ret;
 330}
 331
 332static int rpm_reg_mV_disable(struct regulator_dev *rdev)
 333{
 334        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 335        const struct rpm_reg_parts *parts = vreg->parts;
 336        const struct request_member *req = &parts->mV;
 337        int ret;
 338
 339        if (req->mask == 0)
 340                return -EINVAL;
 341
 342        mutex_lock(&vreg->lock);
 343        ret = rpm_reg_write(vreg, req, 0);
 344        if (!ret)
 345                vreg->is_enabled = 0;
 346        mutex_unlock(&vreg->lock);
 347
 348        return ret;
 349}
 350
 351static int rpm_reg_uV_disable(struct regulator_dev *rdev)
 352{
 353        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 354        const struct rpm_reg_parts *parts = vreg->parts;
 355        const struct request_member *req = &parts->uV;
 356        int ret;
 357
 358        if (req->mask == 0)
 359                return -EINVAL;
 360
 361        mutex_lock(&vreg->lock);
 362        ret = rpm_reg_write(vreg, req, 0);
 363        if (!ret)
 364                vreg->is_enabled = 0;
 365        mutex_unlock(&vreg->lock);
 366
 367        return ret;
 368}
 369
 370static int rpm_reg_switch_disable(struct regulator_dev *rdev)
 371{
 372        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 373        const struct rpm_reg_parts *parts = vreg->parts;
 374        const struct request_member *req = &parts->enable_state;
 375        int ret;
 376
 377        if (req->mask == 0)
 378                return -EINVAL;
 379
 380        mutex_lock(&vreg->lock);
 381        ret = rpm_reg_write(vreg, req, 0);
 382        if (!ret)
 383                vreg->is_enabled = 0;
 384        mutex_unlock(&vreg->lock);
 385
 386        return ret;
 387}
 388
 389static int rpm_reg_is_enabled(struct regulator_dev *rdev)
 390{
 391        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 392
 393        return vreg->is_enabled;
 394}
 395
 396static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
 397{
 398        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 399        const struct rpm_reg_parts *parts = vreg->parts;
 400        const struct request_member *req = &parts->ia;
 401        int load_mA = load_uA / 1000;
 402        int max_mA = req->mask >> req->shift;
 403        int ret;
 404
 405        if (req->mask == 0)
 406                return -EINVAL;
 407
 408        if (load_mA > max_mA)
 409                load_mA = max_mA;
 410
 411        mutex_lock(&vreg->lock);
 412        ret = rpm_reg_write(vreg, req, load_mA);
 413        mutex_unlock(&vreg->lock);
 414
 415        return ret;
 416}
 417
 418static struct regulator_ops uV_ops = {
 419        .list_voltage = regulator_list_voltage_linear_range,
 420
 421        .set_voltage_sel = rpm_reg_set_uV_sel,
 422        .get_voltage = rpm_reg_get_voltage,
 423
 424        .enable = rpm_reg_uV_enable,
 425        .disable = rpm_reg_uV_disable,
 426        .is_enabled = rpm_reg_is_enabled,
 427
 428        .set_load = rpm_reg_set_load,
 429};
 430
 431static struct regulator_ops mV_ops = {
 432        .list_voltage = regulator_list_voltage_linear_range,
 433
 434        .set_voltage_sel = rpm_reg_set_mV_sel,
 435        .get_voltage = rpm_reg_get_voltage,
 436
 437        .enable = rpm_reg_mV_enable,
 438        .disable = rpm_reg_mV_disable,
 439        .is_enabled = rpm_reg_is_enabled,
 440
 441        .set_load = rpm_reg_set_load,
 442};
 443
 444static struct regulator_ops switch_ops = {
 445        .enable = rpm_reg_switch_enable,
 446        .disable = rpm_reg_switch_disable,
 447        .is_enabled = rpm_reg_is_enabled,
 448};
 449
 450/*
 451 * PM8058 regulators
 452 */
 453static const struct qcom_rpm_reg pm8058_pldo = {
 454        .desc.linear_ranges = pldo_ranges,
 455        .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges),
 456        .desc.n_voltages = 161,
 457        .desc.ops = &mV_ops,
 458        .parts = &rpm8660_ldo_parts,
 459        .supports_force_mode_auto = false,
 460        .supports_force_mode_bypass = false,
 461};
 462
 463static const struct qcom_rpm_reg pm8058_nldo = {
 464        .desc.linear_ranges = nldo_ranges,
 465        .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges),
 466        .desc.n_voltages = 64,
 467        .desc.ops = &mV_ops,
 468        .parts = &rpm8660_ldo_parts,
 469        .supports_force_mode_auto = false,
 470        .supports_force_mode_bypass = false,
 471};
 472
 473static const struct qcom_rpm_reg pm8058_smps = {
 474        .desc.linear_ranges = smps_ranges,
 475        .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges),
 476        .desc.n_voltages = 154,
 477        .desc.ops = &mV_ops,
 478        .parts = &rpm8660_smps_parts,
 479        .supports_force_mode_auto = false,
 480        .supports_force_mode_bypass = false,
 481};
 482
 483static const struct qcom_rpm_reg pm8058_ncp = {
 484        .desc.linear_ranges = ncp_ranges,
 485        .desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges),
 486        .desc.n_voltages = 32,
 487        .desc.ops = &mV_ops,
 488        .parts = &rpm8660_ncp_parts,
 489};
 490
 491static const struct qcom_rpm_reg pm8058_switch = {
 492        .desc.ops = &switch_ops,
 493        .parts = &rpm8660_switch_parts,
 494};
 495
 496/*
 497 * PM8901 regulators
 498 */
 499static const struct qcom_rpm_reg pm8901_pldo = {
 500        .desc.linear_ranges = pldo_ranges,
 501        .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges),
 502        .desc.n_voltages = 161,
 503        .desc.ops = &mV_ops,
 504        .parts = &rpm8660_ldo_parts,
 505        .supports_force_mode_auto = false,
 506        .supports_force_mode_bypass = true,
 507};
 508
 509static const struct qcom_rpm_reg pm8901_nldo = {
 510        .desc.linear_ranges = nldo_ranges,
 511        .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges),
 512        .desc.n_voltages = 64,
 513        .desc.ops = &mV_ops,
 514        .parts = &rpm8660_ldo_parts,
 515        .supports_force_mode_auto = false,
 516        .supports_force_mode_bypass = true,
 517};
 518
 519static const struct qcom_rpm_reg pm8901_ftsmps = {
 520        .desc.linear_ranges = ftsmps_ranges,
 521        .desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges),
 522        .desc.n_voltages = 101,
 523        .desc.ops = &mV_ops,
 524        .parts = &rpm8660_smps_parts,
 525        .supports_force_mode_auto = true,
 526        .supports_force_mode_bypass = false,
 527};
 528
 529static const struct qcom_rpm_reg pm8901_switch = {
 530        .desc.ops = &switch_ops,
 531        .parts = &rpm8660_switch_parts,
 532};
 533
 534/*
 535 * PM8921 regulators
 536 */
 537static const struct qcom_rpm_reg pm8921_pldo = {
 538        .desc.linear_ranges = pldo_ranges,
 539        .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges),
 540        .desc.n_voltages = 161,
 541        .desc.ops = &uV_ops,
 542        .parts = &rpm8960_ldo_parts,
 543        .supports_force_mode_auto = false,
 544        .supports_force_mode_bypass = true,
 545};
 546
 547static const struct qcom_rpm_reg pm8921_nldo = {
 548        .desc.linear_ranges = nldo_ranges,
 549        .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges),
 550        .desc.n_voltages = 64,
 551        .desc.ops = &uV_ops,
 552        .parts = &rpm8960_ldo_parts,
 553        .supports_force_mode_auto = false,
 554        .supports_force_mode_bypass = true,
 555};
 556
 557static const struct qcom_rpm_reg pm8921_nldo1200 = {
 558        .desc.linear_ranges = nldo1200_ranges,
 559        .desc.n_linear_ranges = ARRAY_SIZE(nldo1200_ranges),
 560        .desc.n_voltages = 124,
 561        .desc.ops = &uV_ops,
 562        .parts = &rpm8960_ldo_parts,
 563        .supports_force_mode_auto = false,
 564        .supports_force_mode_bypass = true,
 565};
 566
 567static const struct qcom_rpm_reg pm8921_smps = {
 568        .desc.linear_ranges = smps_ranges,
 569        .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges),
 570        .desc.n_voltages = 154,
 571        .desc.ops = &uV_ops,
 572        .parts = &rpm8960_smps_parts,
 573        .supports_force_mode_auto = true,
 574        .supports_force_mode_bypass = false,
 575};
 576
 577static const struct qcom_rpm_reg pm8921_ftsmps = {
 578        .desc.linear_ranges = ftsmps_ranges,
 579        .desc.n_linear_ranges = ARRAY_SIZE(ftsmps_ranges),
 580        .desc.n_voltages = 101,
 581        .desc.ops = &uV_ops,
 582        .parts = &rpm8960_smps_parts,
 583        .supports_force_mode_auto = true,
 584        .supports_force_mode_bypass = false,
 585};
 586
 587static const struct qcom_rpm_reg pm8921_ncp = {
 588        .desc.linear_ranges = ncp_ranges,
 589        .desc.n_linear_ranges = ARRAY_SIZE(ncp_ranges),
 590        .desc.n_voltages = 32,
 591        .desc.ops = &uV_ops,
 592        .parts = &rpm8960_ncp_parts,
 593};
 594
 595static const struct qcom_rpm_reg pm8921_switch = {
 596        .desc.ops = &switch_ops,
 597        .parts = &rpm8960_switch_parts,
 598};
 599
 600static const struct qcom_rpm_reg smb208_smps = {
 601        .desc.linear_ranges = smb208_ranges,
 602        .desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges),
 603        .desc.n_voltages = 235,
 604        .desc.ops = &uV_ops,
 605        .parts = &rpm8960_smps_parts,
 606        .supports_force_mode_auto = false,
 607        .supports_force_mode_bypass = false,
 608};
 609
 610static int rpm_reg_set(struct qcom_rpm_reg *vreg,
 611                       const struct request_member *req,
 612                       const int value)
 613{
 614        if (req->mask == 0 || (value << req->shift) & ~req->mask)
 615                return -EINVAL;
 616
 617        vreg->val[req->word] &= ~req->mask;
 618        vreg->val[req->word] |= value << req->shift;
 619
 620        return 0;
 621}
 622
 623static int rpm_reg_of_parse_freq(struct device *dev,
 624                                 struct device_node *node,
 625                                 struct qcom_rpm_reg *vreg)
 626{
 627        static const int freq_table[] = {
 628                19200000, 9600000, 6400000, 4800000, 3840000, 3200000, 2740000,
 629                2400000, 2130000, 1920000, 1750000, 1600000, 1480000, 1370000,
 630                1280000, 1200000,
 631
 632        };
 633        const char *key;
 634        u32 freq;
 635        int ret;
 636        int i;
 637
 638        key = "qcom,switch-mode-frequency";
 639        ret = of_property_read_u32(node, key, &freq);
 640        if (ret) {
 641                dev_err(dev, "regulator requires %s property\n", key);
 642                return -EINVAL;
 643        }
 644
 645        for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
 646                if (freq == freq_table[i]) {
 647                        rpm_reg_set(vreg, &vreg->parts->freq, i + 1);
 648                        return 0;
 649                }
 650        }
 651
 652        dev_err(dev, "invalid frequency %d\n", freq);
 653        return -EINVAL;
 654}
 655
 656static int rpm_reg_of_parse(struct device_node *node,
 657                            const struct regulator_desc *desc,
 658                            struct regulator_config *config)
 659{
 660        struct qcom_rpm_reg *vreg = config->driver_data;
 661        struct device *dev = config->dev;
 662        const char *key;
 663        u32 force_mode;
 664        bool pwm;
 665        u32 val;
 666        int ret;
 667
 668        key = "bias-pull-down";
 669        if (of_property_read_bool(node, key)) {
 670                ret = rpm_reg_set(vreg, &vreg->parts->pd, 1);
 671                if (ret) {
 672                        dev_err(dev, "%s is invalid", key);
 673                        return ret;
 674                }
 675        }
 676
 677        if (vreg->parts->freq.mask) {
 678                ret = rpm_reg_of_parse_freq(dev, node, vreg);
 679                if (ret < 0)
 680                        return ret;
 681        }
 682
 683        if (vreg->parts->pm.mask) {
 684                key = "qcom,power-mode-hysteretic";
 685                pwm = !of_property_read_bool(node, key);
 686
 687                ret = rpm_reg_set(vreg, &vreg->parts->pm, pwm);
 688                if (ret) {
 689                        dev_err(dev, "failed to set power mode\n");
 690                        return ret;
 691                }
 692        }
 693
 694        if (vreg->parts->fm.mask) {
 695                force_mode = -1;
 696
 697                key = "qcom,force-mode";
 698                ret = of_property_read_u32(node, key, &val);
 699                if (ret == -EINVAL) {
 700                        val = QCOM_RPM_FORCE_MODE_NONE;
 701                } else if (ret < 0) {
 702                        dev_err(dev, "failed to read %s\n", key);
 703                        return ret;
 704                }
 705
 706                /*
 707                 * If force-mode is encoded as 2 bits then the
 708                 * possible register values are:
 709                 * NONE, LPM, HPM
 710                 * otherwise:
 711                 * NONE, LPM, AUTO, HPM, BYPASS
 712                 */
 713                switch (val) {
 714                case QCOM_RPM_FORCE_MODE_NONE:
 715                        force_mode = 0;
 716                        break;
 717                case QCOM_RPM_FORCE_MODE_LPM:
 718                        force_mode = 1;
 719                        break;
 720                case QCOM_RPM_FORCE_MODE_HPM:
 721                        if (FORCE_MODE_IS_2_BITS(vreg))
 722                                force_mode = 2;
 723                        else
 724                                force_mode = 3;
 725                        break;
 726                case QCOM_RPM_FORCE_MODE_AUTO:
 727                        if (vreg->supports_force_mode_auto)
 728                                force_mode = 2;
 729                        break;
 730                case QCOM_RPM_FORCE_MODE_BYPASS:
 731                        if (vreg->supports_force_mode_bypass)
 732                                force_mode = 4;
 733                        break;
 734                }
 735
 736                if (force_mode == -1) {
 737                        dev_err(dev, "invalid force mode\n");
 738                        return -EINVAL;
 739                }
 740
 741                ret = rpm_reg_set(vreg, &vreg->parts->fm, force_mode);
 742                if (ret) {
 743                        dev_err(dev, "failed to set force mode\n");
 744                        return ret;
 745                }
 746        }
 747
 748        return 0;
 749}
 750
 751struct rpm_regulator_data {
 752        const char *name;
 753        int resource;
 754        const struct qcom_rpm_reg *template;
 755        const char *supply;
 756};
 757
 758static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
 759        { "l0",   QCOM_RPM_PM8058_LDO0,   &pm8058_nldo, "vdd_l0_l1_lvs" },
 760        { "l1",   QCOM_RPM_PM8058_LDO1,   &pm8058_nldo, "vdd_l0_l1_lvs" },
 761        { "l2",   QCOM_RPM_PM8058_LDO2,   &pm8058_pldo, "vdd_l2_l11_l12" },
 762        { "l3",   QCOM_RPM_PM8058_LDO3,   &pm8058_pldo, "vdd_l3_l4_l5" },
 763        { "l4",   QCOM_RPM_PM8058_LDO4,   &pm8058_pldo, "vdd_l3_l4_l5" },
 764        { "l5",   QCOM_RPM_PM8058_LDO5,   &pm8058_pldo, "vdd_l3_l4_l5" },
 765        { "l6",   QCOM_RPM_PM8058_LDO6,   &pm8058_pldo, "vdd_l6_l7" },
 766        { "l7",   QCOM_RPM_PM8058_LDO7,   &pm8058_pldo, "vdd_l6_l7" },
 767        { "l8",   QCOM_RPM_PM8058_LDO8,   &pm8058_pldo, "vdd_l8" },
 768        { "l9",   QCOM_RPM_PM8058_LDO9,   &pm8058_pldo, "vdd_l9" },
 769        { "l10",  QCOM_RPM_PM8058_LDO10,  &pm8058_pldo, "vdd_l10" },
 770        { "l11",  QCOM_RPM_PM8058_LDO11,  &pm8058_pldo, "vdd_l2_l11_l12" },
 771        { "l12",  QCOM_RPM_PM8058_LDO12,  &pm8058_pldo, "vdd_l2_l11_l12" },
 772        { "l13",  QCOM_RPM_PM8058_LDO13,  &pm8058_pldo, "vdd_l13_l16" },
 773        { "l14",  QCOM_RPM_PM8058_LDO14,  &pm8058_pldo, "vdd_l14_l15" },
 774        { "l15",  QCOM_RPM_PM8058_LDO15,  &pm8058_pldo, "vdd_l14_l15" },
 775        { "l16",  QCOM_RPM_PM8058_LDO16,  &pm8058_pldo, "vdd_l13_l16" },
 776        { "l17",  QCOM_RPM_PM8058_LDO17,  &pm8058_pldo, "vdd_l17_l18" },
 777        { "l18",  QCOM_RPM_PM8058_LDO18,  &pm8058_pldo, "vdd_l17_l18" },
 778        { "l19",  QCOM_RPM_PM8058_LDO19,  &pm8058_pldo, "vdd_l19_l20" },
 779        { "l20",  QCOM_RPM_PM8058_LDO20,  &pm8058_pldo, "vdd_l19_l20" },
 780        { "l21",  QCOM_RPM_PM8058_LDO21,  &pm8058_nldo, "vdd_l21" },
 781        { "l22",  QCOM_RPM_PM8058_LDO22,  &pm8058_nldo, "vdd_l22" },
 782        { "l23",  QCOM_RPM_PM8058_LDO23,  &pm8058_nldo, "vdd_l23_l24_l25" },
 783        { "l24",  QCOM_RPM_PM8058_LDO24,  &pm8058_nldo, "vdd_l23_l24_l25" },
 784        { "l25",  QCOM_RPM_PM8058_LDO25,  &pm8058_nldo, "vdd_l23_l24_l25" },
 785
 786        { "s0",   QCOM_RPM_PM8058_SMPS0,  &pm8058_smps, "vdd_s0" },
 787        { "s1",   QCOM_RPM_PM8058_SMPS1,  &pm8058_smps, "vdd_s1" },
 788        { "s2",   QCOM_RPM_PM8058_SMPS2,  &pm8058_smps, "vdd_s2" },
 789        { "s3",   QCOM_RPM_PM8058_SMPS3,  &pm8058_smps, "vdd_s3" },
 790        { "s4",   QCOM_RPM_PM8058_SMPS4,  &pm8058_smps, "vdd_s4" },
 791
 792        { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
 793        { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
 794
 795        { "ncp",  QCOM_RPM_PM8058_NCP, &pm8058_ncp, "vdd_ncp" },
 796        { }
 797};
 798
 799static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
 800        { "l0",   QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
 801        { "l1",   QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
 802        { "l2",   QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
 803        { "l3",   QCOM_RPM_PM8901_LDO3, &pm8901_pldo, "vdd_l3" },
 804        { "l4",   QCOM_RPM_PM8901_LDO4, &pm8901_pldo, "vdd_l4" },
 805        { "l5",   QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
 806        { "l6",   QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
 807
 808        { "s0",   QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
 809        { "s1",   QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
 810        { "s2",   QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
 811        { "s3",   QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
 812        { "s4",   QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
 813
 814        { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
 815        { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
 816        { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
 817        { "lvs3", QCOM_RPM_PM8901_LVS3, &pm8901_switch, "lvs3_in" },
 818
 819        { "mvs", QCOM_RPM_PM8901_MVS, &pm8901_switch, "mvs_in" },
 820        { }
 821};
 822
 823static const struct rpm_regulator_data rpm_pm8921_regulators[] = {
 824        { "s1",  QCOM_RPM_PM8921_SMPS1, &pm8921_smps, "vdd_s1" },
 825        { "s2",  QCOM_RPM_PM8921_SMPS2, &pm8921_smps, "vdd_s2" },
 826        { "s3",  QCOM_RPM_PM8921_SMPS3, &pm8921_smps },
 827        { "s4",  QCOM_RPM_PM8921_SMPS4, &pm8921_smps, "vdd_s4" },
 828        { "s7",  QCOM_RPM_PM8921_SMPS7, &pm8921_smps, "vdd_s7" },
 829        { "s8",  QCOM_RPM_PM8921_SMPS8, &pm8921_smps, "vdd_s8"  },
 830
 831        { "l1",  QCOM_RPM_PM8921_LDO1, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
 832        { "l2",  QCOM_RPM_PM8921_LDO2, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
 833        { "l3",  QCOM_RPM_PM8921_LDO3, &pm8921_pldo, "vdd_l3_l15_l17" },
 834        { "l4",  QCOM_RPM_PM8921_LDO4, &pm8921_pldo, "vdd_l4_l14" },
 835        { "l5",  QCOM_RPM_PM8921_LDO5, &pm8921_pldo, "vdd_l5_l8_l16" },
 836        { "l6",  QCOM_RPM_PM8921_LDO6, &pm8921_pldo, "vdd_l6_l7" },
 837        { "l7",  QCOM_RPM_PM8921_LDO7, &pm8921_pldo, "vdd_l6_l7" },
 838        { "l8",  QCOM_RPM_PM8921_LDO8, &pm8921_pldo, "vdd_l5_l8_l16" },
 839        { "l9",  QCOM_RPM_PM8921_LDO9, &pm8921_pldo, "vdd_l9_l11" },
 840        { "l10", QCOM_RPM_PM8921_LDO10, &pm8921_pldo, "vdd_l10_l22" },
 841        { "l11", QCOM_RPM_PM8921_LDO11, &pm8921_pldo, "vdd_l9_l11" },
 842        { "l12", QCOM_RPM_PM8921_LDO12, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
 843        { "l14", QCOM_RPM_PM8921_LDO14, &pm8921_pldo, "vdd_l4_l14" },
 844        { "l15", QCOM_RPM_PM8921_LDO15, &pm8921_pldo, "vdd_l3_l15_l17" },
 845        { "l16", QCOM_RPM_PM8921_LDO16, &pm8921_pldo, "vdd_l5_l8_l16" },
 846        { "l17", QCOM_RPM_PM8921_LDO17, &pm8921_pldo, "vdd_l3_l15_l17" },
 847        { "l18", QCOM_RPM_PM8921_LDO18, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
 848        { "l21", QCOM_RPM_PM8921_LDO21, &pm8921_pldo, "vdd_l21_l23_l29" },
 849        { "l22", QCOM_RPM_PM8921_LDO22, &pm8921_pldo, "vdd_l10_l22" },
 850        { "l23", QCOM_RPM_PM8921_LDO23, &pm8921_pldo, "vdd_l21_l23_l29" },
 851        { "l24", QCOM_RPM_PM8921_LDO24, &pm8921_nldo1200, "vdd_l24" },
 852        { "l25", QCOM_RPM_PM8921_LDO25, &pm8921_nldo1200, "vdd_l25" },
 853        { "l26", QCOM_RPM_PM8921_LDO26, &pm8921_nldo1200, "vdd_l26" },
 854        { "l27", QCOM_RPM_PM8921_LDO27, &pm8921_nldo1200, "vdd_l27" },
 855        { "l28", QCOM_RPM_PM8921_LDO28, &pm8921_nldo1200, "vdd_l28" },
 856        { "l29", QCOM_RPM_PM8921_LDO29, &pm8921_pldo, "vdd_l21_l23_l29" },
 857
 858        { "lvs1", QCOM_RPM_PM8921_LVS1, &pm8921_switch, "vin_lvs1_3_6" },
 859        { "lvs2", QCOM_RPM_PM8921_LVS2, &pm8921_switch, "vin_lvs2" },
 860        { "lvs3", QCOM_RPM_PM8921_LVS3, &pm8921_switch, "vin_lvs1_3_6" },
 861        { "lvs4", QCOM_RPM_PM8921_LVS4, &pm8921_switch, "vin_lvs4_5_7" },
 862        { "lvs5", QCOM_RPM_PM8921_LVS5, &pm8921_switch, "vin_lvs4_5_7" },
 863        { "lvs6", QCOM_RPM_PM8921_LVS6, &pm8921_switch, "vin_lvs1_3_6" },
 864        { "lvs7", QCOM_RPM_PM8921_LVS7, &pm8921_switch, "vin_lvs4_5_7" },
 865
 866        { "usb-switch", QCOM_RPM_USB_OTG_SWITCH, &pm8921_switch, "vin_5vs" },
 867        { "hdmi-switch", QCOM_RPM_HDMI_SWITCH, &pm8921_switch, "vin_5vs" },
 868        { "ncp", QCOM_RPM_PM8921_NCP, &pm8921_ncp, "vdd_ncp" },
 869        { }
 870};
 871
 872static const struct of_device_id rpm_of_match[] = {
 873        { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
 874        { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
 875        { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
 876        { }
 877};
 878MODULE_DEVICE_TABLE(of, rpm_of_match);
 879
 880static int rpm_reg_probe(struct platform_device *pdev)
 881{
 882        const struct rpm_regulator_data *reg;
 883        const struct of_device_id *match;
 884        struct regulator_config config = { };
 885        struct regulator_dev *rdev;
 886        struct qcom_rpm_reg *vreg;
 887        struct qcom_rpm *rpm;
 888
 889        rpm = dev_get_drvdata(pdev->dev.parent);
 890        if (!rpm) {
 891                dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
 892                return -ENODEV;
 893        }
 894
 895        match = of_match_device(rpm_of_match, &pdev->dev);
 896        for (reg = match->data; reg->name; reg++) {
 897                vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 898                if (!vreg)
 899                        return -ENOMEM;
 900
 901                memcpy(vreg, reg->template, sizeof(*vreg));
 902                mutex_init(&vreg->lock);
 903
 904                vreg->dev = &pdev->dev;
 905                vreg->resource = reg->resource;
 906                vreg->rpm = rpm;
 907
 908                vreg->desc.id = -1;
 909                vreg->desc.owner = THIS_MODULE;
 910                vreg->desc.type = REGULATOR_VOLTAGE;
 911                vreg->desc.name = reg->name;
 912                vreg->desc.supply_name = reg->supply;
 913                vreg->desc.of_match = reg->name;
 914                vreg->desc.of_parse_cb = rpm_reg_of_parse;
 915
 916                config.dev = &pdev->dev;
 917                config.driver_data = vreg;
 918                rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
 919                if (IS_ERR(rdev)) {
 920                        dev_err(&pdev->dev, "failed to register %s\n", reg->name);
 921                        return PTR_ERR(rdev);
 922                }
 923        }
 924
 925        return 0;
 926}
 927
 928static struct platform_driver rpm_reg_driver = {
 929        .probe          = rpm_reg_probe,
 930        .driver  = {
 931                .name  = "qcom_rpm_reg",
 932                .of_match_table = of_match_ptr(rpm_of_match),
 933        },
 934};
 935
 936static int __init rpm_reg_init(void)
 937{
 938        return platform_driver_register(&rpm_reg_driver);
 939}
 940subsys_initcall(rpm_reg_init);
 941
 942static void __exit rpm_reg_exit(void)
 943{
 944        platform_driver_unregister(&rpm_reg_driver);
 945}
 946module_exit(rpm_reg_exit)
 947
 948MODULE_DESCRIPTION("Qualcomm RPM regulator driver");
 949MODULE_LICENSE("GPL v2");
 950