aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2009-04-23 14:10:43 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2009-06-15 06:18:22 -0400
commit55f4fa4e33e90c6b25b4c8ed038392a73b654fef (patch)
tree59e9c50090ca6f2bc5ed1a743c0521560c77fcfa /drivers/regulator
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
Maxim 1586 regulator driver
The Maxim 1586 regulator is a voltage regulator with 2 voltage outputs, specially suitable for Marvell PXA chips. One output is in the range of required VCC_CORE by the PXA27x chips, the other in the VCC_USIM required as well by PXA27x chips. The chip is controlled through the I2C bus. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig9
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/max1586.c249
3 files changed, 259 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e58c0ce65aa..707da4d2353 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -56,6 +56,15 @@ config REGULATOR_BQ24022
56 charging select between 100 mA and 500 mA charging current 56 charging select between 100 mA and 500 mA charging current
57 limit. 57 limit.
58 58
59config REGULATOR_MAX1586
60 tristate "Maxim 1586/1587 voltage regulator"
61 depends on I2C
62 default n
63 help
64 This driver controls a Maxim 1586 or 1587 voltage output
65 regulator via I2C bus. The provided regulator is suitable
66 for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
67
59config REGULATOR_TWL4030 68config REGULATOR_TWL4030
60 bool "TI TWL4030/TWL5030/TPS695x0 PMIC" 69 bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
61 depends on TWL4030_CORE 70 depends on TWL4030_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bac133afc06..1d7de87a8e1 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
8obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o 8obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
9 9
10obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o 10obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
11obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
11obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o 12obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
12obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o 13obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
13obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o 14obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
new file mode 100644
index 00000000000..bbbb55fcfe8
--- /dev/null
+++ b/drivers/regulator/max1586.c
@@ -0,0 +1,249 @@
1/*
2 * max1586.c -- Voltage and current regulation for the Maxim 1586
3 *
4 * Copyright (C) 2008 Robert Jarzmik
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/module.h>
21#include <linux/err.h>
22#include <linux/i2c.h>
23#include <linux/platform_device.h>
24#include <linux/regulator/driver.h>
25#include <linux/regulator/max1586.h>
26
27#define MAX1586_V3_MAX_VSEL 31
28#define MAX1586_V6_MAX_VSEL 3
29
30#define MAX1586_V3_MIN_UV 700000
31#define MAX1586_V3_MAX_UV 1475000
32#define MAX1586_V3_STEP_UV 25000
33
34#define MAX1586_V6_MIN_UV 0
35#define MAX1586_V6_MAX_UV 3000000
36
37#define I2C_V3_SELECT (0 << 5)
38#define I2C_V6_SELECT (1 << 5)
39
40/*
41 * V3 voltage
42 * On I2C bus, sending a "x" byte to the max1586 means :
43 * set V3 to 0.700V + (x & 0x1f) * 0.025V
44 */
45static int max1586_v3_calc_voltage(unsigned selector)
46{
47 return MAX1586_V3_MIN_UV + (MAX1586_V3_STEP_UV * selector);
48}
49
50static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
51{
52 struct i2c_client *client = rdev_get_drvdata(rdev);
53 unsigned selector;
54 u8 v3_prog;
55
56 if (min_uV < MAX1586_V3_MIN_UV || min_uV > MAX1586_V3_MAX_UV)
57 return -EINVAL;
58 if (max_uV < MAX1586_V3_MIN_UV || max_uV > MAX1586_V3_MAX_UV)
59 return -EINVAL;
60
61 selector = (min_uV - MAX1586_V3_MIN_UV) / MAX1586_V3_STEP_UV;
62 if (max1586_v3_calc_voltage(selector) > max_uV)
63 return -EINVAL;
64
65 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
66 max1586_v3_calc_voltage(selector) / 1000);
67
68 v3_prog = I2C_V3_SELECT | (u8) selector;
69 return i2c_smbus_write_byte(client, v3_prog);
70}
71
72static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
73{
74 if (selector > MAX1586_V3_MAX_VSEL)
75 return -EINVAL;
76 return max1586_v3_calc_voltage(selector);
77}
78
79/*
80 * V6 voltage
81 * On I2C bus, sending a "x" byte to the max1586 means :
82 * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3)
83 * As regulator framework doesn't accept voltages to be 0V, we use 1uV.
84 */
85static int max1586_v6_calc_voltage(unsigned selector)
86{
87 static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
88
89 return voltages_uv[selector];
90}
91
92static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
93{
94 struct i2c_client *client = rdev_get_drvdata(rdev);
95 unsigned selector;
96 u8 v6_prog;
97
98 if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV)
99 return -EINVAL;
100 if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
101 return -EINVAL;
102
103 if (min_uV >= 3000000)
104 selector = 3;
105 if (min_uV < 3000000)
106 selector = 2;
107 if (min_uV < 2500000)
108 selector = 1;
109 if (min_uV < 1800000)
110 selector = 0;
111
112 if (max1586_v6_calc_voltage(selector) > max_uV)
113 return -EINVAL;
114
115 dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
116 max1586_v6_calc_voltage(selector) / 1000);
117
118 v6_prog = I2C_V6_SELECT | (u8) selector;
119 return i2c_smbus_write_byte(client, v6_prog);
120}
121
122static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector)
123{
124 if (selector > MAX1586_V6_MAX_VSEL)
125 return -EINVAL;
126 return max1586_v6_calc_voltage(selector);
127}
128
129/*
130 * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
131 * the set up value.
132 */
133static struct regulator_ops max1586_v3_ops = {
134 .set_voltage = max1586_v3_set,
135 .list_voltage = max1586_v3_list,
136};
137
138static struct regulator_ops max1586_v6_ops = {
139 .set_voltage = max1586_v6_set,
140 .list_voltage = max1586_v6_list,
141};
142
143static struct regulator_desc max1586_reg[] = {
144 {
145 .name = "Output_V3",
146 .id = MAX1586_V3,
147 .ops = &max1586_v3_ops,
148 .type = REGULATOR_VOLTAGE,
149 .n_voltages = MAX1586_V3_MAX_VSEL + 1,
150 .owner = THIS_MODULE,
151 },
152 {
153 .name = "Output_V6",
154 .id = MAX1586_V6,
155 .ops = &max1586_v6_ops,
156 .type = REGULATOR_VOLTAGE,
157 .n_voltages = MAX1586_V6_MAX_VSEL + 1,
158 .owner = THIS_MODULE,
159 },
160};
161
162static int max1586_pmic_probe(struct i2c_client *client,
163 const struct i2c_device_id *i2c_id)
164{
165 struct regulator_dev **rdev;
166 struct max1586_platform_data *pdata = client->dev.platform_data;
167 int i, id, ret = 0;
168
169 rdev = kzalloc(sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
170 GFP_KERNEL);
171 if (!rdev)
172 return -ENOMEM;
173
174 ret = -EINVAL;
175 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
176 id = pdata->subdevs[i].id;
177 if (!pdata->subdevs[i].platform_data)
178 continue;
179 if (id < MAX1586_V3 || id > MAX1586_V6) {
180 dev_err(&client->dev, "invalid regulator id %d\n", id);
181 goto err;
182 }
183 rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
184 pdata->subdevs[i].platform_data,
185 client);
186 if (IS_ERR(rdev[i])) {
187 ret = PTR_ERR(rdev[i]);
188 dev_err(&client->dev, "failed to register %s\n",
189 max1586_reg[id].name);
190 goto err;
191 }
192 }
193
194 i2c_set_clientdata(client, rdev);
195 dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
196 return 0;
197
198err:
199 while (--i >= 0)
200 regulator_unregister(rdev[i]);
201 kfree(rdev);
202 return ret;
203}
204
205static int max1586_pmic_remove(struct i2c_client *client)
206{
207 struct regulator_dev **rdev = i2c_get_clientdata(client);
208 int i;
209
210 for (i = 0; i <= MAX1586_V6; i++)
211 if (rdev[i])
212 regulator_unregister(rdev[i]);
213 kfree(rdev);
214 i2c_set_clientdata(client, NULL);
215
216 return 0;
217}
218
219static const struct i2c_device_id max1586_id[] = {
220 { "max1586", 0 },
221 { }
222};
223MODULE_DEVICE_TABLE(i2c, max1586_id);
224
225static struct i2c_driver max1586_pmic_driver = {
226 .probe = max1586_pmic_probe,
227 .remove = max1586_pmic_remove,
228 .driver = {
229 .name = "max1586",
230 },
231 .id_table = max1586_id,
232};
233
234static int __init max1586_pmic_init(void)
235{
236 return i2c_add_driver(&max1586_pmic_driver);
237}
238subsys_initcall(max1586_pmic_init);
239
240static void __exit max1586_pmic_exit(void)
241{
242 i2c_del_driver(&max1586_pmic_driver);
243}
244module_exit(max1586_pmic_exit);
245
246/* Module information */
247MODULE_DESCRIPTION("MAXIM 1586 voltage regulator driver");
248MODULE_AUTHOR("Robert Jarzmik");
249MODULE_LICENSE("GPL");