linux/drivers/regulator/tps6507x-regulator.c
<<
>>
Prefs
   1/*
   2 * tps6507x-regulator.c
   3 *
   4 * Regulator driver for TPS65073 PMIC
   5 *
   6 * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation version 2.
  11 *
  12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
  13 * whether express or implied; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/init.h>
  21#include <linux/err.h>
  22#include <linux/platform_device.h>
  23#include <linux/regulator/driver.h>
  24#include <linux/regulator/machine.h>
  25#include <linux/regulator/tps6507x.h>
  26#include <linux/delay.h>
  27#include <linux/slab.h>
  28#include <linux/mfd/tps6507x.h>
  29
  30/* DCDC's */
  31#define TPS6507X_DCDC_1                         0
  32#define TPS6507X_DCDC_2                         1
  33#define TPS6507X_DCDC_3                         2
  34/* LDOs */
  35#define TPS6507X_LDO_1                          3
  36#define TPS6507X_LDO_2                          4
  37
  38#define TPS6507X_MAX_REG_ID                     TPS6507X_LDO_2
  39
  40/* Number of step-down converters available */
  41#define TPS6507X_NUM_DCDC                       3
  42/* Number of LDO voltage regulators  available */
  43#define TPS6507X_NUM_LDO                        2
  44/* Number of total regulators available */
  45#define TPS6507X_NUM_REGULATOR          (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO)
  46
  47/* Supported voltage values for regulators (in milliVolts) */
  48static const u16 VDCDCx_VSEL_table[] = {
  49        725, 750, 775, 800,
  50        825, 850, 875, 900,
  51        925, 950, 975, 1000,
  52        1025, 1050, 1075, 1100,
  53        1125, 1150, 1175, 1200,
  54        1225, 1250, 1275, 1300,
  55        1325, 1350, 1375, 1400,
  56        1425, 1450, 1475, 1500,
  57        1550, 1600, 1650, 1700,
  58        1750, 1800, 1850, 1900,
  59        1950, 2000, 2050, 2100,
  60        2150, 2200, 2250, 2300,
  61        2350, 2400, 2450, 2500,
  62        2550, 2600, 2650, 2700,
  63        2750, 2800, 2850, 2900,
  64        3000, 3100, 3200, 3300,
  65};
  66
  67static const u16 LDO1_VSEL_table[] = {
  68        1000, 1100, 1200, 1250,
  69        1300, 1350, 1400, 1500,
  70        1600, 1800, 2500, 2750,
  71        2800, 3000, 3100, 3300,
  72};
  73
  74static const u16 LDO2_VSEL_table[] = {
  75        725, 750, 775, 800,
  76        825, 850, 875, 900,
  77        925, 950, 975, 1000,
  78        1025, 1050, 1075, 1100,
  79        1125, 1150, 1175, 1200,
  80        1225, 1250, 1275, 1300,
  81        1325, 1350, 1375, 1400,
  82        1425, 1450, 1475, 1500,
  83        1550, 1600, 1650, 1700,
  84        1750, 1800, 1850, 1900,
  85        1950, 2000, 2050, 2100,
  86        2150, 2200, 2250, 2300,
  87        2350, 2400, 2450, 2500,
  88        2550, 2600, 2650, 2700,
  89        2750, 2800, 2850, 2900,
  90        3000, 3100, 3200, 3300,
  91};
  92
  93struct tps_info {
  94        const char *name;
  95        unsigned min_uV;
  96        unsigned max_uV;
  97        u8 table_len;
  98        const u16 *table;
  99
 100        /* Does DCDC high or the low register defines output voltage? */
 101        bool defdcdc_default;
 102};
 103
 104static struct tps_info tps6507x_pmic_regs[] = {
 105        {
 106                .name = "VDCDC1",
 107                .min_uV = 725000,
 108                .max_uV = 3300000,
 109                .table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
 110                .table = VDCDCx_VSEL_table,
 111        },
 112        {
 113                .name = "VDCDC2",
 114                .min_uV = 725000,
 115                .max_uV = 3300000,
 116                .table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
 117                .table = VDCDCx_VSEL_table,
 118        },
 119        {
 120                .name = "VDCDC3",
 121                .min_uV = 725000,
 122                .max_uV = 3300000,
 123                .table_len = ARRAY_SIZE(VDCDCx_VSEL_table),
 124                .table = VDCDCx_VSEL_table,
 125        },
 126        {
 127                .name = "LDO1",
 128                .min_uV = 1000000,
 129                .max_uV = 3300000,
 130                .table_len = ARRAY_SIZE(LDO1_VSEL_table),
 131                .table = LDO1_VSEL_table,
 132        },
 133        {
 134                .name = "LDO2",
 135                .min_uV = 725000,
 136                .max_uV = 3300000,
 137                .table_len = ARRAY_SIZE(LDO2_VSEL_table),
 138                .table = LDO2_VSEL_table,
 139        },
 140};
 141
 142struct tps6507x_pmic {
 143        struct regulator_desc desc[TPS6507X_NUM_REGULATOR];
 144        struct tps6507x_dev *mfd;
 145        struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR];
 146        struct tps_info *info[TPS6507X_NUM_REGULATOR];
 147        struct mutex io_lock;
 148};
 149static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg)
 150{
 151        u8 val;
 152        int err;
 153
 154        err = tps->mfd->read_dev(tps->mfd, reg, 1, &val);
 155
 156        if (err)
 157                return err;
 158
 159        return val;
 160}
 161
 162static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
 163{
 164        return tps->mfd->write_dev(tps->mfd, reg, 1, &val);
 165}
 166
 167static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
 168{
 169        int err, data;
 170
 171        mutex_lock(&tps->io_lock);
 172
 173        data = tps6507x_pmic_read(tps, reg);
 174        if (data < 0) {
 175                dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
 176                err = data;
 177                goto out;
 178        }
 179
 180        data |= mask;
 181        err = tps6507x_pmic_write(tps, reg, data);
 182        if (err)
 183                dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
 184
 185out:
 186        mutex_unlock(&tps->io_lock);
 187        return err;
 188}
 189
 190static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask)
 191{
 192        int err, data;
 193
 194        mutex_lock(&tps->io_lock);
 195
 196        data = tps6507x_pmic_read(tps, reg);
 197        if (data < 0) {
 198                dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
 199                err = data;
 200                goto out;
 201        }
 202
 203        data &= ~mask;
 204        err = tps6507x_pmic_write(tps, reg, data);
 205        if (err)
 206                dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
 207
 208out:
 209        mutex_unlock(&tps->io_lock);
 210        return err;
 211}
 212
 213static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg)
 214{
 215        int data;
 216
 217        mutex_lock(&tps->io_lock);
 218
 219        data = tps6507x_pmic_read(tps, reg);
 220        if (data < 0)
 221                dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg);
 222
 223        mutex_unlock(&tps->io_lock);
 224        return data;
 225}
 226
 227static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
 228{
 229        int err;
 230
 231        mutex_lock(&tps->io_lock);
 232
 233        err = tps6507x_pmic_write(tps, reg, val);
 234        if (err < 0)
 235                dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg);
 236
 237        mutex_unlock(&tps->io_lock);
 238        return err;
 239}
 240
 241static int tps6507x_pmic_is_enabled(struct regulator_dev *dev)
 242{
 243        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 244        int data, rid = rdev_get_id(dev);
 245        u8 shift;
 246
 247        if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
 248                return -EINVAL;
 249
 250        shift = TPS6507X_MAX_REG_ID - rid;
 251        data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
 252
 253        if (data < 0)
 254                return data;
 255        else
 256                return (data & 1<<shift) ? 1 : 0;
 257}
 258
 259static int tps6507x_pmic_enable(struct regulator_dev *dev)
 260{
 261        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 262        int rid = rdev_get_id(dev);
 263        u8 shift;
 264
 265        if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
 266                return -EINVAL;
 267
 268        shift = TPS6507X_MAX_REG_ID - rid;
 269        return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
 270}
 271
 272static int tps6507x_pmic_disable(struct regulator_dev *dev)
 273{
 274        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 275        int rid = rdev_get_id(dev);
 276        u8 shift;
 277
 278        if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
 279                return -EINVAL;
 280
 281        shift = TPS6507X_MAX_REG_ID - rid;
 282        return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
 283                                        1 << shift);
 284}
 285
 286static int tps6507x_pmic_get_voltage(struct regulator_dev *dev)
 287{
 288        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 289        int data, rid = rdev_get_id(dev);
 290        u8 reg, mask;
 291
 292        switch (rid) {
 293        case TPS6507X_DCDC_1:
 294                reg = TPS6507X_REG_DEFDCDC1;
 295                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 296                break;
 297        case TPS6507X_DCDC_2:
 298                if (tps->info[rid]->defdcdc_default)
 299                        reg = TPS6507X_REG_DEFDCDC2_HIGH;
 300                else
 301                        reg = TPS6507X_REG_DEFDCDC2_LOW;
 302                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 303                break;
 304        case TPS6507X_DCDC_3:
 305                if (tps->info[rid]->defdcdc_default)
 306                        reg = TPS6507X_REG_DEFDCDC3_HIGH;
 307                else
 308                        reg = TPS6507X_REG_DEFDCDC3_LOW;
 309                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 310                break;
 311        case TPS6507X_LDO_1:
 312                reg = TPS6507X_REG_LDO_CTRL1;
 313                mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK;
 314                break;
 315        case TPS6507X_LDO_2:
 316                reg = TPS6507X_REG_DEFLDO2;
 317                mask = TPS6507X_REG_DEFLDO2_LDO2_MASK;
 318                break;
 319        default:
 320                return -EINVAL;
 321        }
 322
 323        data = tps6507x_pmic_reg_read(tps, reg);
 324        if (data < 0)
 325                return data;
 326
 327        data &= mask;
 328        return tps->info[rid]->table[data] * 1000;
 329}
 330
 331static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev,
 332                                          unsigned selector)
 333{
 334        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 335        int data, rid = rdev_get_id(dev);
 336        u8 reg, mask;
 337
 338        switch (rid) {
 339        case TPS6507X_DCDC_1:
 340                reg = TPS6507X_REG_DEFDCDC1;
 341                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 342                break;
 343        case TPS6507X_DCDC_2:
 344                if (tps->info[rid]->defdcdc_default)
 345                        reg = TPS6507X_REG_DEFDCDC2_HIGH;
 346                else
 347                        reg = TPS6507X_REG_DEFDCDC2_LOW;
 348                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 349                break;
 350        case TPS6507X_DCDC_3:
 351                if (tps->info[rid]->defdcdc_default)
 352                        reg = TPS6507X_REG_DEFDCDC3_HIGH;
 353                else
 354                        reg = TPS6507X_REG_DEFDCDC3_LOW;
 355                mask = TPS6507X_DEFDCDCX_DCDC_MASK;
 356                break;
 357        case TPS6507X_LDO_1:
 358                reg = TPS6507X_REG_LDO_CTRL1;
 359                mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK;
 360                break;
 361        case TPS6507X_LDO_2:
 362                reg = TPS6507X_REG_DEFLDO2;
 363                mask = TPS6507X_REG_DEFLDO2_LDO2_MASK;
 364                break;
 365        default:
 366                return -EINVAL;
 367        }
 368
 369        data = tps6507x_pmic_reg_read(tps, reg);
 370        if (data < 0)
 371                return data;
 372
 373        data &= ~mask;
 374        data |= selector;
 375
 376        return tps6507x_pmic_reg_write(tps, reg, data);
 377}
 378
 379static int tps6507x_pmic_list_voltage(struct regulator_dev *dev,
 380                                        unsigned selector)
 381{
 382        struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
 383        int rid = rdev_get_id(dev);
 384
 385        if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
 386                return -EINVAL;
 387
 388        if (selector >= tps->info[rid]->table_len)
 389                return -EINVAL;
 390        else
 391                return tps->info[rid]->table[selector] * 1000;
 392}
 393
 394static struct regulator_ops tps6507x_pmic_ops = {
 395        .is_enabled = tps6507x_pmic_is_enabled,
 396        .enable = tps6507x_pmic_enable,
 397        .disable = tps6507x_pmic_disable,
 398        .get_voltage = tps6507x_pmic_get_voltage,
 399        .set_voltage_sel = tps6507x_pmic_set_voltage_sel,
 400        .list_voltage = tps6507x_pmic_list_voltage,
 401};
 402
 403static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
 404{
 405        struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
 406        struct tps_info *info = &tps6507x_pmic_regs[0];
 407        struct regulator_init_data *init_data;
 408        struct regulator_dev *rdev;
 409        struct tps6507x_pmic *tps;
 410        struct tps6507x_board *tps_board;
 411        int i;
 412        int error;
 413
 414        /**
 415         * tps_board points to pmic related constants
 416         * coming from the board-evm file.
 417         */
 418
 419        tps_board = dev_get_platdata(tps6507x_dev->dev);
 420        if (!tps_board)
 421                return -EINVAL;
 422
 423        /**
 424         * init_data points to array of regulator_init structures
 425         * coming from the board-evm file.
 426         */
 427        init_data = tps_board->tps6507x_pmic_init_data;
 428        if (!init_data)
 429                return -EINVAL;
 430
 431        tps = kzalloc(sizeof(*tps), GFP_KERNEL);
 432        if (!tps)
 433                return -ENOMEM;
 434
 435        mutex_init(&tps->io_lock);
 436
 437        /* common for all regulators */
 438        tps->mfd = tps6507x_dev;
 439
 440        for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) {
 441                /* Register the regulators */
 442                tps->info[i] = info;
 443                if (init_data->driver_data) {
 444                        struct tps6507x_reg_platform_data *data =
 445                                                        init_data->driver_data;
 446                        tps->info[i]->defdcdc_default = data->defdcdc_default;
 447                }
 448
 449                tps->desc[i].name = info->name;
 450                tps->desc[i].id = i;
 451                tps->desc[i].n_voltages = info->table_len;
 452                tps->desc[i].ops = &tps6507x_pmic_ops;
 453                tps->desc[i].type = REGULATOR_VOLTAGE;
 454                tps->desc[i].owner = THIS_MODULE;
 455
 456                rdev = regulator_register(&tps->desc[i],
 457                                        tps6507x_dev->dev, init_data, tps, NULL);
 458                if (IS_ERR(rdev)) {
 459                        dev_err(tps6507x_dev->dev,
 460                                "failed to register %s regulator\n",
 461                                pdev->name);
 462                        error = PTR_ERR(rdev);
 463                        goto fail;
 464                }
 465
 466                /* Save regulator for cleanup */
 467                tps->rdev[i] = rdev;
 468        }
 469
 470        tps6507x_dev->pmic = tps;
 471        platform_set_drvdata(pdev, tps6507x_dev);
 472
 473        return 0;
 474
 475fail:
 476        while (--i >= 0)
 477                regulator_unregister(tps->rdev[i]);
 478
 479        kfree(tps);
 480        return error;
 481}
 482
 483static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
 484{
 485        struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
 486        struct tps6507x_pmic *tps = tps6507x_dev->pmic;
 487        int i;
 488
 489        for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
 490                regulator_unregister(tps->rdev[i]);
 491
 492        kfree(tps);
 493
 494        return 0;
 495}
 496
 497static struct platform_driver tps6507x_pmic_driver = {
 498        .driver = {
 499                .name = "tps6507x-pmic",
 500                .owner = THIS_MODULE,
 501        },
 502        .probe = tps6507x_pmic_probe,
 503        .remove = __devexit_p(tps6507x_pmic_remove),
 504};
 505
 506static int __init tps6507x_pmic_init(void)
 507{
 508        return platform_driver_register(&tps6507x_pmic_driver);
 509}
 510subsys_initcall(tps6507x_pmic_init);
 511
 512static void __exit tps6507x_pmic_cleanup(void)
 513{
 514        platform_driver_unregister(&tps6507x_pmic_driver);
 515}
 516module_exit(tps6507x_pmic_cleanup);
 517
 518MODULE_AUTHOR("Texas Instruments");
 519MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
 520MODULE_LICENSE("GPL v2");
 521MODULE_ALIAS("platform:tps6507x-pmic");
 522