linux/drivers/regulator/mc13892-regulator.c
<<
>>
Prefs
   1/*
   2 * Regulator Driver for Freescale MC13892 PMIC
   3 *
   4 * Copyright 2010 Yong Shen <yong.shen@linaro.org>
   5 *
   6 * Based on draft driver from Arnaud Patard <arnaud.patard@rtp-net.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/mfd/mc13892.h>
  14#include <linux/regulator/machine.h>
  15#include <linux/regulator/driver.h>
  16#include <linux/platform_device.h>
  17#include <linux/kernel.h>
  18#include <linux/slab.h>
  19#include <linux/init.h>
  20#include <linux/err.h>
  21#include <linux/module.h>
  22#include "mc13xxx.h"
  23
  24#define MC13892_REVISION                        7
  25
  26#define MC13892_POWERCTL0                       13
  27#define MC13892_POWERCTL0_USEROFFSPI            3
  28#define MC13892_POWERCTL0_VCOINCELLVSEL         20
  29#define MC13892_POWERCTL0_VCOINCELLVSEL_M       (7<<20)
  30#define MC13892_POWERCTL0_VCOINCELLEN           (1<<23)
  31
  32#define MC13892_SWITCHERS0_SWxHI                (1<<23)
  33
  34#define MC13892_SWITCHERS0                      24
  35#define MC13892_SWITCHERS0_SW1VSEL              0
  36#define MC13892_SWITCHERS0_SW1VSEL_M            (0x1f<<0)
  37#define MC13892_SWITCHERS0_SW1HI                (1<<23)
  38#define MC13892_SWITCHERS0_SW1EN                0
  39
  40#define MC13892_SWITCHERS1                      25
  41#define MC13892_SWITCHERS1_SW2VSEL              0
  42#define MC13892_SWITCHERS1_SW2VSEL_M            (0x1f<<0)
  43#define MC13892_SWITCHERS1_SW2HI                (1<<23)
  44#define MC13892_SWITCHERS1_SW2EN                0
  45
  46#define MC13892_SWITCHERS2                      26
  47#define MC13892_SWITCHERS2_SW3VSEL              0
  48#define MC13892_SWITCHERS2_SW3VSEL_M            (0x1f<<0)
  49#define MC13892_SWITCHERS2_SW3HI                (1<<23)
  50#define MC13892_SWITCHERS2_SW3EN                0
  51
  52#define MC13892_SWITCHERS3                      27
  53#define MC13892_SWITCHERS3_SW4VSEL              0
  54#define MC13892_SWITCHERS3_SW4VSEL_M            (0x1f<<0)
  55#define MC13892_SWITCHERS3_SW4HI                (1<<23)
  56#define MC13892_SWITCHERS3_SW4EN                0
  57
  58#define MC13892_SWITCHERS4                      28
  59#define MC13892_SWITCHERS4_SW1MODE              0
  60#define MC13892_SWITCHERS4_SW1MODE_AUTO         (8<<0)
  61#define MC13892_SWITCHERS4_SW1MODE_M            (0xf<<0)
  62#define MC13892_SWITCHERS4_SW2MODE              10
  63#define MC13892_SWITCHERS4_SW2MODE_AUTO         (8<<10)
  64#define MC13892_SWITCHERS4_SW2MODE_M            (0xf<<10)
  65
  66#define MC13892_SWITCHERS5                      29
  67#define MC13892_SWITCHERS5_SW3MODE              0
  68#define MC13892_SWITCHERS5_SW3MODE_AUTO         (8<<0)
  69#define MC13892_SWITCHERS5_SW3MODE_M            (0xf<<0)
  70#define MC13892_SWITCHERS5_SW4MODE              8
  71#define MC13892_SWITCHERS5_SW4MODE_AUTO         (8<<8)
  72#define MC13892_SWITCHERS5_SW4MODE_M            (0xf<<8)
  73#define MC13892_SWITCHERS5_SWBSTEN              (1<<20)
  74
  75#define MC13892_REGULATORSETTING0               30
  76#define MC13892_REGULATORSETTING0_VGEN1VSEL     0
  77#define MC13892_REGULATORSETTING0_VDIGVSEL      4
  78#define MC13892_REGULATORSETTING0_VGEN2VSEL     6
  79#define MC13892_REGULATORSETTING0_VPLLVSEL      9
  80#define MC13892_REGULATORSETTING0_VUSB2VSEL     11
  81#define MC13892_REGULATORSETTING0_VGEN3VSEL     14
  82#define MC13892_REGULATORSETTING0_VCAMVSEL      16
  83
  84#define MC13892_REGULATORSETTING0_VGEN1VSEL_M   (3<<0)
  85#define MC13892_REGULATORSETTING0_VDIGVSEL_M    (3<<4)
  86#define MC13892_REGULATORSETTING0_VGEN2VSEL_M   (7<<6)
  87#define MC13892_REGULATORSETTING0_VPLLVSEL_M    (3<<9)
  88#define MC13892_REGULATORSETTING0_VUSB2VSEL_M   (3<<11)
  89#define MC13892_REGULATORSETTING0_VGEN3VSEL_M   (1<<14)
  90#define MC13892_REGULATORSETTING0_VCAMVSEL_M    (3<<16)
  91
  92#define MC13892_REGULATORSETTING1               31
  93#define MC13892_REGULATORSETTING1_VVIDEOVSEL    2
  94#define MC13892_REGULATORSETTING1_VAUDIOVSEL    4
  95#define MC13892_REGULATORSETTING1_VSDVSEL       6
  96
  97#define MC13892_REGULATORSETTING1_VVIDEOVSEL_M  (3<<2)
  98#define MC13892_REGULATORSETTING1_VAUDIOVSEL_M  (3<<4)
  99#define MC13892_REGULATORSETTING1_VSDVSEL_M     (7<<6)
 100
 101#define MC13892_REGULATORMODE0                  32
 102#define MC13892_REGULATORMODE0_VGEN1EN          (1<<0)
 103#define MC13892_REGULATORMODE0_VGEN1STDBY       (1<<1)
 104#define MC13892_REGULATORMODE0_VGEN1MODE        (1<<2)
 105#define MC13892_REGULATORMODE0_VIOHIEN          (1<<3)
 106#define MC13892_REGULATORMODE0_VIOHISTDBY       (1<<4)
 107#define MC13892_REGULATORMODE0_VIOHIMODE        (1<<5)
 108#define MC13892_REGULATORMODE0_VDIGEN           (1<<9)
 109#define MC13892_REGULATORMODE0_VDIGSTDBY        (1<<10)
 110#define MC13892_REGULATORMODE0_VDIGMODE         (1<<11)
 111#define MC13892_REGULATORMODE0_VGEN2EN          (1<<12)
 112#define MC13892_REGULATORMODE0_VGEN2STDBY       (1<<13)
 113#define MC13892_REGULATORMODE0_VGEN2MODE        (1<<14)
 114#define MC13892_REGULATORMODE0_VPLLEN           (1<<15)
 115#define MC13892_REGULATORMODE0_VPLLSTDBY        (1<<16)
 116#define MC13892_REGULATORMODE0_VPLLMODE         (1<<17)
 117#define MC13892_REGULATORMODE0_VUSB2EN          (1<<18)
 118#define MC13892_REGULATORMODE0_VUSB2STDBY       (1<<19)
 119#define MC13892_REGULATORMODE0_VUSB2MODE        (1<<20)
 120
 121#define MC13892_REGULATORMODE1                  33
 122#define MC13892_REGULATORMODE1_VGEN3EN          (1<<0)
 123#define MC13892_REGULATORMODE1_VGEN3STDBY       (1<<1)
 124#define MC13892_REGULATORMODE1_VGEN3MODE        (1<<2)
 125#define MC13892_REGULATORMODE1_VCAMEN           (1<<6)
 126#define MC13892_REGULATORMODE1_VCAMSTDBY        (1<<7)
 127#define MC13892_REGULATORMODE1_VCAMMODE         (1<<8)
 128#define MC13892_REGULATORMODE1_VCAMCONFIGEN     (1<<9)
 129#define MC13892_REGULATORMODE1_VVIDEOEN         (1<<12)
 130#define MC13892_REGULATORMODE1_VVIDEOSTDBY      (1<<13)
 131#define MC13892_REGULATORMODE1_VVIDEOMODE       (1<<14)
 132#define MC13892_REGULATORMODE1_VAUDIOEN         (1<<15)
 133#define MC13892_REGULATORMODE1_VAUDIOSTDBY      (1<<16)
 134#define MC13892_REGULATORMODE1_VAUDIOMODE       (1<<17)
 135#define MC13892_REGULATORMODE1_VSDEN            (1<<18)
 136#define MC13892_REGULATORMODE1_VSDSTDBY         (1<<19)
 137#define MC13892_REGULATORMODE1_VSDMODE          (1<<20)
 138
 139#define MC13892_POWERMISC                       34
 140#define MC13892_POWERMISC_GPO1EN                (1<<6)
 141#define MC13892_POWERMISC_GPO2EN                (1<<8)
 142#define MC13892_POWERMISC_GPO3EN                (1<<10)
 143#define MC13892_POWERMISC_GPO4EN                (1<<12)
 144#define MC13892_POWERMISC_PWGT1SPIEN            (1<<15)
 145#define MC13892_POWERMISC_PWGT2SPIEN            (1<<16)
 146#define MC13892_POWERMISC_GPO4ADINEN            (1<<21)
 147
 148#define MC13892_POWERMISC_PWGTSPI_M             (3 << 15)
 149
 150#define MC13892_USB1                            50
 151#define MC13892_USB1_VUSBEN                     (1<<3)
 152
 153static const unsigned int mc13892_vcoincell[] = {
 154        2500000, 2700000, 2800000, 2900000, 3000000, 3100000,
 155        3200000, 3300000,
 156};
 157
 158static const unsigned int mc13892_sw1[] = {
 159        600000,   625000,  650000,  675000,  700000,  725000,
 160        750000,   775000,  800000,  825000,  850000,  875000,
 161        900000,   925000,  950000,  975000, 1000000, 1025000,
 162        1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
 163        1200000, 1225000, 1250000, 1275000, 1300000, 1325000,
 164        1350000, 1375000
 165};
 166
 167static const unsigned int mc13892_sw[] = {
 168        600000,   625000,  650000,  675000,  700000,  725000,
 169        750000,   775000,  800000,  825000,  850000,  875000,
 170        900000,   925000,  950000,  975000, 1000000, 1025000,
 171        1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
 172        1200000, 1225000, 1250000, 1275000, 1300000, 1325000,
 173        1350000, 1375000, 1400000, 1425000, 1450000, 1475000,
 174        1500000, 1525000, 1550000, 1575000, 1600000, 1625000,
 175        1650000, 1675000, 1700000, 1725000, 1750000, 1775000,
 176        1800000, 1825000, 1850000, 1875000
 177};
 178
 179static const unsigned int mc13892_swbst[] = {
 180        5000000,
 181};
 182
 183static const unsigned int mc13892_viohi[] = {
 184        2775000,
 185};
 186
 187static const unsigned int mc13892_vpll[] = {
 188        1050000, 1250000, 1650000, 1800000,
 189};
 190
 191static const unsigned int mc13892_vdig[] = {
 192        1050000, 1250000, 1650000, 1800000,
 193};
 194
 195static const unsigned int mc13892_vsd[] = {
 196        1800000, 2000000, 2600000, 2700000,
 197        2800000, 2900000, 3000000, 3150000,
 198};
 199
 200static const unsigned int mc13892_vusb2[] = {
 201        2400000, 2600000, 2700000, 2775000,
 202};
 203
 204static const unsigned int mc13892_vvideo[] = {
 205        2700000, 2775000, 2500000, 2600000,
 206};
 207
 208static const unsigned int mc13892_vaudio[] = {
 209        2300000, 2500000, 2775000, 3000000,
 210};
 211
 212static const unsigned int mc13892_vcam[] = {
 213        2500000, 2600000, 2750000, 3000000,
 214};
 215
 216static const unsigned int mc13892_vgen1[] = {
 217        1200000, 1500000, 2775000, 3150000,
 218};
 219
 220static const unsigned int mc13892_vgen2[] = {
 221        1200000, 1500000, 1600000, 1800000,
 222        2700000, 2800000, 3000000, 3150000,
 223};
 224
 225static const unsigned int mc13892_vgen3[] = {
 226        1800000, 2900000,
 227};
 228
 229static const unsigned int mc13892_vusb[] = {
 230        3300000,
 231};
 232
 233static const unsigned int mc13892_gpo[] = {
 234        2750000,
 235};
 236
 237static const unsigned int mc13892_pwgtdrv[] = {
 238        5000000,
 239};
 240
 241static struct regulator_ops mc13892_gpo_regulator_ops;
 242/* sw regulators need special care due to the "hi bit" */
 243static struct regulator_ops mc13892_sw_regulator_ops;
 244
 245
 246#define MC13892_FIXED_DEFINE(name, reg, voltages)               \
 247        MC13xxx_FIXED_DEFINE(MC13892_, name, reg, voltages,     \
 248                        mc13xxx_fixed_regulator_ops)
 249
 250#define MC13892_GPO_DEFINE(name, reg, voltages)                 \
 251        MC13xxx_GPO_DEFINE(MC13892_, name, reg, voltages,       \
 252                        mc13892_gpo_regulator_ops)
 253
 254#define MC13892_SW_DEFINE(name, reg, vsel_reg, voltages)        \
 255        MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \
 256                        mc13892_sw_regulator_ops)
 257
 258#define MC13892_DEFINE_REGU(name, reg, vsel_reg, voltages)      \
 259        MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \
 260                        mc13xxx_regulator_ops)
 261
 262static struct mc13xxx_regulator mc13892_regulators[] = {
 263        MC13892_DEFINE_REGU(VCOINCELL, POWERCTL0, POWERCTL0, mc13892_vcoincell),
 264        MC13892_SW_DEFINE(SW1, SWITCHERS0, SWITCHERS0, mc13892_sw1),
 265        MC13892_SW_DEFINE(SW2, SWITCHERS1, SWITCHERS1, mc13892_sw),
 266        MC13892_SW_DEFINE(SW3, SWITCHERS2, SWITCHERS2, mc13892_sw),
 267        MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw),
 268        MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst),
 269        MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi),
 270        MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0,    \
 271                mc13892_vpll),
 272        MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0,    \
 273                mc13892_vdig),
 274        MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1,     \
 275                mc13892_vsd),
 276        MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0,   \
 277                mc13892_vusb2),
 278        MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1,  \
 279                mc13892_vvideo),
 280        MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1,  \
 281                mc13892_vaudio),
 282        MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0,    \
 283                mc13892_vcam),
 284        MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0,   \
 285                mc13892_vgen1),
 286        MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0,   \
 287                mc13892_vgen2),
 288        MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0,   \
 289                mc13892_vgen3),
 290        MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb),
 291        MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo),
 292        MC13892_GPO_DEFINE(GPO2, POWERMISC, mc13892_gpo),
 293        MC13892_GPO_DEFINE(GPO3, POWERMISC, mc13892_gpo),
 294        MC13892_GPO_DEFINE(GPO4, POWERMISC, mc13892_gpo),
 295        MC13892_GPO_DEFINE(PWGT1SPI, POWERMISC, mc13892_pwgtdrv),
 296        MC13892_GPO_DEFINE(PWGT2SPI, POWERMISC, mc13892_pwgtdrv),
 297};
 298
 299static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
 300                                 u32 val)
 301{
 302        struct mc13xxx *mc13892 = priv->mc13xxx;
 303        int ret;
 304        u32 valread;
 305
 306        BUG_ON(val & ~mask);
 307
 308        ret = mc13xxx_reg_read(mc13892, MC13892_POWERMISC, &valread);
 309        if (ret)
 310                return ret;
 311
 312        /* Update the stored state for Power Gates. */
 313        priv->powermisc_pwgt_state =
 314                (priv->powermisc_pwgt_state & ~mask) | val;
 315        priv->powermisc_pwgt_state &= MC13892_POWERMISC_PWGTSPI_M;
 316
 317        /* Construct the new register value */
 318        valread = (valread & ~mask) | val;
 319        /* Overwrite the PWGTxEN with the stored version */
 320        valread = (valread & ~MC13892_POWERMISC_PWGTSPI_M) |
 321                priv->powermisc_pwgt_state;
 322
 323        return mc13xxx_reg_write(mc13892, MC13892_POWERMISC, valread);
 324}
 325
 326static int mc13892_gpo_regulator_enable(struct regulator_dev *rdev)
 327{
 328        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 329        int id = rdev_get_id(rdev);
 330        int ret;
 331        u32 en_val = mc13892_regulators[id].enable_bit;
 332        u32 mask = mc13892_regulators[id].enable_bit;
 333
 334        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 335
 336        /* Power Gate enable value is 0 */
 337        if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI)
 338                en_val = 0;
 339
 340        if (id == MC13892_GPO4)
 341                mask |= MC13892_POWERMISC_GPO4ADINEN;
 342
 343        mc13xxx_lock(priv->mc13xxx);
 344        ret = mc13892_powermisc_rmw(priv, mask, en_val);
 345        mc13xxx_unlock(priv->mc13xxx);
 346
 347        return ret;
 348}
 349
 350static int mc13892_gpo_regulator_disable(struct regulator_dev *rdev)
 351{
 352        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 353        int id = rdev_get_id(rdev);
 354        int ret;
 355        u32 dis_val = 0;
 356
 357        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 358
 359        /* Power Gate disable value is 1 */
 360        if (id == MC13892_PWGT1SPI || id == MC13892_PWGT2SPI)
 361                dis_val = mc13892_regulators[id].enable_bit;
 362
 363        mc13xxx_lock(priv->mc13xxx);
 364        ret = mc13892_powermisc_rmw(priv, mc13892_regulators[id].enable_bit,
 365                dis_val);
 366        mc13xxx_unlock(priv->mc13xxx);
 367
 368        return ret;
 369}
 370
 371static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev)
 372{
 373        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 374        int ret, id = rdev_get_id(rdev);
 375        unsigned int val;
 376
 377        mc13xxx_lock(priv->mc13xxx);
 378        ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val);
 379        mc13xxx_unlock(priv->mc13xxx);
 380
 381        if (ret)
 382                return ret;
 383
 384        /* Power Gates state is stored in powermisc_pwgt_state
 385         * where the meaning of bits is negated */
 386        val = (val & ~MC13892_POWERMISC_PWGTSPI_M) |
 387                (priv->powermisc_pwgt_state ^ MC13892_POWERMISC_PWGTSPI_M);
 388
 389        return (val & mc13892_regulators[id].enable_bit) != 0;
 390}
 391
 392
 393static struct regulator_ops mc13892_gpo_regulator_ops = {
 394        .enable = mc13892_gpo_regulator_enable,
 395        .disable = mc13892_gpo_regulator_disable,
 396        .is_enabled = mc13892_gpo_regulator_is_enabled,
 397        .list_voltage = regulator_list_voltage_table,
 398        .set_voltage = mc13xxx_fixed_regulator_set_voltage,
 399        .get_voltage = mc13xxx_fixed_regulator_get_voltage,
 400};
 401
 402static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
 403{
 404        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 405        int ret, id = rdev_get_id(rdev);
 406        unsigned int val, hi;
 407
 408        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 409
 410        mc13xxx_lock(priv->mc13xxx);
 411        ret = mc13xxx_reg_read(priv->mc13xxx,
 412                mc13892_regulators[id].vsel_reg, &val);
 413        mc13xxx_unlock(priv->mc13xxx);
 414        if (ret)
 415                return ret;
 416
 417        hi  = val & MC13892_SWITCHERS0_SWxHI;
 418        val = (val & mc13892_regulators[id].vsel_mask)
 419                >> mc13892_regulators[id].vsel_shift;
 420
 421        dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
 422
 423        if (hi)
 424                val = (25000 * val) + 1100000;
 425        else
 426                val = (25000 * val) + 600000;
 427
 428        return val;
 429}
 430
 431static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
 432                                                unsigned selector)
 433{
 434        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 435        int hi, value, mask, id = rdev_get_id(rdev);
 436        u32 valread;
 437        int ret;
 438
 439        value = rdev->desc->volt_table[selector];
 440
 441        mc13xxx_lock(priv->mc13xxx);
 442        ret = mc13xxx_reg_read(priv->mc13xxx,
 443                mc13892_regulators[id].vsel_reg, &valread);
 444        if (ret)
 445                goto err;
 446
 447        if (value > 1375000)
 448                hi = 1;
 449        else if (value < 1100000)
 450                hi = 0;
 451        else
 452                hi = valread & MC13892_SWITCHERS0_SWxHI;
 453
 454        if (hi) {
 455                value = (value - 1100000) / 25000;
 456                value |= MC13892_SWITCHERS0_SWxHI;
 457        } else
 458                value = (value - 600000) / 25000;
 459
 460        mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI;
 461        valread = (valread & ~mask) |
 462                        (value << mc13892_regulators[id].vsel_shift);
 463        ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
 464                        valread);
 465err:
 466        mc13xxx_unlock(priv->mc13xxx);
 467
 468        return ret;
 469}
 470
 471static struct regulator_ops mc13892_sw_regulator_ops = {
 472        .list_voltage = regulator_list_voltage_table,
 473        .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
 474        .get_voltage = mc13892_sw_regulator_get_voltage,
 475};
 476
 477static int mc13892_vcam_set_mode(struct regulator_dev *rdev, unsigned int mode)
 478{
 479        unsigned int en_val = 0;
 480        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 481        int ret, id = rdev_get_id(rdev);
 482
 483        if (mode == REGULATOR_MODE_FAST)
 484                en_val = MC13892_REGULATORMODE1_VCAMCONFIGEN;
 485
 486        mc13xxx_lock(priv->mc13xxx);
 487        ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].reg,
 488                MC13892_REGULATORMODE1_VCAMCONFIGEN, en_val);
 489        mc13xxx_unlock(priv->mc13xxx);
 490
 491        return ret;
 492}
 493
 494static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev)
 495{
 496        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 497        int ret, id = rdev_get_id(rdev);
 498        unsigned int val;
 499
 500        mc13xxx_lock(priv->mc13xxx);
 501        ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val);
 502        mc13xxx_unlock(priv->mc13xxx);
 503
 504        if (ret)
 505                return ret;
 506
 507        if (val & MC13892_REGULATORMODE1_VCAMCONFIGEN)
 508                return REGULATOR_MODE_FAST;
 509
 510        return REGULATOR_MODE_NORMAL;
 511}
 512
 513
 514static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
 515{
 516        struct mc13xxx_regulator_priv *priv;
 517        struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
 518        struct mc13xxx_regulator_platform_data *pdata =
 519                dev_get_platdata(&pdev->dev);
 520        struct mc13xxx_regulator_init_data *mc13xxx_data;
 521        struct regulator_config config = { };
 522        int i, ret;
 523        int num_regulators = 0;
 524        u32 val;
 525
 526        num_regulators = mc13xxx_get_num_regulators_dt(pdev);
 527        if (num_regulators <= 0 && pdata)
 528                num_regulators = pdata->num_regulators;
 529        if (num_regulators <= 0)
 530                return -EINVAL;
 531
 532        priv = devm_kzalloc(&pdev->dev, sizeof(*priv) +
 533                num_regulators * sizeof(priv->regulators[0]),
 534                GFP_KERNEL);
 535        if (!priv)
 536                return -ENOMEM;
 537
 538        priv->num_regulators = num_regulators;
 539        priv->mc13xxx_regulators = mc13892_regulators;
 540        priv->mc13xxx = mc13892;
 541        platform_set_drvdata(pdev, priv);
 542
 543        mc13xxx_lock(mc13892);
 544        ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val);
 545        if (ret)
 546                goto err_unlock;
 547
 548        /* enable switch auto mode */
 549        if ((val & 0x0000FFFF) == 0x45d0) {
 550                ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4,
 551                        MC13892_SWITCHERS4_SW1MODE_M |
 552                        MC13892_SWITCHERS4_SW2MODE_M,
 553                        MC13892_SWITCHERS4_SW1MODE_AUTO |
 554                        MC13892_SWITCHERS4_SW2MODE_AUTO);
 555                if (ret)
 556                        goto err_unlock;
 557
 558                ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5,
 559                        MC13892_SWITCHERS5_SW3MODE_M |
 560                        MC13892_SWITCHERS5_SW4MODE_M,
 561                        MC13892_SWITCHERS5_SW3MODE_AUTO |
 562                        MC13892_SWITCHERS5_SW4MODE_AUTO);
 563                if (ret)
 564                        goto err_unlock;
 565        }
 566        mc13xxx_unlock(mc13892);
 567
 568        mc13892_regulators[MC13892_VCAM].desc.ops->set_mode
 569                = mc13892_vcam_set_mode;
 570        mc13892_regulators[MC13892_VCAM].desc.ops->get_mode
 571                = mc13892_vcam_get_mode;
 572
 573        mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
 574                                        ARRAY_SIZE(mc13892_regulators));
 575        for (i = 0; i < num_regulators; i++) {
 576                struct regulator_init_data *init_data;
 577                struct regulator_desc *desc;
 578                struct device_node *node = NULL;
 579                int id;
 580
 581                if (mc13xxx_data) {
 582                        id = mc13xxx_data[i].id;
 583                        init_data = mc13xxx_data[i].init_data;
 584                        node = mc13xxx_data[i].node;
 585                } else {
 586                        id = pdata->regulators[i].id;
 587                        init_data = pdata->regulators[i].init_data;
 588                }
 589                desc = &mc13892_regulators[id].desc;
 590
 591                config.dev = &pdev->dev;
 592                config.init_data = init_data;
 593                config.driver_data = priv;
 594                config.of_node = node;
 595
 596                priv->regulators[i] = regulator_register(desc, &config);
 597                if (IS_ERR(priv->regulators[i])) {
 598                        dev_err(&pdev->dev, "failed to register regulator %s\n",
 599                                mc13892_regulators[i].desc.name);
 600                        ret = PTR_ERR(priv->regulators[i]);
 601                        goto err;
 602                }
 603        }
 604
 605        return 0;
 606err:
 607        while (--i >= 0)
 608                regulator_unregister(priv->regulators[i]);
 609        return ret;
 610
 611err_unlock:
 612        mc13xxx_unlock(mc13892);
 613        return ret;
 614}
 615
 616static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
 617{
 618        struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 619        int i;
 620
 621        platform_set_drvdata(pdev, NULL);
 622
 623        for (i = 0; i < priv->num_regulators; i++)
 624                regulator_unregister(priv->regulators[i]);
 625
 626        return 0;
 627}
 628
 629static struct platform_driver mc13892_regulator_driver = {
 630        .driver = {
 631                .name   = "mc13892-regulator",
 632                .owner  = THIS_MODULE,
 633        },
 634        .remove = __devexit_p(mc13892_regulator_remove),
 635        .probe  = mc13892_regulator_probe,
 636};
 637
 638static int __init mc13892_regulator_init(void)
 639{
 640        return platform_driver_register(&mc13892_regulator_driver);
 641}
 642subsys_initcall(mc13892_regulator_init);
 643
 644static void __exit mc13892_regulator_exit(void)
 645{
 646        platform_driver_unregister(&mc13892_regulator_driver);
 647}
 648module_exit(mc13892_regulator_exit);
 649
 650MODULE_LICENSE("GPL v2");
 651MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
 652MODULE_DESCRIPTION("Regulator Driver for Freescale MC13892 PMIC");
 653MODULE_ALIAS("platform:mc13892-regulator");
 654
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.