* [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions
@ 2011-03-08 9:42 Linus Walleij
2011-03-08 11:56 ` Mark Brown
0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2011-03-08 9:42 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, linux-kernel
Cc: Lee Jones, Linus Walleij, Samuel Ortiz, Ola Lilja
From: Linus Walleij <linus.walleij@linaro.org>
This adds a subdriver for the regulator found inside the TPS61050
and TPS61052 chips.
Cc: Samuel Ortiz <samuel.ortiz@intel.com>
Cc: Ola Lilja <ola.o.lilja@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/regulator/Kconfig | 9 ++
drivers/regulator/Makefile | 2 +-
drivers/regulator/tps6105x-regulator.c | 220 ++++++++++++++++++++++++++++++++
3 files changed, 230 insertions(+), 1 deletions(-)
create mode 100644 drivers/regulator/tps6105x-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e1d9436..0e52301 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -214,6 +214,15 @@ config REGULATOR_AB3100
AB3100 analog baseband dealing with power regulators
for the system.
+config REGULATOR_TPS6105X
+ tristate "TI TPS6105X Power regulators"
+ depends on TPS6105X
+ default y if TPS6105X
+ help
+ This driver supports TPS61050/TPS61052 voltage regulator chips.
+ It is a single boost converter primarily for white LEDs and
+ audio amplifiers.
+
config REGULATOR_TPS65023
tristate "TI TPS65023 Power regulators"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0b5e88c..1d797c7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
-
+obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
new file mode 100644
index 0000000..682ef25
--- /dev/null
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -0,0 +1,220 @@
+/*
+ * Driver for TPS61050/61052 boost converters, typically used for white LEDs
+ * or audio amplifiers.
+ *
+ * Copyright (C) 2011 ST-Ericsson SA
+ * Written on behalf of Linaro
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/tps6105x.h>
+
+static const int tps6105x_voltages[] = {
+ 4500000,
+ 5000000,
+ 5250000,
+ 5000000, /* There is an additional 5V */
+};
+
+static int tps6105x_regulator_enable(struct regulator_dev *rdev)
+{
+ struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
+ int ret;
+
+ /* Activate voltage mode */
+ ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
+ TPS6105X_REG0_MODE_MASK,
+ TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int tps6105x_regulator_disable(struct regulator_dev *rdev)
+{
+ struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
+ int ret;
+
+ /* Set into shutdown mode */
+ ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
+ TPS6105X_REG0_MODE_MASK,
+ TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
+ u8 regval;
+ int ret;
+
+ ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val);
+ if (ret)
+ return ret;
+ regval &= TPS6105X_REG0_MODE_MASK;
+ regval >>= TPS6105X_REG0_MODE_SHIFT;
+
+ if (regval == TPS6105X_REG0_MODE_VOLTAGE)
+ return 1;
+
+ return 0;
+}
+
+static int tps6105x_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
+ u8 regval;
+ int ret;
+
+ ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val);
+ if (ret)
+ return ret;
+
+ regval &= TPS6105X_REG0_VOLTAGE_MASK;
+ regval >>= TPS6105X_REG0_VOLTAGE_SHIFT;
+ return tps6105x_voltages[regval];
+}
+
+static int tps6105x_regulator_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV,
+ unsigned *selector)
+{
+ struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
+ int ret;
+ int i;
+
+ /* Look up a good voltage */
+ for (i = 0; i < ARRAY_SIZE(tps6105x_voltages)-1; i++) {
+ if ((tps6105x_voltages[i] >= min_uV) &&
+ (tps6105x_voltages[i] <= max_uV)) {
+ *selector = i;
+ /* Set it */
+ ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
+ TPS6105X_REG0_VOLTAGE_MASK,
+ i << TPS6105X_REG0_VOLTAGE_SHIFT);
+ if (ret)
+ return ret;
+ }
+ }
+ dev_err(rdev_get_dev(rdev),
+ "no good voltage available\n");
+ return -EINVAL;
+}
+
+static int tps6105x_regulator_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector >= ARRAY_SIZE(tps6105x_voltages))
+ return -EINVAL;
+
+ return tps6105x_voltages[selector];
+}
+
+static struct regulator_ops tps6105x_regulator_ops = {
+ .enable = tps6105x_regulator_enable,
+ .disable = tps6105x_regulator_disable,
+ .is_enabled = tps6105x_regulator_is_enabled,
+ .get_voltage = tps6105x_regulator_get_voltage,
+ .set_voltage = tps6105x_regulator_set_voltage,
+ .list_voltage = tps6105x_regulator_list_voltage,
+};
+
+static struct regulator_desc tps6105x_regulator_desc = {
+ .name = "tps6105x-boost",
+ .ops = &tps6105x_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = 0,
+ .owner = THIS_MODULE,
+ .n_voltages = ARRAY_SIZE(tps6105x_voltages),
+};
+
+/*
+ * Registers the chip as a voltage regulator
+ */
+static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
+{
+ struct tps6105x *tps6105x = platform_get_drvdata(pdev);
+ struct tps6105x_platform_data *pdata = tps6105x->pdata;
+ int ret;
+
+ /* This instance is not set for regulator mode so bail out */
+ if (pdata->mode != TPS6105X_MODE_VOLTAGE)
+ return 0;
+
+ /* Set lowest voltage 4.5V to begin */
+ ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
+ TPS6105X_REG0_VOLTAGE_MASK,
+ TPS6105X_REG0_VOLTAGE_450 << TPS6105X_REG0_VOLTAGE_SHIFT);
+ if (ret)
+ return ret;
+
+#if 0
+ /* Activate voltage mode - use to check if voltage comes out */
+ ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
+ TPS6105X_REG0_MODE_MASK,
+ TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
+ if (ret)
+ return ret;
+#endif
+
+ /* Register regulator with framework */
+ tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
+ &tps6105x->client->dev,
+ pdata->regulator_data, tps6105x);
+ if (IS_ERR(tps6105x->regulator)) {
+ ret = PTR_ERR(tps6105x->regulator);
+ dev_err(&tps6105x->client->dev,
+ "failed to register regulator\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
+{
+ struct tps6105x *tps6105x = platform_get_drvdata(pdev);
+ regulator_unregister(tps6105x->regulator);
+ return 0;
+}
+
+static struct platform_driver tps6105x_regulator_driver = {
+ .driver = {
+ .name = "tps6105x-regulator",
+ .owner = THIS_MODULE,
+ },
+ .probe = tps6105x_regulator_probe,
+ .remove = __devexit_p(tps6105x_regulator_remove),
+};
+
+static __init int tps6105x_regulator_init(void)
+{
+ return platform_driver_register(&tps6105x_regulator_driver);
+}
+
+static __exit void tps6105x_regulator_exit(void)
+{
+ platform_driver_unregister(&tps6105x_regulator_driver);
+}
+
+subsys_initcall(tps6105x_regulator_init);
+module_exit(tps6105x_regulator_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("TPS6105x regulator driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps6105x-regulator");
--
1.7.3.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions
2011-03-08 9:42 [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions Linus Walleij
@ 2011-03-08 11:56 ` Mark Brown
2011-03-08 13:26 ` Linus Walleij
0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2011-03-08 11:56 UTC (permalink / raw)
To: Linus Walleij
Cc: Liam Girdwood, linux-kernel, Lee Jones, Linus Walleij,
Samuel Ortiz, Ola Lilja
On Tue, Mar 08, 2011 at 10:42:00AM +0100, Linus Walleij wrote:
> +static int tps6105x_regulator_get_voltage(struct regulator_dev *rdev)
> +{
It'd probably simplify things to use the _sel variants for the voltage
operations.
> +static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
> +{
> + struct tps6105x *tps6105x = platform_get_drvdata(pdev);
> + struct tps6105x_platform_data *pdata = tps6105x->pdata;
> + int ret;
> +
> + /* This instance is not set for regulator mode so bail out */
> + if (pdata->mode != TPS6105X_MODE_VOLTAGE)
> + return 0;
-ENODEV? Logging to explain why we're bombing out might be helpful too.
> + /* Set lowest voltage 4.5V to begin */
> + ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
> + TPS6105X_REG0_VOLTAGE_MASK,
> + TPS6105X_REG0_VOLTAGE_450 << TPS6105X_REG0_VOLTAGE_SHIFT);
> + if (ret)
> + return ret;
Don't do this, if the user wants to set a defualt voltage they can use
constraints but if the driver does it then it may disrupt a running
system.
> +#if 0
> + /* Activate voltage mode - use to check if voltage comes out */
> + ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
> + TPS6105X_REG0_MODE_MASK,
> + TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
> + if (ret)
> + return ret;
> +#endif
Don't include if 0 code.
> +subsys_initcall(tps6105x_regulator_init);
> +module_exit(tps6105x_regulator_exit);
These usually go next to the functions.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions
2011-03-08 11:56 ` Mark Brown
@ 2011-03-08 13:26 ` Linus Walleij
2011-03-08 13:29 ` Mark Brown
0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2011-03-08 13:26 UTC (permalink / raw)
To: Mark Brown
Cc: Linus Walleij, Liam Girdwood, linux-kernel, Lee Jones,
Samuel Ortiz, Ola Lilja
On Tue, Mar 8, 2011 at 12:56 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Tue, Mar 08, 2011 at 10:42:00AM +0100, Linus Walleij wrote:
>
>> +static int tps6105x_regulator_get_voltage(struct regulator_dev *rdev)
>> +{
>
> It'd probably simplify things to use the _sel variants for the voltage
> operations.
Good idea. Fixed it.
>> +static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
>> +{
>> + struct tps6105x *tps6105x = platform_get_drvdata(pdev);
>> + struct tps6105x_platform_data *pdata = tps6105x->pdata;
>> + int ret;
>> +
>> + /* This instance is not set for regulator mode so bail out */
>> + if (pdata->mode != TPS6105X_MODE_VOLTAGE)
>> + return 0;
>
> -ENODEV? Logging to explain why we're bombing out might be helpful too.
Not in this case actually, the chip is configured by platform data to
operate as regulator, LED or flashgun. All three drivers may be
compiled in at some point, and a system may have three TPS chips
performing each function. They will spawn three children each,
but only one of them should probe.
So the fact that the regulator driver doesn't probe doesn't mean any
failure, some other driver will likely probe successfully for the chip.
>> + /* Set lowest voltage 4.5V to begin */
>> + ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
>> + TPS6105X_REG0_VOLTAGE_MASK,
>> + TPS6105X_REG0_VOLTAGE_450 << TPS6105X_REG0_VOLTAGE_SHIFT);
>> + if (ret)
>> + return ret;
>
> Don't do this, if the user wants to set a defualt voltage they can use
> constraints but if the driver does it then it may disrupt a running
> system.
OK dropped it.
>> +#if 0
>> + /* Activate voltage mode - use to check if voltage comes out */
>> + ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
>> + TPS6105X_REG0_MODE_MASK,
>> + TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
>> + if (ret)
>> + return ret;
>> +#endif
>
> Don't include if 0 code.
Dropped it.
>> +subsys_initcall(tps6105x_regulator_init);
>> +module_exit(tps6105x_regulator_exit);
>
> These usually go next to the functions.
Reordered.
Thanks Mark,
Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions
2011-03-08 13:26 ` Linus Walleij
@ 2011-03-08 13:29 ` Mark Brown
2011-03-08 13:34 ` Linus Walleij
0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2011-03-08 13:29 UTC (permalink / raw)
To: Linus Walleij
Cc: Linus Walleij, Liam Girdwood, linux-kernel, Lee Jones,
Samuel Ortiz, Ola Lilja
On Tue, Mar 08, 2011 at 02:26:14PM +0100, Linus Walleij wrote:
> On Tue, Mar 8, 2011 at 12:56 PM, Mark Brown
> >> + ? ? /* This instance is not set for regulator mode so bail out */
> >> + ? ? if (pdata->mode != TPS6105X_MODE_VOLTAGE)
> >> + ? ? ? ? ? ? return 0;
> > -ENODEV? ?Logging to explain why we're bombing out might be helpful too.
> Not in this case actually, the chip is configured by platform data to
> operate as regulator, LED or flashgun. All three drivers may be
> compiled in at some point, and a system may have three TPS chips
> performing each function. They will spawn three children each,
> but only one of them should probe.
> So the fact that the regulator driver doesn't probe doesn't mean any
> failure, some other driver will likely probe successfully for the chip.
The general approach other MFDs have taken to this is to pay attention
to the platform data when registering subdevices so that you don't get
inappropriate subdevices registered in the first place.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions
2011-03-08 13:29 ` Mark Brown
@ 2011-03-08 13:34 ` Linus Walleij
0 siblings, 0 replies; 5+ messages in thread
From: Linus Walleij @ 2011-03-08 13:34 UTC (permalink / raw)
To: Mark Brown
Cc: Linus Walleij, Liam Girdwood, linux-kernel, Lee Jones,
Samuel Ortiz, Ola Lilja
On Tue, Mar 8, 2011 at 2:29 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
>> So the fact that the regulator driver doesn't probe doesn't mean any
>> failure, some other driver will likely probe successfully for the chip.
>
> The general approach other MFDs have taken to this is to pay attention
> to the platform data when registering subdevices so that you don't get
> inappropriate subdevices registered in the first place.
Ah, clever. I'll fix.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-03-08 13:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-08 9:42 [PATCH 2/3] regulator: add a subdriver for TI TPS6105x regulator portions Linus Walleij
2011-03-08 11:56 ` Mark Brown
2011-03-08 13:26 ` Linus Walleij
2011-03-08 13:29 ` Mark Brown
2011-03-08 13:34 ` Linus Walleij
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox