linux/drivers/regulator/s2mps11.c
<<
>>
Prefs
   1/*
   2 * s2mps11.c
   3 *
   4 * Copyright (c) 2012 Samsung Electronics Co., Ltd
   5 *              http://www.samsung.com
   6 *
   7 *  This program is free software; you can redistribute  it and/or modify it
   8 *  under  the terms of  the GNU General  Public License as published by the
   9 *  Free Software Foundation;  either version 2 of the  License, or (at your
  10 *  option) any later version.
  11 *
  12 */
  13
  14#include <linux/bug.h>
  15#include <linux/err.h>
  16#include <linux/gpio.h>
  17#include <linux/slab.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/regmap.h>
  21#include <linux/platform_device.h>
  22#include <linux/regulator/driver.h>
  23#include <linux/regulator/machine.h>
  24#include <linux/regulator/of_regulator.h>
  25#include <linux/mfd/samsung/core.h>
  26#include <linux/mfd/samsung/s2mps11.h>
  27
  28#define S2MPS11_REGULATOR_CNT ARRAY_SIZE(regulators)
  29
  30struct s2mps11_info {
  31        struct regulator_dev *rdev[S2MPS11_REGULATOR_MAX];
  32
  33        int ramp_delay2;
  34        int ramp_delay34;
  35        int ramp_delay5;
  36        int ramp_delay16;
  37        int ramp_delay7810;
  38        int ramp_delay9;
  39};
  40
  41static int get_ramp_delay(int ramp_delay)
  42{
  43        unsigned char cnt = 0;
  44
  45        ramp_delay /= 6250;
  46
  47        while (true) {
  48                ramp_delay = ramp_delay >> 1;
  49                if (ramp_delay == 0)
  50                        break;
  51                cnt++;
  52        }
  53
  54        if (cnt > 3)
  55                cnt = 3;
  56
  57        return cnt;
  58}
  59
  60static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
  61                                   unsigned int old_selector,
  62                                   unsigned int new_selector)
  63{
  64        struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
  65        unsigned int ramp_delay = 0;
  66        int old_volt, new_volt;
  67
  68        switch (rdev->desc->id) {
  69        case S2MPS11_BUCK2:
  70                ramp_delay = s2mps11->ramp_delay2;
  71                break;
  72        case S2MPS11_BUCK3:
  73                ramp_delay = s2mps11->ramp_delay34;
  74                break;
  75        case S2MPS11_BUCK4:
  76                ramp_delay = s2mps11->ramp_delay34;
  77                break;
  78        case S2MPS11_BUCK5:
  79                ramp_delay = s2mps11->ramp_delay5;
  80                break;
  81        case S2MPS11_BUCK6:
  82        case S2MPS11_BUCK1:
  83                ramp_delay = s2mps11->ramp_delay16;
  84                break;
  85        case S2MPS11_BUCK7:
  86        case S2MPS11_BUCK8:
  87        case S2MPS11_BUCK10:
  88                ramp_delay = s2mps11->ramp_delay7810;
  89                break;
  90        case S2MPS11_BUCK9:
  91                ramp_delay = s2mps11->ramp_delay9;
  92        }
  93
  94        if (ramp_delay == 0)
  95                ramp_delay = rdev->desc->ramp_delay;
  96
  97        old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);
  98        new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);
  99
 100        return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
 101}
 102
 103static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 104{
 105        struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
 106        unsigned int ramp_val, ramp_shift, ramp_reg = S2MPS11_REG_RAMP_BUCK;
 107        unsigned int ramp_enable = 1, enable_shift = 0;
 108        int ret;
 109
 110        switch (rdev->desc->id) {
 111        case S2MPS11_BUCK1:
 112                if (ramp_delay > s2mps11->ramp_delay16)
 113                        s2mps11->ramp_delay16 = ramp_delay;
 114                else
 115                        ramp_delay = s2mps11->ramp_delay16;
 116
 117                ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT;
 118                break;
 119        case S2MPS11_BUCK2:
 120                enable_shift = S2MPS11_BUCK2_RAMP_EN_SHIFT;
 121                if (!ramp_delay) {
 122                        ramp_enable = 0;
 123                        break;
 124                }
 125
 126                s2mps11->ramp_delay2 = ramp_delay;
 127                ramp_shift = S2MPS11_BUCK2_RAMP_SHIFT;
 128                ramp_reg = S2MPS11_REG_RAMP;
 129                break;
 130        case S2MPS11_BUCK3:
 131                enable_shift = S2MPS11_BUCK3_RAMP_EN_SHIFT;
 132                if (!ramp_delay) {
 133                        ramp_enable = 0;
 134                        break;
 135                }
 136
 137                if (ramp_delay > s2mps11->ramp_delay34)
 138                        s2mps11->ramp_delay34 = ramp_delay;
 139                else
 140                        ramp_delay = s2mps11->ramp_delay34;
 141
 142                ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT;
 143                ramp_reg = S2MPS11_REG_RAMP;
 144                break;
 145        case S2MPS11_BUCK4:
 146                enable_shift = S2MPS11_BUCK4_RAMP_EN_SHIFT;
 147                if (!ramp_delay) {
 148                        ramp_enable = 0;
 149                        break;
 150                }
 151
 152                if (ramp_delay > s2mps11->ramp_delay34)
 153                        s2mps11->ramp_delay34 = ramp_delay;
 154                else
 155                        ramp_delay = s2mps11->ramp_delay34;
 156
 157                ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT;
 158                ramp_reg = S2MPS11_REG_RAMP;
 159                break;
 160        case S2MPS11_BUCK5:
 161                s2mps11->ramp_delay5 = ramp_delay;
 162                ramp_shift = S2MPS11_BUCK5_RAMP_SHIFT;
 163                break;
 164        case S2MPS11_BUCK6:
 165                enable_shift = S2MPS11_BUCK6_RAMP_EN_SHIFT;
 166                if (!ramp_delay) {
 167                        ramp_enable = 0;
 168                        break;
 169                }
 170
 171                if (ramp_delay > s2mps11->ramp_delay16)
 172                        s2mps11->ramp_delay16 = ramp_delay;
 173                else
 174                        ramp_delay = s2mps11->ramp_delay16;
 175
 176                ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT;
 177                break;
 178        case S2MPS11_BUCK7:
 179        case S2MPS11_BUCK8:
 180        case S2MPS11_BUCK10:
 181                if (ramp_delay > s2mps11->ramp_delay7810)
 182                        s2mps11->ramp_delay7810 = ramp_delay;
 183                else
 184                        ramp_delay = s2mps11->ramp_delay7810;
 185
 186                ramp_shift = S2MPS11_BUCK7810_RAMP_SHIFT;
 187                break;
 188        case S2MPS11_BUCK9:
 189                s2mps11->ramp_delay9 = ramp_delay;
 190                ramp_shift = S2MPS11_BUCK9_RAMP_SHIFT;
 191                break;
 192        default:
 193                return 0;
 194        }
 195
 196        if (!ramp_enable)
 197                goto ramp_disable;
 198
 199        if (enable_shift) {
 200                ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
 201                                        1 << enable_shift, 1 << enable_shift);
 202                if (ret) {
 203                        dev_err(&rdev->dev, "failed to enable ramp rate\n");
 204                        return ret;
 205                }
 206        }
 207
 208        ramp_val = get_ramp_delay(ramp_delay);
 209
 210        return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,
 211                                  ramp_val << ramp_shift);
 212
 213ramp_disable:
 214        return regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
 215                                  1 << enable_shift, 0);
 216}
 217
 218static struct regulator_ops s2mps11_ldo_ops = {
 219        .list_voltage           = regulator_list_voltage_linear,
 220        .map_voltage            = regulator_map_voltage_linear,
 221        .is_enabled             = regulator_is_enabled_regmap,
 222        .enable                 = regulator_enable_regmap,
 223        .disable                = regulator_disable_regmap,
 224        .get_voltage_sel        = regulator_get_voltage_sel_regmap,
 225        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
 226        .set_voltage_time_sel   = regulator_set_voltage_time_sel,
 227};
 228
 229static struct regulator_ops s2mps11_buck_ops = {
 230        .list_voltage           = regulator_list_voltage_linear,
 231        .map_voltage            = regulator_map_voltage_linear,
 232        .is_enabled             = regulator_is_enabled_regmap,
 233        .enable                 = regulator_enable_regmap,
 234        .disable                = regulator_disable_regmap,
 235        .get_voltage_sel        = regulator_get_voltage_sel_regmap,
 236        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
 237        .set_voltage_time_sel   = s2mps11_regulator_set_voltage_time_sel,
 238        .set_ramp_delay         = s2mps11_set_ramp_delay,
 239};
 240
 241#define regulator_desc_ldo1(num)        {               \
 242        .name           = "LDO"#num,                    \
 243        .id             = S2MPS11_LDO##num,             \
 244        .ops            = &s2mps11_ldo_ops,             \
 245        .type           = REGULATOR_VOLTAGE,            \
 246        .owner          = THIS_MODULE,                  \
 247        .min_uV         = S2MPS11_LDO_MIN,              \
 248        .uV_step        = S2MPS11_LDO_STEP1,            \
 249        .n_voltages     = S2MPS11_LDO_N_VOLTAGES,       \
 250        .vsel_reg       = S2MPS11_REG_L1CTRL + num - 1, \
 251        .vsel_mask      = S2MPS11_LDO_VSEL_MASK,        \
 252        .enable_reg     = S2MPS11_REG_L1CTRL + num - 1, \
 253        .enable_mask    = S2MPS11_ENABLE_MASK           \
 254}
 255#define regulator_desc_ldo2(num)        {               \
 256        .name           = "LDO"#num,                    \
 257        .id             = S2MPS11_LDO##num,             \
 258        .ops            = &s2mps11_ldo_ops,             \
 259        .type           = REGULATOR_VOLTAGE,            \
 260        .owner          = THIS_MODULE,                  \
 261        .min_uV         = S2MPS11_LDO_MIN,              \
 262        .uV_step        = S2MPS11_LDO_STEP2,            \
 263        .n_voltages     = S2MPS11_LDO_N_VOLTAGES,       \
 264        .vsel_reg       = S2MPS11_REG_L1CTRL + num - 1, \
 265        .vsel_mask      = S2MPS11_LDO_VSEL_MASK,        \
 266        .enable_reg     = S2MPS11_REG_L1CTRL + num - 1, \
 267        .enable_mask    = S2MPS11_ENABLE_MASK           \
 268}
 269
 270#define regulator_desc_buck1_4(num)     {                       \
 271        .name           = "BUCK"#num,                           \
 272        .id             = S2MPS11_BUCK##num,                    \
 273        .ops            = &s2mps11_buck_ops,                    \
 274        .type           = REGULATOR_VOLTAGE,                    \
 275        .owner          = THIS_MODULE,                          \
 276        .min_uV         = S2MPS11_BUCK_MIN1,                    \
 277        .uV_step        = S2MPS11_BUCK_STEP1,                   \
 278        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
 279        .ramp_delay     = S2MPS11_RAMP_DELAY,                   \
 280        .vsel_reg       = S2MPS11_REG_B1CTRL2 + (num - 1) * 2,  \
 281        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
 282        .enable_reg     = S2MPS11_REG_B1CTRL1 + (num - 1) * 2,  \
 283        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 284}
 285
 286#define regulator_desc_buck5    {                               \
 287        .name           = "BUCK5",                              \
 288        .id             = S2MPS11_BUCK5,                        \
 289        .ops            = &s2mps11_buck_ops,                    \
 290        .type           = REGULATOR_VOLTAGE,                    \
 291        .owner          = THIS_MODULE,                          \
 292        .min_uV         = S2MPS11_BUCK_MIN1,                    \
 293        .uV_step        = S2MPS11_BUCK_STEP1,                   \
 294        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
 295        .ramp_delay     = S2MPS11_RAMP_DELAY,                   \
 296        .vsel_reg       = S2MPS11_REG_B5CTRL2,                  \
 297        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
 298        .enable_reg     = S2MPS11_REG_B5CTRL1,                  \
 299        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 300}
 301
 302#define regulator_desc_buck6_8(num)     {                       \
 303        .name           = "BUCK"#num,                           \
 304        .id             = S2MPS11_BUCK##num,                    \
 305        .ops            = &s2mps11_buck_ops,                    \
 306        .type           = REGULATOR_VOLTAGE,                    \
 307        .owner          = THIS_MODULE,                          \
 308        .min_uV         = S2MPS11_BUCK_MIN1,                    \
 309        .uV_step        = S2MPS11_BUCK_STEP1,                   \
 310        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
 311        .ramp_delay     = S2MPS11_RAMP_DELAY,                   \
 312        .vsel_reg       = S2MPS11_REG_B6CTRL2 + (num - 6) * 2,  \
 313        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
 314        .enable_reg     = S2MPS11_REG_B6CTRL1 + (num - 6) * 2,  \
 315        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 316}
 317
 318#define regulator_desc_buck9    {                               \
 319        .name           = "BUCK9",                              \
 320        .id             = S2MPS11_BUCK9,                        \
 321        .ops            = &s2mps11_buck_ops,                    \
 322        .type           = REGULATOR_VOLTAGE,                    \
 323        .owner          = THIS_MODULE,                          \
 324        .min_uV         = S2MPS11_BUCK_MIN3,                    \
 325        .uV_step        = S2MPS11_BUCK_STEP3,                   \
 326        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
 327        .ramp_delay     = S2MPS11_RAMP_DELAY,                   \
 328        .vsel_reg       = S2MPS11_REG_B9CTRL2,                  \
 329        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
 330        .enable_reg     = S2MPS11_REG_B9CTRL1,                  \
 331        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 332}
 333
 334#define regulator_desc_buck10   {                               \
 335        .name           = "BUCK10",                             \
 336        .id             = S2MPS11_BUCK10,                       \
 337        .ops            = &s2mps11_buck_ops,                    \
 338        .type           = REGULATOR_VOLTAGE,                    \
 339        .owner          = THIS_MODULE,                          \
 340        .min_uV         = S2MPS11_BUCK_MIN2,                    \
 341        .uV_step        = S2MPS11_BUCK_STEP2,                   \
 342        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
 343        .ramp_delay     = S2MPS11_RAMP_DELAY,                   \
 344        .vsel_reg       = S2MPS11_REG_B10CTRL2,                 \
 345        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
 346        .enable_reg     = S2MPS11_REG_B10CTRL1,                 \
 347        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 348}
 349
 350static struct regulator_desc regulators[] = {
 351        regulator_desc_ldo2(1),
 352        regulator_desc_ldo1(2),
 353        regulator_desc_ldo1(3),
 354        regulator_desc_ldo1(4),
 355        regulator_desc_ldo1(5),
 356        regulator_desc_ldo2(6),
 357        regulator_desc_ldo1(7),
 358        regulator_desc_ldo1(8),
 359        regulator_desc_ldo1(9),
 360        regulator_desc_ldo1(10),
 361        regulator_desc_ldo2(11),
 362        regulator_desc_ldo1(12),
 363        regulator_desc_ldo1(13),
 364        regulator_desc_ldo1(14),
 365        regulator_desc_ldo1(15),
 366        regulator_desc_ldo1(16),
 367        regulator_desc_ldo1(17),
 368        regulator_desc_ldo1(18),
 369        regulator_desc_ldo1(19),
 370        regulator_desc_ldo1(20),
 371        regulator_desc_ldo1(21),
 372        regulator_desc_ldo2(22),
 373        regulator_desc_ldo2(23),
 374        regulator_desc_ldo1(24),
 375        regulator_desc_ldo1(25),
 376        regulator_desc_ldo1(26),
 377        regulator_desc_ldo2(27),
 378        regulator_desc_ldo1(28),
 379        regulator_desc_ldo1(29),
 380        regulator_desc_ldo1(30),
 381        regulator_desc_ldo1(31),
 382        regulator_desc_ldo1(32),
 383        regulator_desc_ldo1(33),
 384        regulator_desc_ldo1(34),
 385        regulator_desc_ldo1(35),
 386        regulator_desc_ldo1(36),
 387        regulator_desc_ldo1(37),
 388        regulator_desc_ldo1(38),
 389        regulator_desc_buck1_4(1),
 390        regulator_desc_buck1_4(2),
 391        regulator_desc_buck1_4(3),
 392        regulator_desc_buck1_4(4),
 393        regulator_desc_buck5,
 394        regulator_desc_buck6_8(6),
 395        regulator_desc_buck6_8(7),
 396        regulator_desc_buck6_8(8),
 397        regulator_desc_buck9,
 398        regulator_desc_buck10,
 399};
 400
 401static int s2mps11_pmic_probe(struct platform_device *pdev)
 402{
 403        struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 404        struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
 405        struct of_regulator_match rdata[S2MPS11_REGULATOR_MAX];
 406        struct device_node *reg_np = NULL;
 407        struct regulator_config config = { };
 408        struct s2mps11_info *s2mps11;
 409        int i, ret;
 410
 411        s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info),
 412                                GFP_KERNEL);
 413        if (!s2mps11)
 414                return -ENOMEM;
 415
 416        if (!iodev->dev->of_node) {
 417                if (pdata) {
 418                        goto common_reg;
 419                } else {
 420                        dev_err(pdev->dev.parent,
 421                                "Platform data or DT node not supplied\n");
 422                        return -ENODEV;
 423                }
 424        }
 425
 426        for (i = 0; i < S2MPS11_REGULATOR_CNT; i++)
 427                rdata[i].name = regulators[i].name;
 428
 429        reg_np = of_find_node_by_name(iodev->dev->of_node, "regulators");
 430        if (!reg_np) {
 431                dev_err(&pdev->dev, "could not find regulators sub-node\n");
 432                return -EINVAL;
 433        }
 434
 435        of_regulator_match(&pdev->dev, reg_np, rdata, S2MPS11_REGULATOR_MAX);
 436
 437common_reg:
 438        platform_set_drvdata(pdev, s2mps11);
 439
 440        config.dev = &pdev->dev;
 441        config.regmap = iodev->regmap;
 442        config.driver_data = s2mps11;
 443        for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) {
 444                if (!reg_np) {
 445                        config.init_data = pdata->regulators[i].initdata;
 446                } else {
 447                        config.init_data = rdata[i].init_data;
 448                        config.of_node = rdata[i].of_node;
 449                }
 450
 451                s2mps11->rdev[i] = regulator_register(&regulators[i], &config);
 452                if (IS_ERR(s2mps11->rdev[i])) {
 453                        ret = PTR_ERR(s2mps11->rdev[i]);
 454                        dev_err(&pdev->dev, "regulator init failed for %d\n",
 455                                i);
 456                        s2mps11->rdev[i] = NULL;
 457                        goto err;
 458                }
 459        }
 460
 461        return 0;
 462err:
 463        for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
 464                regulator_unregister(s2mps11->rdev[i]);
 465
 466        return ret;
 467}
 468
 469static int s2mps11_pmic_remove(struct platform_device *pdev)
 470{
 471        struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev);
 472        int i;
 473
 474        for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
 475                regulator_unregister(s2mps11->rdev[i]);
 476
 477        return 0;
 478}
 479
 480static const struct platform_device_id s2mps11_pmic_id[] = {
 481        { "s2mps11-pmic", 0},
 482        { },
 483};
 484MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
 485
 486static struct platform_driver s2mps11_pmic_driver = {
 487        .driver = {
 488                .name = "s2mps11-pmic",
 489                .owner = THIS_MODULE,
 490        },
 491        .probe = s2mps11_pmic_probe,
 492        .remove = s2mps11_pmic_remove,
 493        .id_table = s2mps11_pmic_id,
 494};
 495
 496static int __init s2mps11_pmic_init(void)
 497{
 498        return platform_driver_register(&s2mps11_pmic_driver);
 499}
 500subsys_initcall(s2mps11_pmic_init);
 501
 502static void __exit s2mps11_pmic_exit(void)
 503{
 504        platform_driver_unregister(&s2mps11_pmic_driver);
 505}
 506module_exit(s2mps11_pmic_exit);
 507
 508/* Module information */
 509MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
 510MODULE_DESCRIPTION("SAMSUNG S2MPS11 Regulator Driver");
 511MODULE_LICENSE("GPL");
 512
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.