aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@arm.com>2012-09-24 13:56:54 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-10-14 22:56:08 -0400
commit31e54086dd7bb86ad40f1d76a9063f2a95866b87 (patch)
tree9e54d6dd2491ffa90ef10a4d8e86fd351497bdfe /drivers/regulator
parentbd7a2b600ace90c8819495b639a744c8f5c68feb (diff)
regulator: Versatile Express regulator driver
Implementation of the regulator framework driver for the Versatile Express voltage control. Devices without voltage constraints (ie. "regulator-[min|max]-microvolt" properties in the DT node) are treated as fixed (or rather read-only) regulators. Signed-off-by: Pawel Moll <pawel.moll@arm.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig7
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/vexpress.c146
3 files changed, 154 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 67d47b59a66d..b44b019b9433 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -422,6 +422,13 @@ config REGULATOR_TWL4030
422 This driver supports the voltage regulators provided by 422 This driver supports the voltage regulators provided by
423 this family of companion chips. 423 this family of companion chips.
424 424
425config REGULATOR_VEXPRESS
426 tristate "Versatile Express regulators"
427 depends on VEXPRESS_CONFIG
428 help
429 This driver provides support for voltage regulators available
430 on the ARM Ltd's Versatile Express platform.
431
425config REGULATOR_WM831X 432config REGULATOR_WM831X
426 tristate "Wolfson Microelectronics WM831x PMIC regulators" 433 tristate "Wolfson Microelectronics WM831x PMIC regulators"
427 depends on MFD_WM831X 434 depends on MFD_WM831X
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e431eed8a878..9fa7a7bc42d8 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
57obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o 57obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
58obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o 58obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
59obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o 59obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
60obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
60obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 61obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
61obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 62obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
62obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o 63obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c
new file mode 100644
index 000000000000..1702945a93a9
--- /dev/null
+++ b/drivers/regulator/vexpress.c
@@ -0,0 +1,146 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14#define DRVNAME "vexpress-regulator"
15#define pr_fmt(fmt) DRVNAME ": " fmt
16
17#include <linux/device.h>
18#include <linux/err.h>
19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/regulator/driver.h>
22#include <linux/regulator/machine.h>
23#include <linux/regulator/of_regulator.h>
24#include <linux/vexpress.h>
25
26struct vexpress_regulator {
27 struct regulator_desc desc;
28 struct regulator_dev *regdev;
29 struct vexpress_config_func *func;
30};
31
32static int vexpress_regulator_get_voltage(struct regulator_dev *regdev)
33{
34 struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
35 u32 uV;
36 int err = vexpress_config_read(reg->func, 0, &uV);
37
38 return err ? err : uV;
39}
40
41static int vexpress_regulator_set_voltage(struct regulator_dev *regdev,
42 int min_uV, int max_uV, unsigned *selector)
43{
44 struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
45
46 return vexpress_config_write(reg->func, 0, min_uV);
47}
48
49static struct regulator_ops vexpress_regulator_ops_ro = {
50 .get_voltage = vexpress_regulator_get_voltage,
51};
52
53static struct regulator_ops vexpress_regulator_ops = {
54 .get_voltage = vexpress_regulator_get_voltage,
55 .set_voltage = vexpress_regulator_set_voltage,
56};
57
58static int vexpress_regulator_probe(struct platform_device *pdev)
59{
60 int err;
61 struct vexpress_regulator *reg;
62 struct regulator_init_data *init_data;
63 struct regulator_config config = { };
64
65 reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL);
66 if (!reg) {
67 err = -ENOMEM;
68 goto error_kzalloc;
69 }
70
71 reg->func = vexpress_config_func_get_by_dev(&pdev->dev);
72 if (!reg->func) {
73 err = -ENXIO;
74 goto error_get_func;
75 }
76
77 reg->desc.name = dev_name(&pdev->dev);
78 reg->desc.type = REGULATOR_VOLTAGE;
79 reg->desc.owner = THIS_MODULE;
80 reg->desc.continuous_voltage_range = true;
81
82 init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
83 if (!init_data) {
84 err = -EINVAL;
85 goto error_get_regulator_init_data;
86 }
87
88 init_data->constraints.apply_uV = 0;
89 if (init_data->constraints.min_uV && init_data->constraints.max_uV)
90 reg->desc.ops = &vexpress_regulator_ops;
91 else
92 reg->desc.ops = &vexpress_regulator_ops_ro;
93
94 config.dev = &pdev->dev;
95 config.init_data = init_data;
96 config.driver_data = reg;
97 config.of_node = pdev->dev.of_node;
98
99 reg->regdev = regulator_register(&reg->desc, &config);
100 if (IS_ERR(reg->regdev)) {
101 err = PTR_ERR(reg->regdev);
102 goto error_regulator_register;
103 }
104
105 platform_set_drvdata(pdev, reg);
106
107 return 0;
108
109error_regulator_register:
110error_get_regulator_init_data:
111 vexpress_config_func_put(reg->func);
112error_get_func:
113error_kzalloc:
114 return err;
115}
116
117static int __devexit vexpress_regulator_remove(struct platform_device *pdev)
118{
119 struct vexpress_regulator *reg = platform_get_drvdata(pdev);
120
121 vexpress_config_func_put(reg->func);
122 regulator_unregister(reg->regdev);
123
124 return 0;
125}
126
127static struct of_device_id vexpress_regulator_of_match[] = {
128 { .compatible = "arm,vexpress-volt", },
129};
130
131static struct platform_driver vexpress_regulator_driver = {
132 .probe = vexpress_regulator_probe,
133 .remove = __devexit_p(vexpress_regulator_remove),
134 .driver = {
135 .name = DRVNAME,
136 .owner = THIS_MODULE,
137 .of_match_table = vexpress_regulator_of_match,
138 },
139};
140
141module_platform_driver(vexpress_regulator_driver);
142
143MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
144MODULE_DESCRIPTION("Versatile Express regulator");
145MODULE_LICENSE("GPL");
146MODULE_ALIAS("platform:vexpress-regulator");