linux/drivers/regulator/tps6105x-regulator.c
<<
>>
Prefs
   1/*
   2 * Driver for TPS61050/61052 boost converters, typically used for white LEDs
   3 * or audio amplifiers.
   4 *
   5 * Copyright (C) 2011 ST-Ericsson SA
   6 * Written on behalf of Linaro for ST-Ericsson
   7 *
   8 * Author: Linus Walleij <linus.walleij@linaro.org>
   9 *
  10 * License terms: GNU General Public License (GPL) version 2
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/err.h>
  17#include <linux/i2c.h>
  18#include <linux/platform_device.h>
  19#include <linux/regulator/driver.h>
  20#include <linux/mfd/core.h>
  21#include <linux/mfd/tps6105x.h>
  22
  23static const unsigned int tps6105x_voltages[] = {
  24        4500000,
  25        5000000,
  26        5250000,
  27        5000000, /* There is an additional 5V */
  28};
  29
  30static int tps6105x_regulator_enable(struct regulator_dev *rdev)
  31{
  32        struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
  33        int ret;
  34
  35        /* Activate voltage mode */
  36        ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
  37                TPS6105X_REG0_MODE_MASK,
  38                TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
  39        if (ret)
  40                return ret;
  41
  42        return 0;
  43}
  44
  45static int tps6105x_regulator_disable(struct regulator_dev *rdev)
  46{
  47        struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
  48        int ret;
  49
  50        /* Set into shutdown mode */
  51        ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
  52                TPS6105X_REG0_MODE_MASK,
  53                TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
  54        if (ret)
  55                return ret;
  56
  57        return 0;
  58}
  59
  60static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev)
  61{
  62        struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
  63        u8 regval;
  64        int ret;
  65
  66        ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
  67        if (ret)
  68                return ret;
  69        regval &= TPS6105X_REG0_MODE_MASK;
  70        regval >>= TPS6105X_REG0_MODE_SHIFT;
  71
  72        if (regval == TPS6105X_REG0_MODE_VOLTAGE)
  73                return 1;
  74
  75        return 0;
  76}
  77
  78static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev)
  79{
  80        struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
  81        u8 regval;
  82        int ret;
  83
  84        ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
  85        if (ret)
  86                return ret;
  87
  88        regval &= TPS6105X_REG0_VOLTAGE_MASK;
  89        regval >>= TPS6105X_REG0_VOLTAGE_SHIFT;
  90        return (int) regval;
  91}
  92
  93static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev,
  94                                              unsigned selector)
  95{
  96        struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
  97        int ret;
  98
  99        ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
 100                                    TPS6105X_REG0_VOLTAGE_MASK,
 101                                    selector << TPS6105X_REG0_VOLTAGE_SHIFT);
 102        if (ret)
 103                return ret;
 104
 105        return 0;
 106}
 107
 108static struct regulator_ops tps6105x_regulator_ops = {
 109        .enable         = tps6105x_regulator_enable,
 110        .disable        = tps6105x_regulator_disable,
 111        .is_enabled     = tps6105x_regulator_is_enabled,
 112        .get_voltage_sel = tps6105x_regulator_get_voltage_sel,
 113        .set_voltage_sel = tps6105x_regulator_set_voltage_sel,
 114        .list_voltage   = regulator_list_voltage_table,
 115};
 116
 117static const struct regulator_desc tps6105x_regulator_desc = {
 118        .name           = "tps6105x-boost",
 119        .ops            = &tps6105x_regulator_ops,
 120        .type           = REGULATOR_VOLTAGE,
 121        .id             = 0,
 122        .owner          = THIS_MODULE,
 123        .n_voltages     = ARRAY_SIZE(tps6105x_voltages),
 124        .volt_table     = tps6105x_voltages,
 125};
 126
 127/*
 128 * Registers the chip as a voltage regulator
 129 */
 130static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
 131{
 132        struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 133        struct tps6105x_platform_data *pdata = tps6105x->pdata;
 134        struct regulator_config config = { };
 135        int ret;
 136
 137        /* This instance is not set for regulator mode so bail out */
 138        if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
 139                dev_info(&pdev->dev,
 140                         "chip not in voltage mode mode, exit probe \n");
 141                return 0;
 142        }
 143
 144        config.dev = &tps6105x->client->dev;
 145        config.init_data = pdata->regulator_data;
 146        config.driver_data = tps6105x;
 147
 148        /* Register regulator with framework */
 149        tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
 150                                                 &config);
 151        if (IS_ERR(tps6105x->regulator)) {
 152                ret = PTR_ERR(tps6105x->regulator);
 153                dev_err(&tps6105x->client->dev,
 154                        "failed to register regulator\n");
 155                return ret;
 156        }
 157        platform_set_drvdata(pdev, tps6105x);
 158
 159        return 0;
 160}
 161
 162static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
 163{
 164        struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 165        regulator_unregister(tps6105x->regulator);
 166        return 0;
 167}
 168
 169static struct platform_driver tps6105x_regulator_driver = {
 170        .driver = {
 171                .name  = "tps6105x-regulator",
 172                .owner = THIS_MODULE,
 173        },
 174        .probe = tps6105x_regulator_probe,
 175        .remove = __devexit_p(tps6105x_regulator_remove),
 176};
 177
 178static __init int tps6105x_regulator_init(void)
 179{
 180        return platform_driver_register(&tps6105x_regulator_driver);
 181}
 182subsys_initcall(tps6105x_regulator_init);
 183
 184static __exit void tps6105x_regulator_exit(void)
 185{
 186        platform_driver_unregister(&tps6105x_regulator_driver);
 187}
 188module_exit(tps6105x_regulator_exit);
 189
 190MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 191MODULE_DESCRIPTION("TPS6105x regulator driver");
 192MODULE_LICENSE("GPL v2");
 193MODULE_ALIAS("platform:tps6105x-regulator");
 194