linux/drivers/regulator/tps6586x-regulator.c
<<
>>
Prefs
   1/*
   2 * Regulator driver for TI TPS6586x
   3 *
   4 * Copyright (C) 2010 Compulab Ltd.
   5 * Author: Mike Rapoport <mike@compulab.co.il>
   6 *
   7 * Based on da903x
   8 * Copyright (C) 2006-2008 Marvell International Ltd.
   9 * Copyright (C) 2008 Compulab Ltd.
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/err.h>
  20#include <linux/of.h>
  21#include <linux/slab.h>
  22#include <linux/platform_device.h>
  23#include <linux/regulator/driver.h>
  24#include <linux/regulator/machine.h>
  25#include <linux/regulator/of_regulator.h>
  26#include <linux/mfd/tps6586x.h>
  27
  28/* supply control and voltage setting  */
  29#define TPS6586X_SUPPLYENA      0x10
  30#define TPS6586X_SUPPLYENB      0x11
  31#define TPS6586X_SUPPLYENC      0x12
  32#define TPS6586X_SUPPLYEND      0x13
  33#define TPS6586X_SUPPLYENE      0x14
  34#define TPS6586X_VCC1           0x20
  35#define TPS6586X_VCC2           0x21
  36#define TPS6586X_SM1V1          0x23
  37#define TPS6586X_SM1V2          0x24
  38#define TPS6586X_SM1SL          0x25
  39#define TPS6586X_SM0V1          0x26
  40#define TPS6586X_SM0V2          0x27
  41#define TPS6586X_SM0SL          0x28
  42#define TPS6586X_LDO2AV1        0x29
  43#define TPS6586X_LDO2AV2        0x2A
  44#define TPS6586X_LDO2BV1        0x2F
  45#define TPS6586X_LDO2BV2        0x30
  46#define TPS6586X_LDO4V1         0x32
  47#define TPS6586X_LDO4V2         0x33
  48
  49/* converter settings  */
  50#define TPS6586X_SUPPLYV1       0x41
  51#define TPS6586X_SUPPLYV2       0x42
  52#define TPS6586X_SUPPLYV3       0x43
  53#define TPS6586X_SUPPLYV4       0x44
  54#define TPS6586X_SUPPLYV5       0x45
  55#define TPS6586X_SUPPLYV6       0x46
  56#define TPS6586X_SMODE1         0x47
  57#define TPS6586X_SMODE2         0x48
  58
  59struct tps6586x_regulator {
  60        struct regulator_desc desc;
  61
  62        int enable_bit[2];
  63        int enable_reg[2];
  64
  65        /* for DVM regulators */
  66        int go_reg;
  67        int go_bit;
  68};
  69
  70static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
  71{
  72        return rdev_get_dev(rdev)->parent;
  73}
  74
  75static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
  76                                    unsigned selector)
  77{
  78        struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
  79        struct device *parent = to_tps6586x_dev(rdev);
  80        int ret, val, rid = rdev_get_id(rdev);
  81        uint8_t mask;
  82
  83        val = selector << (ffs(rdev->desc->vsel_mask) - 1);
  84        mask = rdev->desc->vsel_mask;
  85
  86        ret = tps6586x_update(parent, rdev->desc->vsel_reg, val, mask);
  87        if (ret)
  88                return ret;
  89
  90        /* Update go bit for DVM regulators */
  91        switch (rid) {
  92        case TPS6586X_ID_LDO_2:
  93        case TPS6586X_ID_LDO_4:
  94        case TPS6586X_ID_SM_0:
  95        case TPS6586X_ID_SM_1:
  96                ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
  97                break;
  98        }
  99        return ret;
 100}
 101
 102static struct regulator_ops tps6586x_regulator_ops = {
 103        .list_voltage = regulator_list_voltage_table,
 104        .get_voltage_sel = regulator_get_voltage_sel_regmap,
 105        .set_voltage_sel = tps6586x_set_voltage_sel,
 106
 107        .is_enabled = regulator_is_enabled_regmap,
 108        .enable = regulator_enable_regmap,
 109        .disable = regulator_disable_regmap,
 110};
 111
 112static struct regulator_ops tps6586x_sys_regulator_ops = {
 113};
 114
 115static const unsigned int tps6586x_ldo0_voltages[] = {
 116        1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
 117};
 118
 119static const unsigned int tps6586x_ldo4_voltages[] = {
 120        1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
 121        1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000,
 122        2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000,
 123        2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000,
 124};
 125
 126static const unsigned int tps6586x_ldo_voltages[] = {
 127        1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
 128};
 129
 130static const unsigned int tps6586x_sm2_voltages[] = {
 131        3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000,
 132        3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000,
 133        3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000,
 134        4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000,
 135};
 136
 137static const unsigned int tps6586x_dvm_voltages[] = {
 138         725000,  750000,  775000,  800000,  825000,  850000,  875000,  900000,
 139         925000,  950000,  975000, 1000000, 1025000, 1050000, 1075000, 1100000,
 140        1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
 141        1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
 142};
 143
 144#define TPS6586X_REGULATOR(_id, _pin_name, vdata, vreg, shift, nbits,   \
 145                           ereg0, ebit0, ereg1, ebit1)                  \
 146        .desc   = {                                                     \
 147                .supply_name = _pin_name,                               \
 148                .name   = "REG-" #_id,                                  \
 149                .ops    = &tps6586x_regulator_ops,                      \
 150                .type   = REGULATOR_VOLTAGE,                            \
 151                .id     = TPS6586X_ID_##_id,                            \
 152                .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages),  \
 153                .volt_table = tps6586x_##vdata##_voltages,              \
 154                .owner  = THIS_MODULE,                                  \
 155                .enable_reg = TPS6586X_SUPPLY##ereg0,                   \
 156                .enable_mask = 1 << (ebit0),                            \
 157                .vsel_reg = TPS6586X_##vreg,                            \
 158                .vsel_mask = ((1 << (nbits)) - 1) << (shift),           \
 159        },                                                              \
 160        .enable_reg[0]  = TPS6586X_SUPPLY##ereg0,                       \
 161        .enable_bit[0]  = (ebit0),                                      \
 162        .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
 163        .enable_bit[1]  = (ebit1),
 164
 165#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
 166        .go_reg = TPS6586X_##goreg,                                     \
 167        .go_bit = (gobit),
 168
 169#define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits,            \
 170                     ereg0, ebit0, ereg1, ebit1)                        \
 171{                                                                       \
 172        TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits,      \
 173                           ereg0, ebit0, ereg1, ebit1)                  \
 174}
 175
 176#define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits,            \
 177                     ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
 178{                                                                       \
 179        TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits,      \
 180                           ereg0, ebit0, ereg1, ebit1)                  \
 181        TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
 182}
 183
 184#define TPS6586X_SYS_REGULATOR()                                        \
 185{                                                                       \
 186        .desc   = {                                                     \
 187                .supply_name = "sys",                                   \
 188                .name   = "REG-SYS",                                    \
 189                .ops    = &tps6586x_sys_regulator_ops,                  \
 190                .type   = REGULATOR_VOLTAGE,                            \
 191                .id     = TPS6586X_ID_SYS,                              \
 192                .owner  = THIS_MODULE,                                  \
 193        },                                                              \
 194}
 195
 196static struct tps6586x_regulator tps6586x_regulator[] = {
 197        TPS6586X_SYS_REGULATOR(),
 198        TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0),
 199        TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2),
 200        TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
 201        TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
 202        TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
 203        TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
 204        TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
 205        TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
 206        TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
 207        TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
 208
 209        TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3,
 210                                        ENB, 3, VCC2, 6),
 211        TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3,
 212                                        END, 3, VCC1, 6),
 213        TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1,
 214                                        ENB, 1, VCC1, 2),
 215        TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0,
 216                                        ENB, 0, VCC1, 0),
 217};
 218
 219/*
 220 * TPS6586X has 2 enable bits that are OR'ed to determine the actual
 221 * regulator state. Clearing one of this bits allows switching
 222 * regulator on and of with single register write.
 223 */
 224static inline int tps6586x_regulator_preinit(struct device *parent,
 225                                             struct tps6586x_regulator *ri)
 226{
 227        uint8_t val1, val2;
 228        int ret;
 229
 230        if (ri->enable_reg[0] == ri->enable_reg[1] &&
 231            ri->enable_bit[0] == ri->enable_bit[1])
 232                        return 0;
 233
 234        ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
 235        if (ret)
 236                return ret;
 237
 238        ret = tps6586x_read(parent, ri->enable_reg[1], &val2);
 239        if (ret)
 240                return ret;
 241
 242        if (!(val2 & (1 << ri->enable_bit[1])))
 243                return 0;
 244
 245        /*
 246         * The regulator is on, but it's enabled with the bit we don't
 247         * want to use, so we switch the enable bits
 248         */
 249        if (!(val1 & (1 << ri->enable_bit[0]))) {
 250                ret = tps6586x_set_bits(parent, ri->enable_reg[0],
 251                                        1 << ri->enable_bit[0]);
 252                if (ret)
 253                        return ret;
 254        }
 255
 256        return tps6586x_clr_bits(parent, ri->enable_reg[1],
 257                                 1 << ri->enable_bit[1]);
 258}
 259
 260static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev,
 261                        int id, struct regulator_init_data *p)
 262{
 263        struct device *parent = pdev->dev.parent;
 264        struct tps6586x_settings *setting = p->driver_data;
 265        uint8_t reg;
 266
 267        if (setting == NULL)
 268                return 0;
 269
 270        if (!(setting->slew_rate & TPS6586X_SLEW_RATE_SET))
 271                return 0;
 272
 273        /* only SM0 and SM1 can have the slew rate settings */
 274        switch (id) {
 275        case TPS6586X_ID_SM_0:
 276                reg = TPS6586X_SM0SL;
 277                break;
 278        case TPS6586X_ID_SM_1:
 279                reg = TPS6586X_SM1SL;
 280                break;
 281        default:
 282                dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n");
 283                return -EINVAL;
 284        }
 285
 286        return tps6586x_write(parent, reg,
 287                        setting->slew_rate & TPS6586X_SLEW_RATE_MASK);
 288}
 289
 290static inline struct tps6586x_regulator *find_regulator_info(int id)
 291{
 292        struct tps6586x_regulator *ri;
 293        int i;
 294
 295        for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) {
 296                ri = &tps6586x_regulator[i];
 297                if (ri->desc.id == id)
 298                        return ri;
 299        }
 300        return NULL;
 301}
 302
 303#ifdef CONFIG_OF
 304static struct of_regulator_match tps6586x_matches[] = {
 305        { .name = "sys",     .driver_data = (void *)TPS6586X_ID_SYS     },
 306        { .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
 307        { .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
 308        { .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
 309        { .name = "ldo0",    .driver_data = (void *)TPS6586X_ID_LDO_0   },
 310        { .name = "ldo1",    .driver_data = (void *)TPS6586X_ID_LDO_1   },
 311        { .name = "ldo2",    .driver_data = (void *)TPS6586X_ID_LDO_2   },
 312        { .name = "ldo3",    .driver_data = (void *)TPS6586X_ID_LDO_3   },
 313        { .name = "ldo4",    .driver_data = (void *)TPS6586X_ID_LDO_4   },
 314        { .name = "ldo5",    .driver_data = (void *)TPS6586X_ID_LDO_5   },
 315        { .name = "ldo6",    .driver_data = (void *)TPS6586X_ID_LDO_6   },
 316        { .name = "ldo7",    .driver_data = (void *)TPS6586X_ID_LDO_7   },
 317        { .name = "ldo8",    .driver_data = (void *)TPS6586X_ID_LDO_8   },
 318        { .name = "ldo9",    .driver_data = (void *)TPS6586X_ID_LDO_9   },
 319        { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
 320};
 321
 322static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
 323                struct platform_device *pdev,
 324                struct of_regulator_match **tps6586x_reg_matches)
 325{
 326        const unsigned int num = ARRAY_SIZE(tps6586x_matches);
 327        struct device_node *np = pdev->dev.parent->of_node;
 328        struct device_node *regs;
 329        const char *sys_rail = NULL;
 330        unsigned int i;
 331        struct tps6586x_platform_data *pdata;
 332        int err;
 333
 334        regs = of_find_node_by_name(np, "regulators");
 335        if (!regs) {
 336                dev_err(&pdev->dev, "regulator node not found\n");
 337                return NULL;
 338        }
 339
 340        err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num);
 341        if (err < 0) {
 342                dev_err(&pdev->dev, "Regulator match failed, e %d\n", err);
 343                of_node_put(regs);
 344                return NULL;
 345        }
 346
 347        of_node_put(regs);
 348
 349        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 350        if (!pdata) {
 351                dev_err(&pdev->dev, "Memory alloction failed\n");
 352                return NULL;
 353        }
 354
 355        for (i = 0; i < num; i++) {
 356                int id;
 357                if (!tps6586x_matches[i].init_data)
 358                        continue;
 359
 360                pdata->reg_init_data[i] = tps6586x_matches[i].init_data;
 361                id = (int)tps6586x_matches[i].driver_data;
 362                if (id == TPS6586X_ID_SYS)
 363                        sys_rail = pdata->reg_init_data[i]->constraints.name;
 364
 365                if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC))
 366                        pdata->reg_init_data[i]->supply_regulator = sys_rail;
 367        }
 368        *tps6586x_reg_matches = tps6586x_matches;
 369        return pdata;
 370}
 371#else
 372static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
 373                struct platform_device *pdev,
 374                struct of_regulator_match **tps6586x_reg_matches)
 375{
 376        *tps6586x_reg_matches = NULL;
 377        return NULL;
 378}
 379#endif
 380
 381static int tps6586x_regulator_probe(struct platform_device *pdev)
 382{
 383        struct tps6586x_regulator *ri = NULL;
 384        struct regulator_config config = { };
 385        struct regulator_dev **rdev;
 386        struct regulator_init_data *reg_data;
 387        struct tps6586x_platform_data *pdata;
 388        struct of_regulator_match *tps6586x_reg_matches = NULL;
 389        int id;
 390        int err;
 391
 392        dev_dbg(&pdev->dev, "Probing regulator\n");
 393
 394        pdata = dev_get_platdata(pdev->dev.parent);
 395        if ((!pdata) && (pdev->dev.parent->of_node))
 396                pdata = tps6586x_parse_regulator_dt(pdev,
 397                                        &tps6586x_reg_matches);
 398
 399        if (!pdata) {
 400                dev_err(&pdev->dev, "Platform data not available, exiting\n");
 401                return -ENODEV;
 402        }
 403
 404        rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR *
 405                                sizeof(*rdev), GFP_KERNEL);
 406        if (!rdev) {
 407                dev_err(&pdev->dev, "Mmemory alloc failed\n");
 408                return -ENOMEM;
 409        }
 410
 411        for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) {
 412                reg_data = pdata->reg_init_data[id];
 413
 414                ri = find_regulator_info(id);
 415                if (!ri) {
 416                        dev_err(&pdev->dev, "invalid regulator ID specified\n");
 417                        err = -EINVAL;
 418                        goto fail;
 419                }
 420
 421                err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
 422                if (err) {
 423                        dev_err(&pdev->dev,
 424                                "regulator %d preinit failed, e %d\n", id, err);
 425                        goto fail;
 426                }
 427
 428                config.dev = pdev->dev.parent;
 429                config.init_data = reg_data;
 430                config.driver_data = ri;
 431
 432                if (tps6586x_reg_matches)
 433                        config.of_node = tps6586x_reg_matches[id].of_node;
 434
 435                rdev[id] = regulator_register(&ri->desc, &config);
 436                if (IS_ERR(rdev[id])) {
 437                        dev_err(&pdev->dev, "failed to register regulator %s\n",
 438                                        ri->desc.name);
 439                        err = PTR_ERR(rdev[id]);
 440                        goto fail;
 441                }
 442
 443                if (reg_data) {
 444                        err = tps6586x_regulator_set_slew_rate(pdev, id,
 445                                        reg_data);
 446                        if (err < 0) {
 447                                dev_err(&pdev->dev,
 448                                        "Slew rate config failed, e %d\n", err);
 449                                regulator_unregister(rdev[id]);
 450                                goto fail;
 451                        }
 452                }
 453        }
 454
 455        platform_set_drvdata(pdev, rdev);
 456        return 0;
 457
 458fail:
 459        while (--id >= 0)
 460                regulator_unregister(rdev[id]);
 461        return err;
 462}
 463
 464static int tps6586x_regulator_remove(struct platform_device *pdev)
 465{
 466        struct regulator_dev **rdev = platform_get_drvdata(pdev);
 467        int id = TPS6586X_ID_MAX_REGULATOR;
 468
 469        while (--id >= 0)
 470                regulator_unregister(rdev[id]);
 471
 472        return 0;
 473}
 474
 475static struct platform_driver tps6586x_regulator_driver = {
 476        .driver = {
 477                .name   = "tps6586x-pmic",
 478                .owner  = THIS_MODULE,
 479        },
 480        .probe          = tps6586x_regulator_probe,
 481        .remove         = tps6586x_regulator_remove,
 482};
 483
 484static int __init tps6586x_regulator_init(void)
 485{
 486        return platform_driver_register(&tps6586x_regulator_driver);
 487}
 488subsys_initcall(tps6586x_regulator_init);
 489
 490static void __exit tps6586x_regulator_exit(void)
 491{
 492        platform_driver_unregister(&tps6586x_regulator_driver);
 493}
 494module_exit(tps6586x_regulator_exit);
 495
 496MODULE_LICENSE("GPL");
 497MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 498MODULE_DESCRIPTION("Regulator Driver for TI TPS6586X PMIC");
 499MODULE_ALIAS("platform:tps6586x-regulator");
 500
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.