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/regmap.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 = regmap_update_bits(tps6105x->regmap, 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 = regmap_update_bits(tps6105x->regmap, 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        unsigned int regval;
  64        int ret;
  65
  66        ret = regmap_read(tps6105x->regmap, 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        unsigned int regval;
  82        int ret;
  83
  84        ret = regmap_read(tps6105x->regmap, 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 = regmap_update_bits(tps6105x->regmap, 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 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 = devm_regulator_register(&pdev->dev,
 150                                                      &tps6105x_regulator_desc,
 151                                                      &config);
 152        if (IS_ERR(tps6105x->regulator)) {
 153                ret = PTR_ERR(tps6105x->regulator);
 154                dev_err(&tps6105x->client->dev,
 155                        "failed to register regulator\n");
 156                return ret;
 157        }
 158        platform_set_drvdata(pdev, tps6105x);
 159
 160        return 0;
 161}
 162
 163static struct platform_driver tps6105x_regulator_driver = {
 164        .driver = {
 165                .name  = "tps6105x-regulator",
 166        },
 167        .probe = tps6105x_regulator_probe,
 168};
 169
 170static __init int tps6105x_regulator_init(void)
 171{
 172        return platform_driver_register(&tps6105x_regulator_driver);
 173}
 174subsys_initcall(tps6105x_regulator_init);
 175
 176static __exit void tps6105x_regulator_exit(void)
 177{
 178        platform_driver_unregister(&tps6105x_regulator_driver);
 179}
 180module_exit(tps6105x_regulator_exit);
 181
 182MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 183MODULE_DESCRIPTION("TPS6105x regulator driver");
 184MODULE_LICENSE("GPL v2");
 185MODULE_ALIAS("platform:tps6105x-regulator");
 186