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 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 int tps6105x_regulator_list_voltage(struct regulator_dev *rdev,
 109                                           unsigned selector)
 110{
 111        if (selector >= ARRAY_SIZE(tps6105x_voltages))
 112                return -EINVAL;
 113
 114        return tps6105x_voltages[selector];
 115}
 116
 117static struct regulator_ops tps6105x_regulator_ops = {
 118        .enable         = tps6105x_regulator_enable,
 119        .disable        = tps6105x_regulator_disable,
 120        .is_enabled     = tps6105x_regulator_is_enabled,
 121        .get_voltage_sel = tps6105x_regulator_get_voltage_sel,
 122        .set_voltage_sel = tps6105x_regulator_set_voltage_sel,
 123        .list_voltage   = tps6105x_regulator_list_voltage,
 124};
 125
 126static struct regulator_desc tps6105x_regulator_desc = {
 127        .name           = "tps6105x-boost",
 128        .ops            = &tps6105x_regulator_ops,
 129        .type           = REGULATOR_VOLTAGE,
 130        .id             = 0,
 131        .owner          = THIS_MODULE,
 132        .n_voltages     = ARRAY_SIZE(tps6105x_voltages),
 133};
 134
 135/*
 136 * Registers the chip as a voltage regulator
 137 */
 138static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
 139{
 140        struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 141        struct tps6105x_platform_data *pdata = tps6105x->pdata;
 142        int ret;
 143
 144        /* This instance is not set for regulator mode so bail out */
 145        if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
 146                dev_info(&pdev->dev,
 147                         "chip not in voltage mode mode, exit probe \n");
 148                return 0;
 149        }
 150
 151        /* Register regulator with framework */
 152        tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
 153                                             &tps6105x->client->dev,
 154                                             pdata->regulator_data, tps6105x,
 155                                             NULL);
 156        if (IS_ERR(tps6105x->regulator)) {
 157                ret = PTR_ERR(tps6105x->regulator);
 158                dev_err(&tps6105x->client->dev,
 159                        "failed to register regulator\n");
 160                return ret;
 161        }
 162        platform_set_drvdata(pdev, tps6105x);
 163
 164        return 0;
 165}
 166
 167static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
 168{
 169        struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 170        regulator_unregister(tps6105x->regulator);
 171        return 0;
 172}
 173
 174static struct platform_driver tps6105x_regulator_driver = {
 175        .driver = {
 176                .name  = "tps6105x-regulator",
 177                .owner = THIS_MODULE,
 178        },
 179        .probe = tps6105x_regulator_probe,
 180        .remove = __devexit_p(tps6105x_regulator_remove),
 181};
 182
 183static __init int tps6105x_regulator_init(void)
 184{
 185        return platform_driver_register(&tps6105x_regulator_driver);
 186}
 187subsys_initcall(tps6105x_regulator_init);
 188
 189static __exit void tps6105x_regulator_exit(void)
 190{
 191        platform_driver_unregister(&tps6105x_regulator_driver);
 192}
 193module_exit(tps6105x_regulator_exit);
 194
 195MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 196MODULE_DESCRIPTION("TPS6105x regulator driver");
 197MODULE_LICENSE("GPL v2");
 198MODULE_ALIAS("platform:tps6105x-regulator");
 199
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.