linux/drivers/regulator/ab3100.c
<<
>>
Prefs
   1/*
   2 * drivers/regulator/ab3100.c
   3 *
   4 * Copyright (C) 2008-2009 ST-Ericsson AB
   5 * License terms: GNU General Public License (GPL) version 2
   6 * Low-level control of the AB3100 IC Low Dropout (LDO)
   7 * regulators, external regulator and buck converter
   8 * Author: Mattias Wallin <mattias.wallin@stericsson.com>
   9 * Author: Linus Walleij <linus.walleij@stericsson.com>
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/err.h>
  16#include <linux/platform_device.h>
  17#include <linux/regulator/driver.h>
  18#include <linux/mfd/abx500.h>
  19
  20/* LDO registers and some handy masking definitions for AB3100 */
  21#define AB3100_LDO_A            0x40
  22#define AB3100_LDO_C            0x41
  23#define AB3100_LDO_D            0x42
  24#define AB3100_LDO_E            0x43
  25#define AB3100_LDO_E_SLEEP      0x44
  26#define AB3100_LDO_F            0x45
  27#define AB3100_LDO_G            0x46
  28#define AB3100_LDO_H            0x47
  29#define AB3100_LDO_H_SLEEP_MODE 0
  30#define AB3100_LDO_H_SLEEP_EN   2
  31#define AB3100_LDO_ON           4
  32#define AB3100_LDO_H_VSEL_AC    5
  33#define AB3100_LDO_K            0x48
  34#define AB3100_LDO_EXT          0x49
  35#define AB3100_BUCK             0x4A
  36#define AB3100_BUCK_SLEEP       0x4B
  37#define AB3100_REG_ON_MASK      0x10
  38
  39/**
  40 * struct ab3100_regulator
  41 * A struct passed around the individual regulator functions
  42 * @platform_device: platform device holding this regulator
  43 * @dev: handle to the device
  44 * @plfdata: AB3100 platform data passed in at probe time
  45 * @regreg: regulator register number in the AB3100
  46 */
  47struct ab3100_regulator {
  48        struct regulator_dev *rdev;
  49        struct device *dev;
  50        struct ab3100_platform_data *plfdata;
  51        u8 regreg;
  52};
  53
  54/* The order in which registers are initialized */
  55static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = {
  56        AB3100_LDO_A,
  57        AB3100_LDO_C,
  58        AB3100_LDO_E,
  59        AB3100_LDO_E_SLEEP,
  60        AB3100_LDO_F,
  61        AB3100_LDO_G,
  62        AB3100_LDO_H,
  63        AB3100_LDO_K,
  64        AB3100_LDO_EXT,
  65        AB3100_BUCK,
  66        AB3100_BUCK_SLEEP,
  67        AB3100_LDO_D,
  68};
  69
  70/* Preset (hardware defined) voltages for these regulators */
  71#define LDO_A_VOLTAGE 2750000
  72#define LDO_C_VOLTAGE 2650000
  73#define LDO_D_VOLTAGE 2650000
  74
  75static const unsigned int ldo_e_buck_typ_voltages[] = {
  76        1800000,
  77        1400000,
  78        1300000,
  79        1200000,
  80        1100000,
  81        1050000,
  82        900000,
  83};
  84
  85static const unsigned int ldo_f_typ_voltages[] = {
  86        1800000,
  87        1400000,
  88        1300000,
  89        1200000,
  90        1100000,
  91        1050000,
  92        2500000,
  93        2650000,
  94};
  95
  96static const unsigned int ldo_g_typ_voltages[] = {
  97        2850000,
  98        2750000,
  99        1800000,
 100        1500000,
 101};
 102
 103static const unsigned int ldo_h_typ_voltages[] = {
 104        2750000,
 105        1800000,
 106        1500000,
 107        1200000,
 108};
 109
 110static const unsigned int ldo_k_typ_voltages[] = {
 111        2750000,
 112        1800000,
 113};
 114
 115
 116/* The regulator devices */
 117static struct ab3100_regulator
 118ab3100_regulators[AB3100_NUM_REGULATORS] = {
 119        {
 120                .regreg = AB3100_LDO_A,
 121        },
 122        {
 123                .regreg = AB3100_LDO_C,
 124        },
 125        {
 126                .regreg = AB3100_LDO_D,
 127        },
 128        {
 129                .regreg = AB3100_LDO_E,
 130        },
 131        {
 132                .regreg = AB3100_LDO_F,
 133        },
 134        {
 135                .regreg = AB3100_LDO_G,
 136        },
 137        {
 138                .regreg = AB3100_LDO_H,
 139        },
 140        {
 141                .regreg = AB3100_LDO_K,
 142        },
 143        {
 144                .regreg = AB3100_LDO_EXT,
 145                /* No voltages for the external regulator */
 146        },
 147        {
 148                .regreg = AB3100_BUCK,
 149        },
 150};
 151
 152/*
 153 * General functions for enable, disable and is_enabled used for
 154 * LDO: A,C,E,F,G,H,K,EXT and BUCK
 155 */
 156static int ab3100_enable_regulator(struct regulator_dev *reg)
 157{
 158        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 159        int err;
 160        u8 regval;
 161
 162        err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg,
 163                                                &regval);
 164        if (err) {
 165                dev_warn(&reg->dev, "failed to get regid %d value\n",
 166                         abreg->regreg);
 167                return err;
 168        }
 169
 170        /* The regulator is already on, no reason to go further */
 171        if (regval & AB3100_REG_ON_MASK)
 172                return 0;
 173
 174        regval |= AB3100_REG_ON_MASK;
 175
 176        err = abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg,
 177                                                regval);
 178        if (err) {
 179                dev_warn(&reg->dev, "failed to set regid %d value\n",
 180                         abreg->regreg);
 181                return err;
 182        }
 183
 184        return 0;
 185}
 186
 187static int ab3100_disable_regulator(struct regulator_dev *reg)
 188{
 189        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 190        int err;
 191        u8 regval;
 192
 193        /*
 194         * LDO D is a special regulator. When it is disabled, the entire
 195         * system is shut down. So this is handled specially.
 196         */
 197        pr_info("Called ab3100_disable_regulator\n");
 198        if (abreg->regreg == AB3100_LDO_D) {
 199                dev_info(&reg->dev, "disabling LDO D - shut down system\n");
 200                /* Setting LDO D to 0x00 cuts the power to the SoC */
 201                return abx500_set_register_interruptible(abreg->dev, 0,
 202                                                         AB3100_LDO_D, 0x00U);
 203        }
 204
 205        /*
 206         * All other regulators are handled here
 207         */
 208        err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg,
 209                                                &regval);
 210        if (err) {
 211                dev_err(&reg->dev, "unable to get register 0x%x\n",
 212                        abreg->regreg);
 213                return err;
 214        }
 215        regval &= ~AB3100_REG_ON_MASK;
 216        return abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg,
 217                                                 regval);
 218}
 219
 220static int ab3100_is_enabled_regulator(struct regulator_dev *reg)
 221{
 222        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 223        u8 regval;
 224        int err;
 225
 226        err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg,
 227                                                &regval);
 228        if (err) {
 229                dev_err(&reg->dev, "unable to get register 0x%x\n",
 230                        abreg->regreg);
 231                return err;
 232        }
 233
 234        return regval & AB3100_REG_ON_MASK;
 235}
 236
 237static int ab3100_get_voltage_regulator(struct regulator_dev *reg)
 238{
 239        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 240        u8 regval;
 241        int err;
 242
 243        /*
 244         * For variable types, read out setting and index into
 245         * supplied voltage list.
 246         */
 247        err = abx500_get_register_interruptible(abreg->dev, 0,
 248                                                abreg->regreg, &regval);
 249        if (err) {
 250                dev_warn(&reg->dev,
 251                         "failed to get regulator value in register %02x\n",
 252                         abreg->regreg);
 253                return err;
 254        }
 255
 256        /* The 3 highest bits index voltages */
 257        regval &= 0xE0;
 258        regval >>= 5;
 259
 260        if (regval >= reg->desc->n_voltages) {
 261                dev_err(&reg->dev,
 262                        "regulator register %02x contains an illegal voltage setting\n",
 263                        abreg->regreg);
 264                return -EINVAL;
 265        }
 266
 267        return reg->desc->volt_table[regval];
 268}
 269
 270static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg,
 271                                            unsigned selector)
 272{
 273        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 274        u8 regval;
 275        int err;
 276
 277        err = abx500_get_register_interruptible(abreg->dev, 0,
 278                                                abreg->regreg, &regval);
 279        if (err) {
 280                dev_warn(&reg->dev,
 281                         "failed to get regulator register %02x\n",
 282                         abreg->regreg);
 283                return err;
 284        }
 285
 286        /* The highest three bits control the variable regulators */
 287        regval &= ~0xE0;
 288        regval |= (selector << 5);
 289
 290        err = abx500_set_register_interruptible(abreg->dev, 0,
 291                                                abreg->regreg, regval);
 292        if (err)
 293                dev_warn(&reg->dev, "failed to set regulator register %02x\n",
 294                        abreg->regreg);
 295
 296        return err;
 297}
 298
 299static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg,
 300                                                int uV)
 301{
 302        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 303        u8 regval;
 304        int err;
 305        int bestindex;
 306        u8 targetreg;
 307
 308        if (abreg->regreg == AB3100_LDO_E)
 309                targetreg = AB3100_LDO_E_SLEEP;
 310        else if (abreg->regreg == AB3100_BUCK)
 311                targetreg = AB3100_BUCK_SLEEP;
 312        else
 313                return -EINVAL;
 314
 315        /* LDO E and BUCK have special suspend voltages you can set */
 316        bestindex = regulator_map_voltage_iterate(reg, uV, uV);
 317
 318        err = abx500_get_register_interruptible(abreg->dev, 0,
 319                                                targetreg, &regval);
 320        if (err) {
 321                dev_warn(&reg->dev,
 322                         "failed to get regulator register %02x\n",
 323                         targetreg);
 324                return err;
 325        }
 326
 327        /* The highest three bits control the variable regulators */
 328        regval &= ~0xE0;
 329        regval |= (bestindex << 5);
 330
 331        err = abx500_set_register_interruptible(abreg->dev, 0,
 332                                                targetreg, regval);
 333        if (err)
 334                dev_warn(&reg->dev, "failed to set regulator register %02x\n",
 335                        abreg->regreg);
 336
 337        return err;
 338}
 339
 340/*
 341 * The external regulator can just define a fixed voltage.
 342 */
 343static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
 344{
 345        struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
 346
 347        return abreg->plfdata->external_voltage;
 348}
 349
 350static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg)
 351{
 352        return reg->desc->min_uV;
 353}
 354
 355static struct regulator_ops regulator_ops_fixed = {
 356        .list_voltage = regulator_list_voltage_linear,
 357        .enable      = ab3100_enable_regulator,
 358        .disable     = ab3100_disable_regulator,
 359        .is_enabled  = ab3100_is_enabled_regulator,
 360        .get_voltage = ab3100_get_fixed_voltage_regulator,
 361};
 362
 363static struct regulator_ops regulator_ops_variable = {
 364        .enable      = ab3100_enable_regulator,
 365        .disable     = ab3100_disable_regulator,
 366        .is_enabled  = ab3100_is_enabled_regulator,
 367        .get_voltage = ab3100_get_voltage_regulator,
 368        .set_voltage_sel = ab3100_set_voltage_regulator_sel,
 369        .list_voltage = regulator_list_voltage_table,
 370};
 371
 372static struct regulator_ops regulator_ops_variable_sleepable = {
 373        .enable      = ab3100_enable_regulator,
 374        .disable     = ab3100_disable_regulator,
 375        .is_enabled  = ab3100_is_enabled_regulator,
 376        .get_voltage = ab3100_get_voltage_regulator,
 377        .set_voltage_sel = ab3100_set_voltage_regulator_sel,
 378        .set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
 379        .list_voltage = regulator_list_voltage_table,
 380};
 381
 382/*
 383 * LDO EXT is an external regulator so it is really
 384 * not possible to set any voltage locally here, AB3100
 385 * is an on/off switch plain an simple. The external
 386 * voltage is defined in the board set-up if any.
 387 */
 388static struct regulator_ops regulator_ops_external = {
 389        .enable      = ab3100_enable_regulator,
 390        .disable     = ab3100_disable_regulator,
 391        .is_enabled  = ab3100_is_enabled_regulator,
 392        .get_voltage = ab3100_get_voltage_regulator_external,
 393};
 394
 395static struct regulator_desc
 396ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
 397        {
 398                .name = "LDO_A",
 399                .id   = AB3100_LDO_A,
 400                .ops  = &regulator_ops_fixed,
 401                .n_voltages = 1,
 402                .type = REGULATOR_VOLTAGE,
 403                .owner = THIS_MODULE,
 404                .min_uV = LDO_A_VOLTAGE,
 405                .enable_time = 200,
 406        },
 407        {
 408                .name = "LDO_C",
 409                .id   = AB3100_LDO_C,
 410                .ops  = &regulator_ops_fixed,
 411                .n_voltages = 1,
 412                .type = REGULATOR_VOLTAGE,
 413                .owner = THIS_MODULE,
 414                .min_uV = LDO_C_VOLTAGE,
 415                .enable_time = 200,
 416        },
 417        {
 418                .name = "LDO_D",
 419                .id   = AB3100_LDO_D,
 420                .ops  = &regulator_ops_fixed,
 421                .n_voltages = 1,
 422                .type = REGULATOR_VOLTAGE,
 423                .owner = THIS_MODULE,
 424                .min_uV = LDO_D_VOLTAGE,
 425                .enable_time = 200,
 426        },
 427        {
 428                .name = "LDO_E",
 429                .id   = AB3100_LDO_E,
 430                .ops  = &regulator_ops_variable_sleepable,
 431                .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
 432                .volt_table = ldo_e_buck_typ_voltages,
 433                .type = REGULATOR_VOLTAGE,
 434                .owner = THIS_MODULE,
 435                .enable_time = 200,
 436        },
 437        {
 438                .name = "LDO_F",
 439                .id   = AB3100_LDO_F,
 440                .ops  = &regulator_ops_variable,
 441                .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages),
 442                .volt_table = ldo_f_typ_voltages,
 443                .type = REGULATOR_VOLTAGE,
 444                .owner = THIS_MODULE,
 445                .enable_time = 600,
 446        },
 447        {
 448                .name = "LDO_G",
 449                .id   = AB3100_LDO_G,
 450                .ops  = &regulator_ops_variable,
 451                .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages),
 452                .volt_table = ldo_g_typ_voltages,
 453                .type = REGULATOR_VOLTAGE,
 454                .owner = THIS_MODULE,
 455                .enable_time = 400,
 456        },
 457        {
 458                .name = "LDO_H",
 459                .id   = AB3100_LDO_H,
 460                .ops  = &regulator_ops_variable,
 461                .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages),
 462                .volt_table = ldo_h_typ_voltages,
 463                .type = REGULATOR_VOLTAGE,
 464                .owner = THIS_MODULE,
 465                .enable_time = 200,
 466        },
 467        {
 468                .name = "LDO_K",
 469                .id   = AB3100_LDO_K,
 470                .ops  = &regulator_ops_variable,
 471                .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages),
 472                .volt_table = ldo_k_typ_voltages,
 473                .type = REGULATOR_VOLTAGE,
 474                .owner = THIS_MODULE,
 475                .enable_time = 200,
 476        },
 477        {
 478                .name = "LDO_EXT",
 479                .id   = AB3100_LDO_EXT,
 480                .ops  = &regulator_ops_external,
 481                .type = REGULATOR_VOLTAGE,
 482                .owner = THIS_MODULE,
 483        },
 484        {
 485                .name = "BUCK",
 486                .id   = AB3100_BUCK,
 487                .ops  = &regulator_ops_variable_sleepable,
 488                .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
 489                .volt_table = ldo_e_buck_typ_voltages,
 490                .type = REGULATOR_VOLTAGE,
 491                .owner = THIS_MODULE,
 492                .enable_time = 1000,
 493        },
 494};
 495
 496/*
 497 * NOTE: the following functions are regulators pluralis - it is the
 498 * binding to the AB3100 core driver and the parent platform device
 499 * for all the different regulators.
 500 */
 501
 502static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
 503{
 504        struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
 505        struct regulator_config config = { };
 506        int err = 0;
 507        u8 data;
 508        int i;
 509
 510        /* Check chip state */
 511        err = abx500_get_register_interruptible(&pdev->dev, 0,
 512                                                AB3100_LDO_D, &data);
 513        if (err) {
 514                dev_err(&pdev->dev, "could not read initial status of LDO_D\n");
 515                return err;
 516        }
 517        if (data & 0x10)
 518                dev_notice(&pdev->dev,
 519                           "chip is already in active mode (Warm start)\n");
 520        else
 521                dev_notice(&pdev->dev,
 522                           "chip is in inactive mode (Cold start)\n");
 523
 524        /* Set up regulators */
 525        for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
 526                err = abx500_set_register_interruptible(&pdev->dev, 0,
 527                                        ab3100_reg_init_order[i],
 528                                        plfdata->reg_initvals[i]);
 529                if (err) {
 530                        dev_err(&pdev->dev, "regulator initialization failed with error %d\n",
 531                                err);
 532                        return err;
 533                }
 534        }
 535
 536        /* Register the regulators */
 537        for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
 538                struct ab3100_regulator *reg = &ab3100_regulators[i];
 539                struct regulator_dev *rdev;
 540
 541                /*
 542                 * Initialize per-regulator struct.
 543                 * Inherit platform data, this comes down from the
 544                 * i2c boarddata, from the machine. So if you want to
 545                 * see what it looks like for a certain machine, go
 546                 * into the machine I2C setup.
 547                 */
 548                reg->dev = &pdev->dev;
 549                reg->plfdata = plfdata;
 550
 551                config.dev = &pdev->dev;
 552                config.driver_data = reg;
 553                config.init_data = &plfdata->reg_constraints[i];
 554
 555                /*
 556                 * Register the regulator, pass around
 557                 * the ab3100_regulator struct
 558                 */
 559                rdev = regulator_register(&ab3100_regulator_desc[i], &config);
 560                if (IS_ERR(rdev)) {
 561                        err = PTR_ERR(rdev);
 562                        dev_err(&pdev->dev,
 563                                "%s: failed to register regulator %s err %d\n",
 564                                __func__, ab3100_regulator_desc[i].name,
 565                                err);
 566                        /* remove the already registered regulators */
 567                        while (--i >= 0)
 568                                regulator_unregister(ab3100_regulators[i].rdev);
 569                        return err;
 570                }
 571
 572                /* Then set a pointer back to the registered regulator */
 573                reg->rdev = rdev;
 574        }
 575
 576        return 0;
 577}
 578
 579static int __devexit ab3100_regulators_remove(struct platform_device *pdev)
 580{
 581        int i;
 582
 583        for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
 584                struct ab3100_regulator *reg = &ab3100_regulators[i];
 585
 586                regulator_unregister(reg->rdev);
 587        }
 588        return 0;
 589}
 590
 591static struct platform_driver ab3100_regulators_driver = {
 592        .driver = {
 593                .name  = "ab3100-regulators",
 594                .owner = THIS_MODULE,
 595        },
 596        .probe = ab3100_regulators_probe,
 597        .remove = __devexit_p(ab3100_regulators_remove),
 598};
 599
 600static __init int ab3100_regulators_init(void)
 601{
 602        return platform_driver_register(&ab3100_regulators_driver);
 603}
 604
 605static __exit void ab3100_regulators_exit(void)
 606{
 607        platform_driver_unregister(&ab3100_regulators_driver);
 608}
 609
 610subsys_initcall(ab3100_regulators_init);
 611module_exit(ab3100_regulators_exit);
 612
 613MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
 614MODULE_DESCRIPTION("AB3100 Regulator driver");
 615MODULE_LICENSE("GPL");
 616MODULE_ALIAS("platform:ab3100-regulators");
 617
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.