linux/drivers/regulator/qcom_smd-regulator.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015, 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/of.h>
  17#include <linux/of_device.h>
  18#include <linux/platform_device.h>
  19#include <linux/regulator/driver.h>
  20#include <linux/soc/qcom/smd-rpm.h>
  21
  22struct qcom_rpm_reg {
  23        struct device *dev;
  24
  25        struct qcom_smd_rpm *rpm;
  26
  27        u32 type;
  28        u32 id;
  29
  30        struct regulator_desc desc;
  31
  32        int is_enabled;
  33        int uV;
  34};
  35
  36struct rpm_regulator_req {
  37        __le32 key;
  38        __le32 nbytes;
  39        __le32 value;
  40};
  41
  42#define RPM_KEY_SWEN    0x6e657773 /* "swen" */
  43#define RPM_KEY_UV      0x00007675 /* "uv" */
  44#define RPM_KEY_MA      0x0000616d /* "ma" */
  45
  46static int rpm_reg_write_active(struct qcom_rpm_reg *vreg,
  47                                struct rpm_regulator_req *req,
  48                                size_t size)
  49{
  50        return qcom_rpm_smd_write(vreg->rpm,
  51                                  QCOM_SMD_RPM_ACTIVE_STATE,
  52                                  vreg->type,
  53                                  vreg->id,
  54                                  req, size);
  55}
  56
  57static int rpm_reg_enable(struct regulator_dev *rdev)
  58{
  59        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  60        struct rpm_regulator_req req;
  61        int ret;
  62
  63        req.key = cpu_to_le32(RPM_KEY_SWEN);
  64        req.nbytes = cpu_to_le32(sizeof(u32));
  65        req.value = cpu_to_le32(1);
  66
  67        ret = rpm_reg_write_active(vreg, &req, sizeof(req));
  68        if (!ret)
  69                vreg->is_enabled = 1;
  70
  71        return ret;
  72}
  73
  74static int rpm_reg_is_enabled(struct regulator_dev *rdev)
  75{
  76        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  77
  78        return vreg->is_enabled;
  79}
  80
  81static int rpm_reg_disable(struct regulator_dev *rdev)
  82{
  83        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
  84        struct rpm_regulator_req req;
  85        int ret;
  86
  87        req.key = cpu_to_le32(RPM_KEY_SWEN);
  88        req.nbytes = cpu_to_le32(sizeof(u32));
  89        req.value = 0;
  90
  91        ret = rpm_reg_write_active(vreg, &req, sizeof(req));
  92        if (!ret)
  93                vreg->is_enabled = 0;
  94
  95        return ret;
  96}
  97
  98static int rpm_reg_get_voltage(struct regulator_dev *rdev)
  99{
 100        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 101
 102        return vreg->uV;
 103}
 104
 105static int rpm_reg_set_voltage(struct regulator_dev *rdev,
 106                               int min_uV,
 107                               int max_uV,
 108                               unsigned *selector)
 109{
 110        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 111        struct rpm_regulator_req req;
 112        int ret = 0;
 113
 114        req.key = cpu_to_le32(RPM_KEY_UV);
 115        req.nbytes = cpu_to_le32(sizeof(u32));
 116        req.value = cpu_to_le32(min_uV);
 117
 118        ret = rpm_reg_write_active(vreg, &req, sizeof(req));
 119        if (!ret)
 120                vreg->uV = min_uV;
 121
 122        return ret;
 123}
 124
 125static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
 126{
 127        struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
 128        struct rpm_regulator_req req;
 129
 130        req.key = cpu_to_le32(RPM_KEY_MA);
 131        req.nbytes = cpu_to_le32(sizeof(u32));
 132        req.value = cpu_to_le32(load_uA / 1000);
 133
 134        return rpm_reg_write_active(vreg, &req, sizeof(req));
 135}
 136
 137static const struct regulator_ops rpm_smps_ldo_ops = {
 138        .enable = rpm_reg_enable,
 139        .disable = rpm_reg_disable,
 140        .is_enabled = rpm_reg_is_enabled,
 141        .list_voltage = regulator_list_voltage_linear_range,
 142
 143        .get_voltage = rpm_reg_get_voltage,
 144        .set_voltage = rpm_reg_set_voltage,
 145
 146        .set_load = rpm_reg_set_load,
 147};
 148
 149static const struct regulator_ops rpm_smps_ldo_ops_fixed = {
 150        .enable = rpm_reg_enable,
 151        .disable = rpm_reg_disable,
 152        .is_enabled = rpm_reg_is_enabled,
 153
 154        .get_voltage = rpm_reg_get_voltage,
 155        .set_voltage = rpm_reg_set_voltage,
 156
 157        .set_load = rpm_reg_set_load,
 158};
 159
 160static const struct regulator_ops rpm_switch_ops = {
 161        .enable = rpm_reg_enable,
 162        .disable = rpm_reg_disable,
 163        .is_enabled = rpm_reg_is_enabled,
 164};
 165
 166static const struct regulator_ops rpm_bob_ops = {
 167        .enable = rpm_reg_enable,
 168        .disable = rpm_reg_disable,
 169        .is_enabled = rpm_reg_is_enabled,
 170
 171        .get_voltage = rpm_reg_get_voltage,
 172        .set_voltage = rpm_reg_set_voltage,
 173};
 174
 175static const struct regulator_desc pma8084_hfsmps = {
 176        .linear_ranges = (struct regulator_linear_range[]) {
 177                REGULATOR_LINEAR_RANGE(375000,  0,  95, 12500),
 178                REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
 179        },
 180        .n_linear_ranges = 2,
 181        .n_voltages = 159,
 182        .ops = &rpm_smps_ldo_ops,
 183};
 184
 185static const struct regulator_desc pma8084_ftsmps = {
 186        .linear_ranges = (struct regulator_linear_range[]) {
 187                REGULATOR_LINEAR_RANGE(350000,  0, 184, 5000),
 188                REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
 189        },
 190        .n_linear_ranges = 2,
 191        .n_voltages = 262,
 192        .ops = &rpm_smps_ldo_ops,
 193};
 194
 195static const struct regulator_desc pma8084_pldo = {
 196        .linear_ranges = (struct regulator_linear_range[]) {
 197                REGULATOR_LINEAR_RANGE( 750000,  0,  63, 12500),
 198                REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
 199                REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
 200        },
 201        .n_linear_ranges = 3,
 202        .n_voltages = 164,
 203        .ops = &rpm_smps_ldo_ops,
 204};
 205
 206static const struct regulator_desc pma8084_nldo = {
 207        .linear_ranges = (struct regulator_linear_range[]) {
 208                REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
 209        },
 210        .n_linear_ranges = 1,
 211        .n_voltages = 64,
 212        .ops = &rpm_smps_ldo_ops,
 213};
 214
 215static const struct regulator_desc pma8084_switch = {
 216        .ops = &rpm_switch_ops,
 217};
 218
 219static const struct regulator_desc pm8x41_hfsmps = {
 220        .linear_ranges = (struct regulator_linear_range[]) {
 221                REGULATOR_LINEAR_RANGE( 375000,  0,  95, 12500),
 222                REGULATOR_LINEAR_RANGE(1575000, 96, 158, 25000),
 223        },
 224        .n_linear_ranges = 2,
 225        .n_voltages = 159,
 226        .ops = &rpm_smps_ldo_ops,
 227};
 228
 229static const struct regulator_desc pm8841_ftsmps = {
 230        .linear_ranges = (struct regulator_linear_range[]) {
 231                REGULATOR_LINEAR_RANGE(350000,  0, 184, 5000),
 232                REGULATOR_LINEAR_RANGE(1280000, 185, 261, 10000),
 233        },
 234        .n_linear_ranges = 2,
 235        .n_voltages = 262,
 236        .ops = &rpm_smps_ldo_ops,
 237};
 238
 239static const struct regulator_desc pm8941_boost = {
 240        .linear_ranges = (struct regulator_linear_range[]) {
 241                REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000),
 242        },
 243        .n_linear_ranges = 1,
 244        .n_voltages = 31,
 245        .ops = &rpm_smps_ldo_ops,
 246};
 247
 248static const struct regulator_desc pm8941_pldo = {
 249        .linear_ranges = (struct regulator_linear_range[]) {
 250                REGULATOR_LINEAR_RANGE( 750000,  0,  63, 12500),
 251                REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
 252                REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
 253        },
 254        .n_linear_ranges = 3,
 255        .n_voltages = 164,
 256        .ops = &rpm_smps_ldo_ops,
 257};
 258
 259static const struct regulator_desc pm8941_nldo = {
 260        .linear_ranges = (struct regulator_linear_range[]) {
 261                REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
 262        },
 263        .n_linear_ranges = 1,
 264        .n_voltages = 64,
 265        .ops = &rpm_smps_ldo_ops,
 266};
 267
 268static const struct regulator_desc pm8941_lnldo = {
 269        .fixed_uV = 1740000,
 270        .n_voltages = 1,
 271        .ops = &rpm_smps_ldo_ops_fixed,
 272};
 273
 274static const struct regulator_desc pm8941_switch = {
 275        .ops = &rpm_switch_ops,
 276};
 277
 278static const struct regulator_desc pm8916_pldo = {
 279        .linear_ranges = (struct regulator_linear_range[]) {
 280                REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500),
 281        },
 282        .n_linear_ranges = 1,
 283        .n_voltages = 209,
 284        .ops = &rpm_smps_ldo_ops,
 285};
 286
 287static const struct regulator_desc pm8916_nldo = {
 288        .linear_ranges = (struct regulator_linear_range[]) {
 289                REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500),
 290        },
 291        .n_linear_ranges = 1,
 292        .n_voltages = 94,
 293        .ops = &rpm_smps_ldo_ops,
 294};
 295
 296static const struct regulator_desc pm8916_buck_lvo_smps = {
 297        .linear_ranges = (struct regulator_linear_range[]) {
 298                REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500),
 299                REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000),
 300        },
 301        .n_linear_ranges = 2,
 302        .n_voltages = 128,
 303        .ops = &rpm_smps_ldo_ops,
 304};
 305
 306static const struct regulator_desc pm8916_buck_hvo_smps = {
 307        .linear_ranges = (struct regulator_linear_range[]) {
 308                REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000),
 309        },
 310        .n_linear_ranges = 1,
 311        .n_voltages = 32,
 312        .ops = &rpm_smps_ldo_ops,
 313};
 314
 315static const struct regulator_desc pm8994_hfsmps = {
 316        .linear_ranges = (struct regulator_linear_range[]) {
 317                REGULATOR_LINEAR_RANGE( 375000,  0,  95, 12500),
 318                REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
 319        },
 320        .n_linear_ranges = 2,
 321        .n_voltages = 159,
 322        .ops = &rpm_smps_ldo_ops,
 323};
 324
 325static const struct regulator_desc pm8994_ftsmps = {
 326        .linear_ranges = (struct regulator_linear_range[]) {
 327                REGULATOR_LINEAR_RANGE(350000,  0, 199, 5000),
 328                REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000),
 329        },
 330        .n_linear_ranges = 2,
 331        .n_voltages = 350,
 332        .ops = &rpm_smps_ldo_ops,
 333};
 334
 335static const struct regulator_desc pm8994_nldo = {
 336        .linear_ranges = (struct regulator_linear_range[]) {
 337                REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
 338        },
 339        .n_linear_ranges = 1,
 340        .n_voltages = 64,
 341        .ops = &rpm_smps_ldo_ops,
 342};
 343
 344static const struct regulator_desc pm8994_pldo = {
 345        .linear_ranges = (struct regulator_linear_range[]) {
 346                REGULATOR_LINEAR_RANGE( 750000,  0,  63, 12500),
 347                REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
 348                REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
 349        },
 350        .n_linear_ranges = 3,
 351        .n_voltages = 164,
 352        .ops = &rpm_smps_ldo_ops,
 353};
 354
 355static const struct regulator_desc pm8994_switch = {
 356        .ops = &rpm_switch_ops,
 357};
 358
 359static const struct regulator_desc pm8994_lnldo = {
 360        .fixed_uV = 1740000,
 361        .n_voltages = 1,
 362        .ops = &rpm_smps_ldo_ops_fixed,
 363};
 364
 365static const struct regulator_desc pm8998_ftsmps = {
 366        .linear_ranges = (struct regulator_linear_range[]) {
 367                REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
 368        },
 369        .n_linear_ranges = 1,
 370        .n_voltages = 259,
 371        .ops = &rpm_smps_ldo_ops,
 372};
 373
 374static const struct regulator_desc pm8998_hfsmps = {
 375        .linear_ranges = (struct regulator_linear_range[]) {
 376                REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
 377        },
 378        .n_linear_ranges = 1,
 379        .n_voltages = 216,
 380        .ops = &rpm_smps_ldo_ops,
 381};
 382
 383static const struct regulator_desc pm8998_nldo = {
 384        .linear_ranges = (struct regulator_linear_range[]) {
 385                REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
 386        },
 387        .n_linear_ranges = 1,
 388        .n_voltages = 128,
 389        .ops = &rpm_smps_ldo_ops,
 390};
 391
 392static const struct regulator_desc pm8998_pldo = {
 393        .linear_ranges = (struct regulator_linear_range[]) {
 394                REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
 395        },
 396        .n_linear_ranges = 1,
 397        .n_voltages = 256,
 398        .ops = &rpm_smps_ldo_ops,
 399};
 400
 401static const struct regulator_desc pm8998_pldo_lv = {
 402        .linear_ranges = (struct regulator_linear_range[]) {
 403                REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
 404        },
 405        .n_linear_ranges = 1,
 406        .n_voltages = 128,
 407        .ops = &rpm_smps_ldo_ops,
 408};
 409
 410static const struct regulator_desc pm8998_switch = {
 411        .ops = &rpm_switch_ops,
 412};
 413
 414static const struct regulator_desc pmi8998_bob = {
 415        .linear_ranges = (struct regulator_linear_range[]) {
 416                REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
 417        },
 418        .n_linear_ranges = 1,
 419        .n_voltages = 84,
 420        .ops = &rpm_bob_ops,
 421};
 422
 423struct rpm_regulator_data {
 424        const char *name;
 425        u32 type;
 426        u32 id;
 427        const struct regulator_desc *desc;
 428        const char *supply;
 429};
 430
 431static const struct rpm_regulator_data rpm_pm8841_regulators[] = {
 432        { "s1", QCOM_SMD_RPM_SMPB, 1, &pm8x41_hfsmps, "vdd_s1" },
 433        { "s2", QCOM_SMD_RPM_SMPB, 2, &pm8841_ftsmps, "vdd_s2" },
 434        { "s3", QCOM_SMD_RPM_SMPB, 3, &pm8x41_hfsmps, "vdd_s3" },
 435        { "s4", QCOM_SMD_RPM_SMPB, 4, &pm8841_ftsmps, "vdd_s4" },
 436        { "s5", QCOM_SMD_RPM_SMPB, 5, &pm8841_ftsmps, "vdd_s5" },
 437        { "s6", QCOM_SMD_RPM_SMPB, 6, &pm8841_ftsmps, "vdd_s6" },
 438        { "s7", QCOM_SMD_RPM_SMPB, 7, &pm8841_ftsmps, "vdd_s7" },
 439        { "s8", QCOM_SMD_RPM_SMPB, 8, &pm8841_ftsmps, "vdd_s8" },
 440        {}
 441};
 442
 443static const struct rpm_regulator_data rpm_pm8916_regulators[] = {
 444        { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8916_buck_lvo_smps, "vdd_s1" },
 445        { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8916_buck_lvo_smps, "vdd_s2" },
 446        { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8916_buck_lvo_smps, "vdd_s3" },
 447        { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8916_buck_hvo_smps, "vdd_s4" },
 448        { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8916_nldo, "vdd_l1_l2_l3" },
 449        { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8916_nldo, "vdd_l1_l2_l3" },
 450        { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8916_nldo, "vdd_l1_l2_l3" },
 451        { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8916_pldo, "vdd_l4_l5_l6" },
 452        { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8916_pldo, "vdd_l4_l5_l6" },
 453        { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8916_pldo, "vdd_l4_l5_l6" },
 454        { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8916_pldo, "vdd_l7" },
 455        { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" },
 456        { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" },
 457        { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 458        { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 459        { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 460        { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 461        { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 462        { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 463        { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 464        { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 465        { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"},
 466        {}
 467};
 468
 469static const struct rpm_regulator_data rpm_pm8941_regulators[] = {
 470        { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" },
 471        { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" },
 472        { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8x41_hfsmps, "vdd_s3" },
 473        { "s4", QCOM_SMD_RPM_BOOST, 1, &pm8941_boost },
 474
 475        { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8941_nldo, "vdd_l1_l3" },
 476        { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8941_nldo, "vdd_l2_lvs1_2_3" },
 477        { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8941_nldo, "vdd_l1_l3" },
 478        { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8941_nldo, "vdd_l4_l11" },
 479        { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8941_lnldo, "vdd_l5_l7" },
 480        { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
 481        { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8941_lnldo, "vdd_l5_l7" },
 482        { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
 483        { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
 484        { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
 485        { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8941_nldo, "vdd_l4_l11" },
 486        { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
 487        { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
 488        { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
 489        { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8941_pldo, "vdd_l6_l12_l14_l15" },
 490        { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
 491        { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
 492        { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
 493        { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8941_pldo, "vdd_l8_l16_l18_l19" },
 494        { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
 495        { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8941_pldo, "vdd_l21" },
 496        { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8941_pldo, "vdd_l9_l10_l17_l22" },
 497        { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
 498        { "l24", QCOM_SMD_RPM_LDOA, 24, &pm8941_pldo, "vdd_l13_l20_l23_l24" },
 499
 500        { "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8941_switch, "vdd_l2_lvs1_2_3" },
 501        { "lvs2", QCOM_SMD_RPM_VSA, 2, &pm8941_switch, "vdd_l2_lvs1_2_3" },
 502        { "lvs3", QCOM_SMD_RPM_VSA, 3, &pm8941_switch, "vdd_l2_lvs1_2_3" },
 503
 504        { "5vs1", QCOM_SMD_RPM_VSA, 4, &pm8941_switch, "vin_5vs" },
 505        { "5vs2", QCOM_SMD_RPM_VSA, 5, &pm8941_switch, "vin_5vs" },
 506
 507        {}
 508};
 509
 510static const struct rpm_regulator_data rpm_pma8084_regulators[] = {
 511        { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" },
 512        { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" },
 513        { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" },
 514        { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" },
 515        { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" },
 516        { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" },
 517        { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" },
 518        { "s8", QCOM_SMD_RPM_SMPA, 8, &pma8084_ftsmps, "vdd_s8" },
 519        { "s9", QCOM_SMD_RPM_SMPA, 9, &pma8084_ftsmps, "vdd_s9" },
 520        { "s10", QCOM_SMD_RPM_SMPA, 10, &pma8084_ftsmps, "vdd_s10" },
 521        { "s11", QCOM_SMD_RPM_SMPA, 11, &pma8084_ftsmps, "vdd_s11" },
 522        { "s12", QCOM_SMD_RPM_SMPA, 12, &pma8084_ftsmps, "vdd_s12" },
 523
 524        { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" },
 525        { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
 526        { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
 527        { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
 528        { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" },
 529        { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
 530        { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" },
 531        { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" },
 532        { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 533        { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 534        { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" },
 535        { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
 536        { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 537        { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
 538        { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
 539        { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" },
 540        { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" },
 541        { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" },
 542        { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" },
 543        { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 544        { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" },
 545        { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" },
 546        { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 547        { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" },
 548        { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" },
 549        { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" },
 550        { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l2_l3_l4_l27" },
 551
 552        { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch },
 553        { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch },
 554        { "lvs3", QCOM_SMD_RPM_VSA, 3, &pma8084_switch },
 555        { "lvs4", QCOM_SMD_RPM_VSA, 4, &pma8084_switch },
 556        { "5vs1", QCOM_SMD_RPM_VSA, 5, &pma8084_switch },
 557
 558        {}
 559};
 560
 561static const struct rpm_regulator_data rpm_pm8994_regulators[] = {
 562        { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_ftsmps, "vdd_s1" },
 563        { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_ftsmps, "vdd_s2" },
 564        { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8994_hfsmps, "vdd_s3" },
 565        { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8994_hfsmps, "vdd_s4" },
 566        { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8994_hfsmps, "vdd_s5" },
 567        { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8994_ftsmps, "vdd_s6" },
 568        { "s7", QCOM_SMD_RPM_SMPA, 7, &pm8994_hfsmps, "vdd_s7" },
 569        { "s8", QCOM_SMD_RPM_SMPA, 8, &pm8994_ftsmps, "vdd_s8" },
 570        { "s9", QCOM_SMD_RPM_SMPA, 9, &pm8994_ftsmps, "vdd_s9" },
 571        { "s10", QCOM_SMD_RPM_SMPA, 10, &pm8994_ftsmps, "vdd_s10" },
 572        { "s11", QCOM_SMD_RPM_SMPA, 11, &pm8994_ftsmps, "vdd_s11" },
 573        { "s12", QCOM_SMD_RPM_SMPA, 12, &pm8994_ftsmps, "vdd_s12" },
 574        { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8994_nldo, "vdd_l1" },
 575        { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8994_nldo, "vdd_l2_l26_l28" },
 576        { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8994_nldo, "vdd_l3_l11" },
 577        { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8994_nldo, "vdd_l4_l27_l31" },
 578        { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8994_lnldo, "vdd_l5_l7" },
 579        { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8994_pldo, "vdd_l6_l12_l32" },
 580        { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8994_lnldo, "vdd_l5_l7" },
 581        { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8994_pldo, "vdd_l8_l16_l30" },
 582        { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
 583        { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
 584        { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8994_nldo, "vdd_l3_l11" },
 585        { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8994_pldo, "vdd_l6_l12_l32" },
 586        { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
 587        { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8994_pldo, "vdd_l14_l15" },
 588        { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8994_pldo, "vdd_l14_l15" },
 589        { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8994_pldo, "vdd_l8_l16_l30" },
 590        { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8994_pldo, "vdd_l17_l29" },
 591        { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
 592        { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
 593        { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8994_pldo, "vdd_l20_l21" },
 594        { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8994_pldo, "vdd_l20_l21" },
 595        { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
 596        { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
 597        { "l24", QCOM_SMD_RPM_LDOA, 24, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
 598        { "l25", QCOM_SMD_RPM_LDOA, 25, &pm8994_pldo, "vdd_l25" },
 599        { "l26", QCOM_SMD_RPM_LDOA, 26, &pm8994_nldo, "vdd_l2_l26_l28" },
 600        { "l27", QCOM_SMD_RPM_LDOA, 27, &pm8994_nldo, "vdd_l4_l27_l31" },
 601        { "l28", QCOM_SMD_RPM_LDOA, 28, &pm8994_nldo, "vdd_l2_l26_l28" },
 602        { "l29", QCOM_SMD_RPM_LDOA, 29, &pm8994_pldo, "vdd_l17_l29" },
 603        { "l30", QCOM_SMD_RPM_LDOA, 30, &pm8994_pldo, "vdd_l8_l16_l30" },
 604        { "l31", QCOM_SMD_RPM_LDOA, 31, &pm8994_nldo, "vdd_l4_l27_l31" },
 605        { "l32", QCOM_SMD_RPM_LDOA, 32, &pm8994_pldo, "vdd_l6_l12_l32" },
 606        { "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8994_switch, "vdd_lvs1_2" },
 607        { "lvs2", QCOM_SMD_RPM_VSA, 2, &pm8994_switch, "vdd_lvs1_2" },
 608
 609        {}
 610};
 611
 612static const struct rpm_regulator_data rpm_pm8998_regulators[] = {
 613        { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8998_ftsmps, "vdd_s1" },
 614        { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8998_ftsmps, "vdd_s2" },
 615        { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8998_hfsmps, "vdd_s3" },
 616        { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8998_hfsmps, "vdd_s4" },
 617        { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8998_hfsmps, "vdd_s5" },
 618        { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8998_ftsmps, "vdd_s6" },
 619        { "s7", QCOM_SMD_RPM_SMPA, 7, &pm8998_ftsmps, "vdd_s7" },
 620        { "s8", QCOM_SMD_RPM_SMPA, 8, &pm8998_ftsmps, "vdd_s8" },
 621        { "s9", QCOM_SMD_RPM_SMPA, 9, &pm8998_ftsmps, "vdd_s9" },
 622        { "s10", QCOM_SMD_RPM_SMPA, 10, &pm8998_ftsmps, "vdd_s10" },
 623        { "s11", QCOM_SMD_RPM_SMPA, 11, &pm8998_ftsmps, "vdd_s11" },
 624        { "s12", QCOM_SMD_RPM_SMPA, 12, &pm8998_ftsmps, "vdd_s12" },
 625        { "s13", QCOM_SMD_RPM_SMPA, 13, &pm8998_ftsmps, "vdd_s13" },
 626        { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8998_nldo, "vdd_l1_l27" },
 627        { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8998_nldo, "vdd_l2_l8_l17" },
 628        { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8998_nldo, "vdd_l3_l11" },
 629        { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8998_nldo, "vdd_l4_l5" },
 630        { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8998_nldo, "vdd_l4_l5" },
 631        { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8998_pldo, "vdd_l6" },
 632        { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8998_pldo_lv, "vdd_l7_l12_l14_l15" },
 633        { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8998_nldo, "vdd_l2_l8_l17" },
 634        { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8998_pldo, "vdd_l9" },
 635        { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8998_pldo, "vdd_l10_l23_l25" },
 636        { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8998_nldo, "vdd_l3_l11" },
 637        { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8998_pldo_lv, "vdd_l7_l12_l14_l15" },
 638        { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8998_pldo, "vdd_l13_l19_l21" },
 639        { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8998_pldo_lv, "vdd_l7_l12_l14_l15" },
 640        { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8998_pldo_lv, "vdd_l7_l12_l14_l15" },
 641        { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8998_pldo, "vdd_l16_l28" },
 642        { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8998_nldo, "vdd_l2_l8_l17" },
 643        { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8998_pldo, "vdd_l18_l22" },
 644        { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8998_pldo, "vdd_l13_l19_l21" },
 645        { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8998_pldo, "vdd_l20_l24" },
 646        { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8998_pldo, "vdd_l13_l19_l21" },
 647        { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8998_pldo, "vdd_l18_l22" },
 648        { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8998_pldo, "vdd_l10_l23_l25" },
 649        { "l24", QCOM_SMD_RPM_LDOA, 24, &pm8998_pldo, "vdd_l20_l24" },
 650        { "l25", QCOM_SMD_RPM_LDOA, 25, &pm8998_pldo, "vdd_l10_l23_l25" },
 651        { "l26", QCOM_SMD_RPM_LDOA, 26, &pm8998_nldo, "vdd_l26" },
 652        { "l27", QCOM_SMD_RPM_LDOA, 27, &pm8998_nldo, "vdd_l1_l27" },
 653        { "l28", QCOM_SMD_RPM_LDOA, 28, &pm8998_pldo, "vdd_l16_l28" },
 654        { "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8998_switch, "vdd_lvs1_lvs2" },
 655        { "lvs2", QCOM_SMD_RPM_VSA, 2, &pm8998_switch, "vdd_lvs1_lvs2" },
 656        {}
 657};
 658
 659static const struct rpm_regulator_data rpm_pmi8998_regulators[] = {
 660        { "bob", QCOM_SMD_RPM_BOBB, 1, &pmi8998_bob, "vdd_bob" },
 661        {}
 662};
 663
 664static const struct of_device_id rpm_of_match[] = {
 665        { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
 666        { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
 667        { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
 668        { .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators },
 669        { .compatible = "qcom,rpm-pm8998-regulators", .data = &rpm_pm8998_regulators },
 670        { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
 671        { .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_regulators },
 672        {}
 673};
 674MODULE_DEVICE_TABLE(of, rpm_of_match);
 675
 676static int rpm_reg_probe(struct platform_device *pdev)
 677{
 678        const struct rpm_regulator_data *reg;
 679        const struct of_device_id *match;
 680        struct regulator_config config = { };
 681        struct regulator_dev *rdev;
 682        struct qcom_rpm_reg *vreg;
 683        struct qcom_smd_rpm *rpm;
 684
 685        rpm = dev_get_drvdata(pdev->dev.parent);
 686        if (!rpm) {
 687                dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
 688                return -ENODEV;
 689        }
 690
 691        match = of_match_device(rpm_of_match, &pdev->dev);
 692        if (!match) {
 693                dev_err(&pdev->dev, "failed to match device\n");
 694                return -ENODEV;
 695        }
 696
 697        for (reg = match->data; reg->name; reg++) {
 698                vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
 699                if (!vreg)
 700                        return -ENOMEM;
 701
 702                vreg->dev = &pdev->dev;
 703                vreg->type = reg->type;
 704                vreg->id = reg->id;
 705                vreg->rpm = rpm;
 706
 707                memcpy(&vreg->desc, reg->desc, sizeof(vreg->desc));
 708
 709                vreg->desc.id = -1;
 710                vreg->desc.owner = THIS_MODULE;
 711                vreg->desc.type = REGULATOR_VOLTAGE;
 712                vreg->desc.name = reg->name;
 713                vreg->desc.supply_name = reg->supply;
 714                vreg->desc.of_match = reg->name;
 715
 716                config.dev = &pdev->dev;
 717                config.driver_data = vreg;
 718                rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
 719                if (IS_ERR(rdev)) {
 720                        dev_err(&pdev->dev, "failed to register %s\n", reg->name);
 721                        return PTR_ERR(rdev);
 722                }
 723        }
 724
 725        return 0;
 726}
 727
 728static struct platform_driver rpm_reg_driver = {
 729        .probe = rpm_reg_probe,
 730        .driver = {
 731                .name  = "qcom_rpm_smd_regulator",
 732                .of_match_table = rpm_of_match,
 733        },
 734};
 735
 736static int __init rpm_reg_init(void)
 737{
 738        return platform_driver_register(&rpm_reg_driver);
 739}
 740subsys_initcall(rpm_reg_init);
 741
 742static void __exit rpm_reg_exit(void)
 743{
 744        platform_driver_unregister(&rpm_reg_driver);
 745}
 746module_exit(rpm_reg_exit)
 747
 748MODULE_DESCRIPTION("Qualcomm RPM regulator driver");
 749MODULE_LICENSE("GPL v2");
 750