linux/drivers/regulator/tps6524x-regulator.c
<<
>>
Prefs
   1/*
   2 * Regulator driver for TPS6524x PMIC
   3 *
   4 * Copyright (C) 2010 Texas Instruments
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation version 2.
   9 *
  10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
  11 * whether express or implied; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/err.h>
  19#include <linux/errno.h>
  20#include <linux/slab.h>
  21#include <linux/spi/spi.h>
  22#include <linux/regulator/driver.h>
  23#include <linux/regulator/machine.h>
  24
  25#define REG_LDO_SET             0x0
  26#define LDO_ILIM_MASK           1       /* 0 = 400-800, 1 = 900-1500 */
  27#define LDO_VSEL_MASK           0x0f
  28#define LDO2_ILIM_SHIFT         12
  29#define LDO2_VSEL_SHIFT         4
  30#define LDO1_ILIM_SHIFT         8
  31#define LDO1_VSEL_SHIFT         0
  32
  33#define REG_BLOCK_EN            0x1
  34#define BLOCK_MASK              1
  35#define BLOCK_LDO1_SHIFT        0
  36#define BLOCK_LDO2_SHIFT        1
  37#define BLOCK_LCD_SHIFT         2
  38#define BLOCK_USB_SHIFT         3
  39
  40#define REG_DCDC_SET            0x2
  41#define DCDC_VDCDC_MASK         0x1f
  42#define DCDC_VDCDC1_SHIFT       0
  43#define DCDC_VDCDC2_SHIFT       5
  44#define DCDC_VDCDC3_SHIFT       10
  45
  46#define REG_DCDC_EN             0x3
  47#define DCDCDCDC_EN_MASK        0x1
  48#define DCDCDCDC1_EN_SHIFT      0
  49#define DCDCDCDC1_PG_MSK        BIT(1)
  50#define DCDCDCDC2_EN_SHIFT      2
  51#define DCDCDCDC2_PG_MSK        BIT(3)
  52#define DCDCDCDC3_EN_SHIFT      4
  53#define DCDCDCDC3_PG_MSK        BIT(5)
  54
  55#define REG_USB                 0x4
  56#define USB_ILIM_SHIFT          0
  57#define USB_ILIM_MASK           0x3
  58#define USB_TSD_SHIFT           2
  59#define USB_TSD_MASK            0x3
  60#define USB_TWARN_SHIFT         4
  61#define USB_TWARN_MASK          0x3
  62#define USB_IWARN_SD            BIT(6)
  63#define USB_FAST_LOOP           BIT(7)
  64
  65#define REG_ALARM               0x5
  66#define ALARM_LDO1              BIT(0)
  67#define ALARM_DCDC1             BIT(1)
  68#define ALARM_DCDC2             BIT(2)
  69#define ALARM_DCDC3             BIT(3)
  70#define ALARM_LDO2              BIT(4)
  71#define ALARM_USB_WARN          BIT(5)
  72#define ALARM_USB_ALARM         BIT(6)
  73#define ALARM_LCD               BIT(9)
  74#define ALARM_TEMP_WARM         BIT(10)
  75#define ALARM_TEMP_HOT          BIT(11)
  76#define ALARM_NRST              BIT(14)
  77#define ALARM_POWERUP           BIT(15)
  78
  79#define REG_INT_ENABLE          0x6
  80#define INT_LDO1                BIT(0)
  81#define INT_DCDC1               BIT(1)
  82#define INT_DCDC2               BIT(2)
  83#define INT_DCDC3               BIT(3)
  84#define INT_LDO2                BIT(4)
  85#define INT_USB_WARN            BIT(5)
  86#define INT_USB_ALARM           BIT(6)
  87#define INT_LCD                 BIT(9)
  88#define INT_TEMP_WARM           BIT(10)
  89#define INT_TEMP_HOT            BIT(11)
  90#define INT_GLOBAL_EN           BIT(15)
  91
  92#define REG_INT_STATUS          0x7
  93#define STATUS_LDO1             BIT(0)
  94#define STATUS_DCDC1            BIT(1)
  95#define STATUS_DCDC2            BIT(2)
  96#define STATUS_DCDC3            BIT(3)
  97#define STATUS_LDO2             BIT(4)
  98#define STATUS_USB_WARN         BIT(5)
  99#define STATUS_USB_ALARM        BIT(6)
 100#define STATUS_LCD              BIT(9)
 101#define STATUS_TEMP_WARM        BIT(10)
 102#define STATUS_TEMP_HOT         BIT(11)
 103
 104#define REG_SOFTWARE_RESET      0xb
 105#define REG_WRITE_ENABLE        0xd
 106#define REG_REV_ID              0xf
 107
 108#define N_DCDC                  3
 109#define N_LDO                   2
 110#define N_SWITCH                2
 111#define N_REGULATORS            (N_DCDC + N_LDO + N_SWITCH)
 112
 113#define CMD_READ(reg)           ((reg) << 6)
 114#define CMD_WRITE(reg)          (BIT(5) | (reg) << 6)
 115#define STAT_CLK                BIT(3)
 116#define STAT_WRITE              BIT(2)
 117#define STAT_INVALID            BIT(1)
 118#define STAT_WP                 BIT(0)
 119
 120struct field {
 121        int             reg;
 122        int             shift;
 123        int             mask;
 124};
 125
 126struct supply_info {
 127        const char      *name;
 128        int             n_voltages;
 129        const unsigned int *voltages;
 130        int             n_ilimsels;
 131        const unsigned int *ilimsels;
 132        struct field    enable, voltage, ilimsel;
 133};
 134
 135struct tps6524x {
 136        struct device           *dev;
 137        struct spi_device       *spi;
 138        struct mutex            lock;
 139        struct regulator_desc   desc[N_REGULATORS];
 140        struct regulator_dev    *rdev[N_REGULATORS];
 141};
 142
 143static int __read_reg(struct tps6524x *hw, int reg)
 144{
 145        int error = 0;
 146        u16 cmd = CMD_READ(reg), in;
 147        u8 status;
 148        struct spi_message m;
 149        struct spi_transfer t[3];
 150
 151        spi_message_init(&m);
 152        memset(t, 0, sizeof(t));
 153
 154        t[0].tx_buf = &cmd;
 155        t[0].len = 2;
 156        t[0].bits_per_word = 12;
 157        spi_message_add_tail(&t[0], &m);
 158
 159        t[1].rx_buf = &in;
 160        t[1].len = 2;
 161        t[1].bits_per_word = 16;
 162        spi_message_add_tail(&t[1], &m);
 163
 164        t[2].rx_buf = &status;
 165        t[2].len = 1;
 166        t[2].bits_per_word = 4;
 167        spi_message_add_tail(&t[2], &m);
 168
 169        error = spi_sync(hw->spi, &m);
 170        if (error < 0)
 171                return error;
 172
 173        dev_dbg(hw->dev, "read reg %d, data %x, status %x\n",
 174                reg, in, status);
 175
 176        if (!(status & STAT_CLK) || (status & STAT_WRITE))
 177                return -EIO;
 178
 179        if (status & STAT_INVALID)
 180                return -EINVAL;
 181
 182        return in;
 183}
 184
 185static int read_reg(struct tps6524x *hw, int reg)
 186{
 187        int ret;
 188
 189        mutex_lock(&hw->lock);
 190        ret = __read_reg(hw, reg);
 191        mutex_unlock(&hw->lock);
 192
 193        return ret;
 194}
 195
 196static int __write_reg(struct tps6524x *hw, int reg, int val)
 197{
 198        int error = 0;
 199        u16 cmd = CMD_WRITE(reg), out = val;
 200        u8 status;
 201        struct spi_message m;
 202        struct spi_transfer t[3];
 203
 204        spi_message_init(&m);
 205        memset(t, 0, sizeof(t));
 206
 207        t[0].tx_buf = &cmd;
 208        t[0].len = 2;
 209        t[0].bits_per_word = 12;
 210        spi_message_add_tail(&t[0], &m);
 211
 212        t[1].tx_buf = &out;
 213        t[1].len = 2;
 214        t[1].bits_per_word = 16;
 215        spi_message_add_tail(&t[1], &m);
 216
 217        t[2].rx_buf = &status;
 218        t[2].len = 1;
 219        t[2].bits_per_word = 4;
 220        spi_message_add_tail(&t[2], &m);
 221
 222        error = spi_sync(hw->spi, &m);
 223        if (error < 0)
 224                return error;
 225
 226        dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n",
 227                reg, out, status);
 228
 229        if (!(status & STAT_CLK) || !(status & STAT_WRITE))
 230                return -EIO;
 231
 232        if (status & (STAT_INVALID | STAT_WP))
 233                return -EINVAL;
 234
 235        return error;
 236}
 237
 238static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val)
 239{
 240        int ret;
 241
 242        ret = __read_reg(hw, reg);
 243        if (ret < 0)
 244                return ret;
 245
 246        ret &= ~mask;
 247        ret |= val;
 248
 249        ret = __write_reg(hw, reg, ret);
 250
 251        return (ret < 0) ? ret : 0;
 252}
 253
 254static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val)
 255{
 256        int ret;
 257
 258        mutex_lock(&hw->lock);
 259
 260        ret = __write_reg(hw, REG_WRITE_ENABLE, 1);
 261        if (ret) {
 262                dev_err(hw->dev, "failed to set write enable\n");
 263                goto error;
 264        }
 265
 266        ret = __rmw_reg(hw, reg, mask, val);
 267        if (ret)
 268                dev_err(hw->dev, "failed to rmw register %d\n", reg);
 269
 270        ret = __write_reg(hw, REG_WRITE_ENABLE, 0);
 271        if (ret) {
 272                dev_err(hw->dev, "failed to clear write enable\n");
 273                goto error;
 274        }
 275
 276error:
 277        mutex_unlock(&hw->lock);
 278
 279        return ret;
 280}
 281
 282static int read_field(struct tps6524x *hw, const struct field *field)
 283{
 284        int tmp;
 285
 286        tmp = read_reg(hw, field->reg);
 287        if (tmp < 0)
 288                return tmp;
 289
 290        return (tmp >> field->shift) & field->mask;
 291}
 292
 293static int write_field(struct tps6524x *hw, const struct field *field,
 294                       int val)
 295{
 296        if (val & ~field->mask)
 297                return -EOVERFLOW;
 298
 299        return rmw_protect(hw, field->reg,
 300                                    field->mask << field->shift,
 301                                    val << field->shift);
 302}
 303
 304static const unsigned int dcdc1_voltages[] = {
 305         800000,  825000,  850000,  875000,
 306         900000,  925000,  950000,  975000,
 307        1000000, 1025000, 1050000, 1075000,
 308        1100000, 1125000, 1150000, 1175000,
 309        1200000, 1225000, 1250000, 1275000,
 310        1300000, 1325000, 1350000, 1375000,
 311        1400000, 1425000, 1450000, 1475000,
 312        1500000, 1525000, 1550000, 1575000,
 313};
 314
 315static const unsigned int dcdc2_voltages[] = {
 316        1400000, 1450000, 1500000, 1550000,
 317        1600000, 1650000, 1700000, 1750000,
 318        1800000, 1850000, 1900000, 1950000,
 319        2000000, 2050000, 2100000, 2150000,
 320        2200000, 2250000, 2300000, 2350000,
 321        2400000, 2450000, 2500000, 2550000,
 322        2600000, 2650000, 2700000, 2750000,
 323        2800000, 2850000, 2900000, 2950000,
 324};
 325
 326static const unsigned int dcdc3_voltages[] = {
 327        2400000, 2450000, 2500000, 2550000, 2600000,
 328        2650000, 2700000, 2750000, 2800000, 2850000,
 329        2900000, 2950000, 3000000, 3050000, 3100000,
 330        3150000, 3200000, 3250000, 3300000, 3350000,
 331        3400000, 3450000, 3500000, 3550000, 3600000,
 332};
 333
 334static const unsigned int ldo1_voltages[] = {
 335        4300000, 4350000, 4400000, 4450000,
 336        4500000, 4550000, 4600000, 4650000,
 337        4700000, 4750000, 4800000, 4850000,
 338        4900000, 4950000, 5000000, 5050000,
 339};
 340
 341static const unsigned int ldo2_voltages[] = {
 342        1100000, 1150000, 1200000, 1250000,
 343        1300000, 1700000, 1750000, 1800000,
 344        1850000, 1900000, 3150000, 3200000,
 345        3250000, 3300000, 3350000, 3400000,
 346};
 347
 348static const unsigned int fixed_5000000_voltage[] = {
 349        5000000
 350};
 351
 352static const unsigned int ldo_ilimsel[] = {
 353        400000, 1500000
 354};
 355
 356static const unsigned int usb_ilimsel[] = {
 357        200000, 400000, 800000, 1000000
 358};
 359
 360static const unsigned int fixed_2400000_ilimsel[] = {
 361        2400000
 362};
 363
 364static const unsigned int fixed_1200000_ilimsel[] = {
 365        1200000
 366};
 367
 368static const unsigned int fixed_400000_ilimsel[] = {
 369        400000
 370};
 371
 372#define __MK_FIELD(_reg, _mask, _shift) \
 373        { .reg = (_reg), .mask = (_mask), .shift = (_shift), }
 374
 375static const struct supply_info supply_info[N_REGULATORS] = {
 376        {
 377                .name           = "DCDC1",
 378                .n_voltages     = ARRAY_SIZE(dcdc1_voltages),
 379                .voltages       = dcdc1_voltages,
 380                .n_ilimsels     = ARRAY_SIZE(fixed_2400000_ilimsel),
 381                .ilimsels       = fixed_2400000_ilimsel,
 382                .enable         = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
 383                                             DCDCDCDC1_EN_SHIFT),
 384                .voltage        = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
 385                                             DCDC_VDCDC1_SHIFT),
 386        },
 387        {
 388                .name           = "DCDC2",
 389                .n_voltages     = ARRAY_SIZE(dcdc2_voltages),
 390                .voltages       = dcdc2_voltages,
 391                .n_ilimsels     = ARRAY_SIZE(fixed_1200000_ilimsel),
 392                .ilimsels       = fixed_1200000_ilimsel,
 393                .enable         = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
 394                                             DCDCDCDC2_EN_SHIFT),
 395                .voltage        = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
 396                                             DCDC_VDCDC2_SHIFT),
 397        },
 398        {
 399                .name           = "DCDC3",
 400                .n_voltages     = ARRAY_SIZE(dcdc3_voltages),
 401                .voltages       = dcdc3_voltages,
 402                .n_ilimsels     = ARRAY_SIZE(fixed_1200000_ilimsel),
 403                .ilimsels       = fixed_1200000_ilimsel,
 404                .enable         = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
 405                                        DCDCDCDC3_EN_SHIFT),
 406                .voltage        = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
 407                                             DCDC_VDCDC3_SHIFT),
 408        },
 409        {
 410                .name           = "LDO1",
 411                .n_voltages     = ARRAY_SIZE(ldo1_voltages),
 412                .voltages       = ldo1_voltages,
 413                .n_ilimsels     = ARRAY_SIZE(ldo_ilimsel),
 414                .ilimsels       = ldo_ilimsel,
 415                .enable         = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
 416                                             BLOCK_LDO1_SHIFT),
 417                .voltage        = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK,
 418                                             LDO1_VSEL_SHIFT),
 419                .ilimsel        = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK,
 420                                             LDO1_ILIM_SHIFT),
 421        },
 422        {
 423                .name           = "LDO2",
 424                .n_voltages     = ARRAY_SIZE(ldo2_voltages),
 425                .voltages       = ldo2_voltages,
 426                .n_ilimsels     = ARRAY_SIZE(ldo_ilimsel),
 427                .ilimsels       = ldo_ilimsel,
 428                .enable         = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
 429                                             BLOCK_LDO2_SHIFT),
 430                .voltage        = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK,
 431                                             LDO2_VSEL_SHIFT),
 432                .ilimsel        = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK,
 433                                             LDO2_ILIM_SHIFT),
 434        },
 435        {
 436                .name           = "USB",
 437                .n_voltages     = ARRAY_SIZE(fixed_5000000_voltage),
 438                .voltages       = fixed_5000000_voltage,
 439                .n_ilimsels     = ARRAY_SIZE(usb_ilimsel),
 440                .ilimsels       = usb_ilimsel,
 441                .enable         = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
 442                                             BLOCK_USB_SHIFT),
 443                .ilimsel        = __MK_FIELD(REG_USB, USB_ILIM_MASK,
 444                                             USB_ILIM_SHIFT),
 445        },
 446        {
 447                .name           = "LCD",
 448                .n_voltages     = ARRAY_SIZE(fixed_5000000_voltage),
 449                .voltages       = fixed_5000000_voltage,
 450                .n_ilimsels     = ARRAY_SIZE(fixed_400000_ilimsel),
 451                .ilimsels       = fixed_400000_ilimsel,
 452                .enable         = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
 453                                             BLOCK_LCD_SHIFT),
 454        },
 455};
 456
 457static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 458{
 459        const struct supply_info *info;
 460        struct tps6524x *hw;
 461
 462        hw      = rdev_get_drvdata(rdev);
 463        info    = &supply_info[rdev_get_id(rdev)];
 464
 465        if (rdev->desc->n_voltages == 1)
 466                return -EINVAL;
 467
 468        return write_field(hw, &info->voltage, selector);
 469}
 470
 471static int get_voltage_sel(struct regulator_dev *rdev)
 472{
 473        const struct supply_info *info;
 474        struct tps6524x *hw;
 475        int ret;
 476
 477        hw      = rdev_get_drvdata(rdev);
 478        info    = &supply_info[rdev_get_id(rdev)];
 479
 480        if (rdev->desc->n_voltages == 1)
 481                return 0;
 482
 483        ret = read_field(hw, &info->voltage);
 484        if (ret < 0)
 485                return ret;
 486        if (WARN_ON(ret >= info->n_voltages))
 487                return -EIO;
 488
 489        return ret;
 490}
 491
 492static int set_current_limit(struct regulator_dev *rdev, int min_uA,
 493                             int max_uA)
 494{
 495        const struct supply_info *info;
 496        struct tps6524x *hw;
 497        int i;
 498
 499        hw      = rdev_get_drvdata(rdev);
 500        info    = &supply_info[rdev_get_id(rdev)];
 501
 502        if (info->n_ilimsels == 1)
 503                return -EINVAL;
 504
 505        for (i = info->n_ilimsels - 1; i >= 0; i--) {
 506                if (min_uA <= info->ilimsels[i] &&
 507                    max_uA >= info->ilimsels[i])
 508                        return write_field(hw, &info->ilimsel, i);
 509        }
 510
 511        return -EINVAL;
 512}
 513
 514static int get_current_limit(struct regulator_dev *rdev)
 515{
 516        const struct supply_info *info;
 517        struct tps6524x *hw;
 518        int ret;
 519
 520        hw      = rdev_get_drvdata(rdev);
 521        info    = &supply_info[rdev_get_id(rdev)];
 522
 523        if (info->n_ilimsels == 1)
 524                return info->ilimsels[0];
 525
 526        ret = read_field(hw, &info->ilimsel);
 527        if (ret < 0)
 528                return ret;
 529        if (WARN_ON(ret >= info->n_ilimsels))
 530                return -EIO;
 531
 532        return info->ilimsels[ret];
 533}
 534
 535static int enable_supply(struct regulator_dev *rdev)
 536{
 537        const struct supply_info *info;
 538        struct tps6524x *hw;
 539
 540        hw      = rdev_get_drvdata(rdev);
 541        info    = &supply_info[rdev_get_id(rdev)];
 542
 543        return write_field(hw, &info->enable, 1);
 544}
 545
 546static int disable_supply(struct regulator_dev *rdev)
 547{
 548        const struct supply_info *info;
 549        struct tps6524x *hw;
 550
 551        hw      = rdev_get_drvdata(rdev);
 552        info    = &supply_info[rdev_get_id(rdev)];
 553
 554        return write_field(hw, &info->enable, 0);
 555}
 556
 557static int is_supply_enabled(struct regulator_dev *rdev)
 558{
 559        const struct supply_info *info;
 560        struct tps6524x *hw;
 561
 562        hw      = rdev_get_drvdata(rdev);
 563        info    = &supply_info[rdev_get_id(rdev)];
 564
 565        return read_field(hw, &info->enable);
 566}
 567
 568static struct regulator_ops regulator_ops = {
 569        .is_enabled             = is_supply_enabled,
 570        .enable                 = enable_supply,
 571        .disable                = disable_supply,
 572        .get_voltage_sel        = get_voltage_sel,
 573        .set_voltage_sel        = set_voltage_sel,
 574        .list_voltage           = regulator_list_voltage_table,
 575        .map_voltage            = regulator_map_voltage_ascend,
 576        .set_current_limit      = set_current_limit,
 577        .get_current_limit      = get_current_limit,
 578};
 579
 580static int pmic_probe(struct spi_device *spi)
 581{
 582        struct tps6524x *hw;
 583        struct device *dev = &spi->dev;
 584        const struct supply_info *info = supply_info;
 585        struct regulator_init_data *init_data;
 586        struct regulator_config config = { };
 587        int i;
 588
 589        init_data = dev_get_platdata(dev);
 590        if (!init_data) {
 591                dev_err(dev, "could not find regulator platform data\n");
 592                return -EINVAL;
 593        }
 594
 595        hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL);
 596        if (!hw)
 597                return -ENOMEM;
 598
 599        spi_set_drvdata(spi, hw);
 600
 601        memset(hw, 0, sizeof(struct tps6524x));
 602        hw->dev = dev;
 603        hw->spi = spi;
 604        mutex_init(&hw->lock);
 605
 606        for (i = 0; i < N_REGULATORS; i++, info++, init_data++) {
 607                hw->desc[i].name        = info->name;
 608                hw->desc[i].id          = i;
 609                hw->desc[i].n_voltages  = info->n_voltages;
 610                hw->desc[i].volt_table  = info->voltages;
 611                hw->desc[i].ops         = &regulator_ops;
 612                hw->desc[i].type        = REGULATOR_VOLTAGE;
 613                hw->desc[i].owner       = THIS_MODULE;
 614
 615                config.dev = dev;
 616                config.init_data = init_data;
 617                config.driver_data = hw;
 618
 619                hw->rdev[i] = devm_regulator_register(dev, &hw->desc[i],
 620                                                      &config);
 621                if (IS_ERR(hw->rdev[i]))
 622                        return PTR_ERR(hw->rdev[i]);
 623        }
 624
 625        return 0;
 626}
 627
 628static struct spi_driver pmic_driver = {
 629        .probe          = pmic_probe,
 630        .driver         = {
 631                .name   = "tps6524x",
 632        },
 633};
 634
 635module_spi_driver(pmic_driver);
 636
 637MODULE_DESCRIPTION("TPS6524X PMIC Driver");
 638MODULE_AUTHOR("Cyril Chemparathy");
 639MODULE_LICENSE("GPL");
 640MODULE_ALIAS("spi:tps6524x");
 641