aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/Kconfig26
-rw-r--r--drivers/regulator/Makefile3
-rw-r--r--drivers/regulator/da903x.c2
-rw-r--r--drivers/regulator/fixed.c18
-rw-r--r--drivers/regulator/lp3971.c562
-rw-r--r--drivers/regulator/max1586.c282
-rw-r--r--drivers/regulator/pcf50633-regulator.c2
-rw-r--r--drivers/regulator/userspace-consumer.c200
-rw-r--r--drivers/regulator/virtual.c1
-rw-r--r--drivers/regulator/wm8350-regulator.c1
-rw-r--r--drivers/regulator/wm8400-regulator.c8
-rw-r--r--include/linux/regulator/lp3971.h51
-rw-r--r--include/linux/regulator/max1586.h63
-rw-r--r--include/linux/regulator/userspace-consumer.h25
14 files changed, 1236 insertions, 8 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e58c0ce65aa6..f4317798e47c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -47,6 +47,16 @@ config REGULATOR_VIRTUAL_CONSUMER
47 47
48 If unsure, say no. 48 If unsure, say no.
49 49
50config REGULATOR_USERSPACE_CONSUMER
51 tristate "Userspace regulator consumer support"
52 default n
53 help
54 There are some classes of devices that are controlled entirely
55 from user space. Usersapce consumer driver provides ability to
56 control power supplies for such devices.
57
58 If unsure, say no.
59
50config REGULATOR_BQ24022 60config REGULATOR_BQ24022
51 tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" 61 tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
52 default n 62 default n
@@ -56,6 +66,15 @@ config REGULATOR_BQ24022
56 charging select between 100 mA and 500 mA charging current 66 charging select between 100 mA and 500 mA charging current
57 limit. 67 limit.
58 68
69config REGULATOR_MAX1586
70 tristate "Maxim 1586/1587 voltage regulator"
71 depends on I2C
72 default n
73 help
74 This driver controls a Maxim 1586 or 1587 voltage output
75 regulator via I2C bus. The provided regulator is suitable
76 for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
77
59config REGULATOR_TWL4030 78config REGULATOR_TWL4030
60 bool "TI TWL4030/TWL5030/TPS695x0 PMIC" 79 bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
61 depends on TWL4030_CORE 80 depends on TWL4030_CORE
@@ -91,4 +110,11 @@ config REGULATOR_PCF50633
91 Say Y here to support the voltage regulators and convertors 110 Say Y here to support the voltage regulators and convertors
92 on PCF50633 111 on PCF50633
93 112
113config REGULATOR_LP3971
114 tristate "National Semiconductors LP3971 PMIC regulator driver"
115 depends on I2C
116 help
117 Say Y here to support the voltage regulators and convertors
118 on National Semiconductors LP3971 PMIC
119
94endif 120endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bac133afc061..4d762c4cccfd 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -6,8 +6,11 @@
6obj-$(CONFIG_REGULATOR) += core.o 6obj-$(CONFIG_REGULATOR) += core.o
7obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o 7obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
8obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o 8obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
9obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
9 10
10obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o 11obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
12obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
13obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
11obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o 14obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
12obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o 15obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
13obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o 16obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index c6628f5a0af7..b8b89ef10a84 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -504,7 +504,7 @@ static int __init da903x_regulator_init(void)
504{ 504{
505 return platform_driver_register(&da903x_regulator_driver); 505 return platform_driver_register(&da903x_regulator_driver);
506} 506}
507module_init(da903x_regulator_init); 507subsys_initcall(da903x_regulator_init);
508 508
509static void __exit da903x_regulator_exit(void) 509static void __exit da903x_regulator_exit(void)
510{ 510{
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 23d554628a76..cdc674fb46c3 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -44,10 +44,22 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)
44 return data->microvolts; 44 return data->microvolts;
45} 45}
46 46
47static int fixed_voltage_list_voltage(struct regulator_dev *dev,
48 unsigned selector)
49{
50 struct fixed_voltage_data *data = rdev_get_drvdata(dev);
51
52 if (selector != 0)
53 return -EINVAL;
54
55 return data->microvolts;
56}
57
47static struct regulator_ops fixed_voltage_ops = { 58static struct regulator_ops fixed_voltage_ops = {
48 .is_enabled = fixed_voltage_is_enabled, 59 .is_enabled = fixed_voltage_is_enabled,
49 .enable = fixed_voltage_enable, 60 .enable = fixed_voltage_enable,
50 .get_voltage = fixed_voltage_get_voltage, 61 .get_voltage = fixed_voltage_get_voltage,
62 .list_voltage = fixed_voltage_list_voltage,
51}; 63};
52 64
53static int regulator_fixed_voltage_probe(struct platform_device *pdev) 65static int regulator_fixed_voltage_probe(struct platform_device *pdev)
@@ -69,7 +81,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
69 } 81 }
70 drvdata->desc.type = REGULATOR_VOLTAGE; 82 drvdata->desc.type = REGULATOR_VOLTAGE;
71 drvdata->desc.owner = THIS_MODULE; 83 drvdata->desc.owner = THIS_MODULE;
72 drvdata->desc.ops = &fixed_voltage_ops, 84 drvdata->desc.ops = &fixed_voltage_ops;
85 drvdata->desc.n_voltages = 1;
73 86
74 drvdata->microvolts = config->microvolts; 87 drvdata->microvolts = config->microvolts;
75 88
@@ -117,7 +130,7 @@ static int __init regulator_fixed_voltage_init(void)
117{ 130{
118 return platform_driver_register(&regulator_fixed_voltage_driver); 131 return platform_driver_register(&regulator_fixed_voltage_driver);
119} 132}
120module_init(regulator_fixed_voltage_init); 133subsys_initcall(regulator_fixed_voltage_init);
121 134
122static void __exit regulator_fixed_voltage_exit(void) 135static void __exit regulator_fixed_voltage_exit(void)
123{ 136{
@@ -128,3 +141,4 @@ module_exit(regulator_fixed_voltage_exit);
128MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 141MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
129MODULE_DESCRIPTION("Fixed voltage regulator"); 142MODULE_DESCRIPTION("Fixed voltage regulator");
130MODULE_LICENSE("GPL"); 143MODULE_LICENSE("GPL");
144MODULE_ALIAS("platform:reg-fixed-voltage");
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
new file mode 100644
index 000000000000..a61018a27698
--- /dev/null
+++ b/drivers/regulator/lp3971.c
@@ -0,0 +1,562 @@
1/*
2 * Regulator driver for National Semiconductors LP3971 PMIC chip
3 *
4 * Copyright (C) 2009 Samsung Electronics
5 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
6 *
7 * Based on wm8350.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/bug.h>
16#include <linux/err.h>
17#include <linux/i2c.h>
18#include <linux/kernel.h>
19#include <linux/regulator/driver.h>
20#include <linux/regulator/lp3971.h>
21
22struct lp3971 {
23 struct device *dev;
24 struct mutex io_lock;
25 struct i2c_client *i2c;
26 int num_regulators;
27 struct regulator_dev **rdev;
28};
29
30static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
31static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
32
33#define LP3971_SYS_CONTROL1_REG 0x07
34
35/* System control register 1 initial value,
36 bits 4 and 5 are EPROM programmable */
37#define SYS_CONTROL1_INIT_VAL 0x40
38#define SYS_CONTROL1_INIT_MASK 0xCF
39
40#define LP3971_BUCK_VOL_ENABLE_REG 0x10
41#define LP3971_BUCK_VOL_CHANGE_REG 0x20
42
43/* Voltage control registers shift:
44 LP3971_BUCK1 -> 0
45 LP3971_BUCK2 -> 4
46 LP3971_BUCK3 -> 6
47*/
48#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
49#define BUCK_VOL_CHANGE_FLAG_GO 0x01
50#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
51#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
52
53#define LP3971_BUCK1_BASE 0x23
54#define LP3971_BUCK2_BASE 0x29
55#define LP3971_BUCK3_BASE 0x32
56
57const static int buck_base_addr[] = {
58 LP3971_BUCK1_BASE,
59 LP3971_BUCK2_BASE,
60 LP3971_BUCK3_BASE,
61};
62
63#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
64#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
65
66const static int buck_voltage_map[] = {
67 0, 800, 850, 900, 950, 1000, 1050, 1100,
68 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
69 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
70 3000, 3300,
71};
72
73#define BUCK_TARGET_VOL_MASK 0x3f
74#define BUCK_TARGET_VOL_MIN_IDX 0x01
75#define BUCK_TARGET_VOL_MAX_IDX 0x19
76
77#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
78
79#define LP3971_LDO_ENABLE_REG 0x12
80#define LP3971_LDO_VOL_CONTR_BASE 0x39
81
82/* Voltage control registers:
83 LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
84 LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
85 LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
86 LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
87 LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
88*/
89#define LP3971_LDO_VOL_CONTR_REG(x) (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
90
91/* Voltage control registers shift:
92 LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
93 LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
94 LP3971_LDO5 -> 0
95*/
96#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
97#define LDO_VOL_CONTR_MASK 0x0f
98
99const static int ldo45_voltage_map[] = {
100 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
101 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
102};
103
104const static int ldo123_voltage_map[] = {
105 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
106 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
107};
108
109const static int *ldo_voltage_map[] = {
110 ldo123_voltage_map, /* LDO1 */
111 ldo123_voltage_map, /* LDO2 */
112 ldo123_voltage_map, /* LDO3 */
113 ldo45_voltage_map, /* LDO4 */
114 ldo45_voltage_map, /* LDO5 */
115};
116
117#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
118
119#define LDO_VOL_MIN_IDX 0x00
120#define LDO_VOL_MAX_IDX 0x0f
121
122static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
123{
124 int ldo = rdev_get_id(dev) - LP3971_LDO1;
125 return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
126}
127
128static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
129{
130 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
131 int ldo = rdev_get_id(dev) - LP3971_LDO1;
132 u16 mask = 1 << (1 + ldo);
133 u16 val;
134
135 val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
136 return (val & mask) != 0;
137}
138
139static int lp3971_ldo_enable(struct regulator_dev *dev)
140{
141 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
142 int ldo = rdev_get_id(dev) - LP3971_LDO1;
143 u16 mask = 1 << (1 + ldo);
144
145 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
146}
147
148static int lp3971_ldo_disable(struct regulator_dev *dev)
149{
150 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
151 int ldo = rdev_get_id(dev) - LP3971_LDO1;
152 u16 mask = 1 << (1 + ldo);
153
154 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
155}
156
157static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
158{
159 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
160 int ldo = rdev_get_id(dev) - LP3971_LDO1;
161 u16 val, reg;
162
163 reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
164 val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
165
166 return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
167}
168
169static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
170 int min_uV, int max_uV)
171{
172 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
173 int ldo = rdev_get_id(dev) - LP3971_LDO1;
174 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
175 const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
176 u16 val;
177
178 if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
179 min_vol > vol_map[LDO_VOL_MAX_IDX])
180 return -EINVAL;
181
182 for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
183 if (vol_map[val] >= min_vol)
184 break;
185
186 if (vol_map[val] > max_vol)
187 return -EINVAL;
188
189 return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
190 LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
191}
192
193static struct regulator_ops lp3971_ldo_ops = {
194 .list_voltage = lp3971_ldo_list_voltage,
195 .is_enabled = lp3971_ldo_is_enabled,
196 .enable = lp3971_ldo_enable,
197 .disable = lp3971_ldo_disable,
198 .get_voltage = lp3971_ldo_get_voltage,
199 .set_voltage = lp3971_ldo_set_voltage,
200};
201
202static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
203{
204 return 1000 * buck_voltage_map[index];
205}
206
207static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
208{
209 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
210 int buck = rdev_get_id(dev) - LP3971_DCDC1;
211 u16 mask = 1 << (buck * 2);
212 u16 val;
213
214 val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
215 return (val & mask) != 0;
216}
217
218static int lp3971_dcdc_enable(struct regulator_dev *dev)
219{
220 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
221 int buck = rdev_get_id(dev) - LP3971_DCDC1;
222 u16 mask = 1 << (buck * 2);
223
224 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
225}
226
227static int lp3971_dcdc_disable(struct regulator_dev *dev)
228{
229 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
230 int buck = rdev_get_id(dev) - LP3971_DCDC1;
231 u16 mask = 1 << (buck * 2);
232
233 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
234}
235
236static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
237{
238 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
239 int buck = rdev_get_id(dev) - LP3971_DCDC1;
240 u16 reg;
241 int val;
242
243 reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
244 reg &= BUCK_TARGET_VOL_MASK;
245
246 if (reg <= BUCK_TARGET_VOL_MAX_IDX)
247 val = 1000 * buck_voltage_map[reg];
248 else {
249 val = 0;
250 dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
251 }
252
253 return val;
254}
255
256static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
257 int min_uV, int max_uV)
258{
259 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
260 int buck = rdev_get_id(dev) - LP3971_DCDC1;
261 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
262 const int *vol_map = buck_voltage_map;
263 u16 val;
264 int ret;
265
266 if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
267 min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
268 return -EINVAL;
269
270 for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
271 val++)
272 if (vol_map[val] >= min_vol)
273 break;
274
275 if (vol_map[val] > max_vol)
276 return -EINVAL;
277
278 ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
279 BUCK_TARGET_VOL_MASK, val);
280 if (ret)
281 return ret;
282
283 ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
284 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
285 BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
286 if (ret)
287 return ret;
288
289 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
290 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
291 0 << BUCK_VOL_CHANGE_SHIFT(buck));
292}
293
294static struct regulator_ops lp3971_dcdc_ops = {
295 .list_voltage = lp3971_dcdc_list_voltage,
296 .is_enabled = lp3971_dcdc_is_enabled,
297 .enable = lp3971_dcdc_enable,
298 .disable = lp3971_dcdc_disable,
299 .get_voltage = lp3971_dcdc_get_voltage,
300 .set_voltage = lp3971_dcdc_set_voltage,
301};
302
303static struct regulator_desc regulators[] = {
304 {
305 .name = "LDO1",
306 .id = LP3971_LDO1,
307 .ops = &lp3971_ldo_ops,
308 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
309 .type = REGULATOR_VOLTAGE,
310 .owner = THIS_MODULE,
311 },
312 {
313 .name = "LDO2",
314 .id = LP3971_LDO2,
315 .ops = &lp3971_ldo_ops,
316 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
317 .type = REGULATOR_VOLTAGE,
318 .owner = THIS_MODULE,
319 },
320 {
321 .name = "LDO3",
322 .id = LP3971_LDO3,
323 .ops = &lp3971_ldo_ops,
324 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
325 .type = REGULATOR_VOLTAGE,
326 .owner = THIS_MODULE,
327 },
328 {
329 .name = "LDO4",
330 .id = LP3971_LDO4,
331 .ops = &lp3971_ldo_ops,
332 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
333 .type = REGULATOR_VOLTAGE,
334 .owner = THIS_MODULE,
335 },
336 {
337 .name = "LDO5",
338 .id = LP3971_LDO5,
339 .ops = &lp3971_ldo_ops,
340 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
341 .type = REGULATOR_VOLTAGE,
342 .owner = THIS_MODULE,
343 },
344 {
345 .name = "DCDC1",
346 .id = LP3971_DCDC1,
347 .ops = &lp3971_dcdc_ops,
348 .n_voltages = ARRAY_SIZE(buck_voltage_map),
349 .type = REGULATOR_VOLTAGE,
350 .owner = THIS_MODULE,
351 },
352 {
353 .name = "DCDC2",
354 .id = LP3971_DCDC2,
355 .ops = &lp3971_dcdc_ops,
356 .n_voltages = ARRAY_SIZE(buck_voltage_map),
357 .type = REGULATOR_VOLTAGE,
358 .owner = THIS_MODULE,
359 },
360 {
361 .name = "DCDC3",
362 .id = LP3971_DCDC3,
363 .ops = &lp3971_dcdc_ops,
364 .n_voltages = ARRAY_SIZE(buck_voltage_map),
365 .type = REGULATOR_VOLTAGE,
366 .owner = THIS_MODULE,
367 },
368};
369
370static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
371 u16 *dest)
372{
373 int ret;
374
375 if (count != 1)
376 return -EIO;
377 ret = i2c_smbus_read_byte_data(i2c, reg);
378 if (ret < 0 || count != 1)
379 return -EIO;
380
381 *dest = ret;
382 return 0;
383}
384
385static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
386 const u16 *src)
387{
388 int ret;
389
390 if (count != 1)
391 return -EIO;
392 ret = i2c_smbus_write_byte_data(i2c, reg, *src);
393 if (ret >= 0)
394 return 0;
395
396 return ret;
397}
398
399static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
400{
401 u16 val = 0;
402
403 mutex_lock(&lp3971->io_lock);
404
405 lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
406
407 dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
408 (unsigned)val&0xff);
409
410 mutex_unlock(&lp3971->io_lock);
411
412 return val & 0xff;
413}
414
415static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
416{
417 u16 tmp;
418 int ret;
419
420 mutex_lock(&lp3971->io_lock);
421
422 ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
423 tmp = (tmp & ~mask) | val;
424 if (ret == 0) {
425 ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
426 dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
427 (unsigned)val&0xff);
428 }
429 mutex_unlock(&lp3971->io_lock);
430
431 return ret;
432}
433
434static int setup_regulators(struct lp3971 *lp3971,
435 struct lp3971_platform_data *pdata)
436{
437 int i, err;
438 int num_regulators = pdata->num_regulators;
439 lp3971->num_regulators = num_regulators;
440 lp3971->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
441 GFP_KERNEL);
442
443 /* Instantiate the regulators */
444 for (i = 0; i < num_regulators; i++) {
445 int id = pdata->regulators[i].id;
446 lp3971->rdev[i] = regulator_register(&regulators[id],
447 lp3971->dev, pdata->regulators[i].initdata, lp3971);
448
449 err = IS_ERR(lp3971->rdev[i]);
450 if (err) {
451 dev_err(lp3971->dev, "regulator init failed: %d\n",
452 err);
453 goto error;
454 }
455 }
456
457 return 0;
458error:
459 for (i = 0; i < num_regulators; i++)
460 if (lp3971->rdev[i])
461 regulator_unregister(lp3971->rdev[i]);
462 kfree(lp3971->rdev);
463 lp3971->rdev = NULL;
464 return err;
465}
466
467static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
468 const struct i2c_device_id *id)
469{
470 struct lp3971 *lp3971;
471 struct lp3971_platform_data *pdata = i2c->dev.platform_data;
472 int ret;
473 u16 val;
474
475 lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
476 if (lp3971 == NULL) {
477 ret = -ENOMEM;
478 goto err;
479 }
480
481 lp3971->i2c = i2c;
482 lp3971->dev = &i2c->dev;
483 i2c_set_clientdata(i2c, lp3971);
484
485 mutex_init(&lp3971->io_lock);
486
487 /* Detect LP3971 */
488 ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
489 if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
490 ret = -ENODEV;
491 if (ret < 0) {
492 dev_err(&i2c->dev, "failed to detect device\n");
493 goto err_detect;
494 }
495
496 if (pdata) {
497 ret = setup_regulators(lp3971, pdata);
498 if (ret < 0)
499 goto err_detect;
500 } else
501 dev_warn(lp3971->dev, "No platform init data supplied\n");
502
503 return 0;
504
505err_detect:
506 i2c_set_clientdata(i2c, NULL);
507 kfree(lp3971);
508err:
509 return ret;
510}
511
512static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
513{
514 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
515 int i;
516 for (i = 0; i < lp3971->num_regulators; i++)
517 if (lp3971->rdev[i])
518 regulator_unregister(lp3971->rdev[i]);
519 kfree(lp3971->rdev);
520 i2c_set_clientdata(i2c, NULL);
521 kfree(lp3971);
522
523 return 0;
524}
525
526static const struct i2c_device_id lp3971_i2c_id[] = {
527 { "lp3971", 0 },
528 { }
529};
530MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
531
532static struct i2c_driver lp3971_i2c_driver = {
533 .driver = {
534 .name = "LP3971",
535 .owner = THIS_MODULE,
536 },
537 .probe = lp3971_i2c_probe,
538 .remove = __devexit_p(lp3971_i2c_remove),
539 .id_table = lp3971_i2c_id,
540};
541
542static int __init lp3971_module_init(void)
543{
544 int ret = -ENODEV;
545
546 ret = i2c_add_driver(&lp3971_i2c_driver);
547 if (ret != 0)
548 pr_err("Failed to register I2C driver: %d\n", ret);
549
550 return ret;
551}
552module_init(lp3971_module_init);
553
554static void __exit lp3971_module_exit(void)
555{
556 i2c_del_driver(&lp3971_i2c_driver);
557}
558module_exit(lp3971_module_exit);
559
560MODULE_LICENSE("GPL");
561MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
562MODULE_DESCRIPTION("LP3971 PMIC driver");
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
new file mode 100644
index 000000000000..2c082d3ef484
--- /dev/null
+++ b/drivers/regulator/max1586.c
@@ -0,0 +1,282 @@
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
33#define MAX1586_V6_MIN_UV 0
34#define MAX1586_V6_MAX_UV 3000000
35
36#define I2C_V3_SELECT (0 << 5)
37#define I2C_V6_SELECT (1 << 5)
38
39struct max1586_data {
40 struct i2c_client *client;
41
42 /* min/max V3 voltage */
43 unsigned int min_uV;
44 unsigned int max_uV;
45
46 struct regulator_dev *rdev[0];
47};
48
49/*
50 * V3 voltage
51 * On I2C bus, sending a "x" byte to the max1586 means :
52 * set V3 to 0.700V + (x & 0x1f) * 0.025V
53 * This voltage can be increased by external resistors
54 * R24 and R25=100kOhm as described in the data sheet.
55 * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
56 */
57static int max1586_v3_calc_voltage(struct max1586_data *max1586,
58 unsigned selector)
59{
60 unsigned range_uV = max1586->max_uV - max1586->min_uV;
61
62 return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL);
63}
64
65static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
66{
67 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
68 struct i2c_client *client = max1586->client;
69 unsigned range_uV = max1586->max_uV - max1586->min_uV;
70 unsigned selector;
71 u8 v3_prog;
72
73 if (min_uV > max1586->max_uV || max_uV < max1586->min_uV)
74 return -EINVAL;
75 if (min_uV < max1586->min_uV)
76 min_uV = max1586->min_uV;
77
78 selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL +
79 range_uV - 1) / range_uV;
80 if (max1586_v3_calc_voltage(max1586, selector) > max_uV)
81 return -EINVAL;
82
83 dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
84 max1586_v3_calc_voltage(max1586, selector) / 1000);
85
86 v3_prog = I2C_V3_SELECT | (u8) selector;
87 return i2c_smbus_write_byte(client, v3_prog);
88}
89
90static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
91{
92 struct max1586_data *max1586 = rdev_get_drvdata(rdev);
93
94 if (selector > MAX1586_V3_MAX_VSEL)
95 return -EINVAL;
96 return max1586_v3_calc_voltage(max1586, selector);
97}
98
99/*
100 * V6 voltage
101 * On I2C bus, sending a "x" byte to the max1586 means :
102 * set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3)
103 * As regulator framework doesn't accept voltages to be 0V, we use 1uV.
104 */
105static int max1586_v6_calc_voltage(unsigned selector)
106{
107 static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
108
109 return voltages_uv[selector];
110}
111
112static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
113{
114 struct i2c_client *client = rdev_get_drvdata(rdev);
115 unsigned selector;
116 u8 v6_prog;
117
118 if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV)
119 return -EINVAL;
120 if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
121 return -EINVAL;
122
123 if (min_uV >= 3000000)
124 selector = 3;
125 if (min_uV < 3000000)
126 selector = 2;
127 if (min_uV < 2500000)
128 selector = 1;
129 if (min_uV < 1800000)
130 selector = 0;
131
132 if (max1586_v6_calc_voltage(selector) > max_uV)
133 return -EINVAL;
134
135 dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
136 max1586_v6_calc_voltage(selector) / 1000);
137
138 v6_prog = I2C_V6_SELECT | (u8) selector;
139 return i2c_smbus_write_byte(client, v6_prog);
140}
141
142static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector)
143{
144 if (selector > MAX1586_V6_MAX_VSEL)
145 return -EINVAL;
146 return max1586_v6_calc_voltage(selector);
147}
148
149/*
150 * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
151 * the set up value.
152 */
153static struct regulator_ops max1586_v3_ops = {
154 .set_voltage = max1586_v3_set,
155 .list_voltage = max1586_v3_list,
156};
157
158static struct regulator_ops max1586_v6_ops = {
159 .set_voltage = max1586_v6_set,
160 .list_voltage = max1586_v6_list,
161};
162
163static struct regulator_desc max1586_reg[] = {
164 {
165 .name = "Output_V3",
166 .id = MAX1586_V3,
167 .ops = &max1586_v3_ops,
168 .type = REGULATOR_VOLTAGE,
169 .n_voltages = MAX1586_V3_MAX_VSEL + 1,
170 .owner = THIS_MODULE,
171 },
172 {
173 .name = "Output_V6",
174 .id = MAX1586_V6,
175 .ops = &max1586_v6_ops,
176 .type = REGULATOR_VOLTAGE,
177 .n_voltages = MAX1586_V6_MAX_VSEL + 1,
178 .owner = THIS_MODULE,
179 },
180};
181
182static int max1586_pmic_probe(struct i2c_client *client,
183 const struct i2c_device_id *i2c_id)
184{
185 struct regulator_dev **rdev;
186 struct max1586_platform_data *pdata = client->dev.platform_data;
187 struct max1586_data *max1586;
188 int i, id, ret = -ENOMEM;
189
190 max1586 = kzalloc(sizeof(struct max1586_data) +
191 sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
192 GFP_KERNEL);
193 if (!max1586)
194 goto out;
195
196 max1586->client = client;
197
198 if (!pdata->v3_gain) {
199 ret = -EINVAL;
200 goto out_unmap;
201 }
202 max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
203 max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
204
205 rdev = max1586->rdev;
206 for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
207 id = pdata->subdevs[i].id;
208 if (!pdata->subdevs[i].platform_data)
209 continue;
210 if (id < MAX1586_V3 || id > MAX1586_V6) {
211 dev_err(&client->dev, "invalid regulator id %d\n", id);
212 goto err;
213 }
214 rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
215 pdata->subdevs[i].platform_data,
216 max1586);
217 if (IS_ERR(rdev[i])) {
218 ret = PTR_ERR(rdev[i]);
219 dev_err(&client->dev, "failed to register %s\n",
220 max1586_reg[id].name);
221 goto err;
222 }
223 }
224
225 i2c_set_clientdata(client, rdev);
226 dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
227 return 0;
228
229err:
230 while (--i >= 0)
231 regulator_unregister(rdev[i]);
232out_unmap:
233 kfree(max1586);
234out:
235 return ret;
236}
237
238static int max1586_pmic_remove(struct i2c_client *client)
239{
240 struct regulator_dev **rdev = i2c_get_clientdata(client);
241 int i;
242
243 for (i = 0; i <= MAX1586_V6; i++)
244 if (rdev[i])
245 regulator_unregister(rdev[i]);
246 kfree(rdev);
247 i2c_set_clientdata(client, NULL);
248
249 return 0;
250}
251
252static const struct i2c_device_id max1586_id[] = {
253 { "max1586", 0 },
254 { }
255};
256MODULE_DEVICE_TABLE(i2c, max1586_id);
257
258static struct i2c_driver max1586_pmic_driver = {
259 .probe = max1586_pmic_probe,
260 .remove = max1586_pmic_remove,
261 .driver = {
262 .name = "max1586",
263 },
264 .id_table = max1586_id,
265};
266
267static int __init max1586_pmic_init(void)
268{
269 return i2c_add_driver(&max1586_pmic_driver);
270}
271subsys_initcall(max1586_pmic_init);
272
273static void __exit max1586_pmic_exit(void)
274{
275 i2c_del_driver(&max1586_pmic_driver);
276}
277module_exit(max1586_pmic_exit);
278
279/* Module information */
280MODULE_DESCRIPTION("MAXIM 1586 voltage regulator driver");
281MODULE_AUTHOR("Robert Jarzmik");
282MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index cd761d85c8fd..8e14900eb686 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -316,7 +316,7 @@ static int __init pcf50633_regulator_init(void)
316{ 316{
317 return platform_driver_register(&pcf50633_regulator_driver); 317 return platform_driver_register(&pcf50633_regulator_driver);
318} 318}
319module_init(pcf50633_regulator_init); 319subsys_initcall(pcf50633_regulator_init);
320 320
321static void __exit pcf50633_regulator_exit(void) 321static void __exit pcf50633_regulator_exit(void)
322{ 322{
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
new file mode 100644
index 000000000000..06d2fa96a8b4
--- /dev/null
+++ b/drivers/regulator/userspace-consumer.c
@@ -0,0 +1,200 @@
1/*
2 * userspace-consumer.c
3 *
4 * Copyright 2009 CompuLab, Ltd.
5 *
6 * Author: Mike Rapoport <mike@compulab.co.il>
7 *
8 * Based of virtual consumer driver:
9 * Copyright 2008 Wolfson Microelectronics PLC.
10 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 */
18
19#include <linux/err.h>
20#include <linux/mutex.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/userspace-consumer.h>
24
25struct userspace_consumer_data {
26 const char *name;
27
28 struct mutex lock;
29 bool enabled;
30
31 int num_supplies;
32 struct regulator_bulk_data *supplies;
33};
34
35static ssize_t reg_show_name(struct device *dev,
36 struct device_attribute *attr, char *buf)
37{
38 struct userspace_consumer_data *data = dev_get_drvdata(dev);
39
40 return sprintf(buf, "%s\n", data->name);
41}
42
43static ssize_t reg_show_state(struct device *dev,
44 struct device_attribute *attr, char *buf)
45{
46 struct userspace_consumer_data *data = dev_get_drvdata(dev);
47
48 if (data->enabled)
49 return sprintf(buf, "enabled\n");
50
51 return sprintf(buf, "disabled\n");
52}
53
54static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
55 const char *buf, size_t count)
56{
57 struct userspace_consumer_data *data = dev_get_drvdata(dev);
58 bool enabled;
59 int ret;
60
61 /*
62 * sysfs_streq() doesn't need the \n's, but we add them so the strings
63 * will be shared with show_state(), above.
64 */
65 if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))
66 enabled = true;
67 else if (sysfs_streq(buf, "disabled\n") || sysfs_streq(buf, "0"))
68 enabled = false;
69 else {
70 dev_err(dev, "Configuring invalid mode\n");
71 return count;
72 }
73
74 mutex_lock(&data->lock);
75 if (enabled != data->enabled) {
76 if (enabled)
77 ret = regulator_bulk_enable(data->num_supplies,
78 data->supplies);
79 else
80 ret = regulator_bulk_disable(data->num_supplies,
81 data->supplies);
82
83 if (ret == 0)
84 data->enabled = enabled;
85 else
86 dev_err(dev, "Failed to configure state: %d\n", ret);
87 }
88 mutex_unlock(&data->lock);
89
90 return count;
91}
92
93static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
94static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
95
96static struct device_attribute *attributes[] = {
97 &dev_attr_name,
98 &dev_attr_state,
99};
100
101static int regulator_userspace_consumer_probe(struct platform_device *pdev)
102{
103 struct regulator_userspace_consumer_data *pdata;
104 struct userspace_consumer_data *drvdata;
105 int ret, i;
106
107 pdata = pdev->dev.platform_data;
108 if (!pdata)
109 return -EINVAL;
110
111 drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL);
112 if (drvdata == NULL)
113 return -ENOMEM;
114
115 drvdata->name = pdata->name;
116 drvdata->num_supplies = pdata->num_supplies;
117 drvdata->supplies = pdata->supplies;
118
119 mutex_init(&drvdata->lock);
120
121 ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies,
122 drvdata->supplies);
123 if (ret) {
124 dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
125 goto err_alloc_supplies;
126 }
127
128 for (i = 0; i < ARRAY_SIZE(attributes); i++) {
129 ret = device_create_file(&pdev->dev, attributes[i]);
130 if (ret != 0)
131 goto err_create_attrs;
132 }
133
134 if (pdata->init_on)
135 ret = regulator_bulk_enable(drvdata->num_supplies,
136 drvdata->supplies);
137
138 drvdata->enabled = pdata->init_on;
139
140 if (ret) {
141 dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret);
142 goto err_create_attrs;
143 }
144
145 platform_set_drvdata(pdev, drvdata);
146
147 return 0;
148
149err_create_attrs:
150 for (i = 0; i < ARRAY_SIZE(attributes); i++)
151 device_remove_file(&pdev->dev, attributes[i]);
152
153 regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
154
155err_alloc_supplies:
156 kfree(drvdata);
157 return ret;
158}
159
160static int regulator_userspace_consumer_remove(struct platform_device *pdev)
161{
162 struct userspace_consumer_data *data = platform_get_drvdata(pdev);
163 int i;
164
165 for (i = 0; i < ARRAY_SIZE(attributes); i++)
166 device_remove_file(&pdev->dev, attributes[i]);
167
168 if (data->enabled)
169 regulator_bulk_disable(data->num_supplies, data->supplies);
170
171 regulator_bulk_free(data->num_supplies, data->supplies);
172 kfree(data);
173
174 return 0;
175}
176
177static struct platform_driver regulator_userspace_consumer_driver = {
178 .probe = regulator_userspace_consumer_probe,
179 .remove = regulator_userspace_consumer_remove,
180 .driver = {
181 .name = "reg-userspace-consumer",
182 },
183};
184
185
186static int __init regulator_userspace_consumer_init(void)
187{
188 return platform_driver_register(&regulator_userspace_consumer_driver);
189}
190module_init(regulator_userspace_consumer_init);
191
192static void __exit regulator_userspace_consumer_exit(void)
193{
194 platform_driver_unregister(&regulator_userspace_consumer_driver);
195}
196module_exit(regulator_userspace_consumer_exit);
197
198MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
199MODULE_DESCRIPTION("Userspace consumer for voltage and current regulators");
200MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 71403fa3ffa1..e7db5664722e 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -347,3 +347,4 @@ module_exit(regulator_virtual_consumer_exit);
347MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 347MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
348MODULE_DESCRIPTION("Virtual regulator consumer"); 348MODULE_DESCRIPTION("Virtual regulator consumer");
349MODULE_LICENSE("GPL"); 349MODULE_LICENSE("GPL");
350MODULE_ALIAS("platform:reg-virt-consumer");
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 771eca1066b5..17a00b0fafd1 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1570,3 +1570,4 @@ module_exit(wm8350_regulator_exit);
1570MODULE_AUTHOR("Liam Girdwood"); 1570MODULE_AUTHOR("Liam Girdwood");
1571MODULE_DESCRIPTION("WM8350 voltage and current regulator driver"); 1571MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
1572MODULE_LICENSE("GPL"); 1572MODULE_LICENSE("GPL");
1573MODULE_ALIAS("platform:wm8350-regulator");
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 157426029071..d9a2c988c6e7 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -320,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
320 struct regulator_dev *rdev; 320 struct regulator_dev *rdev;
321 321
322 rdev = regulator_register(&regulators[pdev->id], &pdev->dev, 322 rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
323 pdev->dev.platform_data, pdev->dev.driver_data); 323 pdev->dev.platform_data, dev_get_drvdata(&pdev->dev));
324 324
325 if (IS_ERR(rdev)) 325 if (IS_ERR(rdev))
326 return PTR_ERR(rdev); 326 return PTR_ERR(rdev);
@@ -359,7 +359,7 @@ static struct platform_driver wm8400_regulator_driver = {
359int wm8400_register_regulator(struct device *dev, int reg, 359int wm8400_register_regulator(struct device *dev, int reg,
360 struct regulator_init_data *initdata) 360 struct regulator_init_data *initdata)
361{ 361{
362 struct wm8400 *wm8400 = dev->driver_data; 362 struct wm8400 *wm8400 = dev_get_drvdata(dev);
363 363
364 if (wm8400->regulators[reg].name) 364 if (wm8400->regulators[reg].name)
365 return -EBUSY; 365 return -EBUSY;
@@ -369,8 +369,8 @@ int wm8400_register_regulator(struct device *dev, int reg,
369 wm8400->regulators[reg].name = "wm8400-regulator"; 369 wm8400->regulators[reg].name = "wm8400-regulator";
370 wm8400->regulators[reg].id = reg; 370 wm8400->regulators[reg].id = reg;
371 wm8400->regulators[reg].dev.parent = dev; 371 wm8400->regulators[reg].dev.parent = dev;
372 wm8400->regulators[reg].dev.driver_data = wm8400;
373 wm8400->regulators[reg].dev.platform_data = initdata; 372 wm8400->regulators[reg].dev.platform_data = initdata;
373 dev_set_drvdata(&wm8400->regulators[reg].dev, wm8400);
374 374
375 return platform_device_register(&wm8400->regulators[reg]); 375 return platform_device_register(&wm8400->regulators[reg]);
376} 376}
@@ -380,7 +380,7 @@ static int __init wm8400_regulator_init(void)
380{ 380{
381 return platform_driver_register(&wm8400_regulator_driver); 381 return platform_driver_register(&wm8400_regulator_driver);
382} 382}
383module_init(wm8400_regulator_init); 383subsys_initcall(wm8400_regulator_init);
384 384
385static void __exit wm8400_regulator_exit(void) 385static void __exit wm8400_regulator_exit(void)
386{ 386{
diff --git a/include/linux/regulator/lp3971.h b/include/linux/regulator/lp3971.h
new file mode 100644
index 000000000000..61401649fe7d
--- /dev/null
+++ b/include/linux/regulator/lp3971.h
@@ -0,0 +1,51 @@
1/*
2 * National Semiconductors LP3971 PMIC chip client interface
3 *
4 * Copyright (C) 2009 Samsung Electronics
5 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
6 *
7 * Based on wm8400.h
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef __LINUX_REGULATOR_LP3971_H
25#define __LINUX_REGULATOR_LP3971_H
26
27#include <linux/regulator/machine.h>
28
29#define LP3971_LDO1 0
30#define LP3971_LDO2 1
31#define LP3971_LDO3 2
32#define LP3971_LDO4 3
33#define LP3971_LDO5 4
34
35#define LP3971_DCDC1 5
36#define LP3971_DCDC2 6
37#define LP3971_DCDC3 7
38
39#define LP3971_NUM_REGULATORS 8
40
41struct lp3971_regulator_subdev {
42 int id;
43 struct regulator_init_data *initdata;
44};
45
46struct lp3971_platform_data {
47 int num_regulators;
48 struct lp3971_regulator_subdev *regulators;
49};
50
51#endif
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h
new file mode 100644
index 000000000000..44563192bf16
--- /dev/null
+++ b/include/linux/regulator/max1586.h
@@ -0,0 +1,63 @@
1/*
2 * max1586.h -- Voltage 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
21#ifndef REGULATOR_MAX1586
22#define REGULATOR_MAX1586
23
24#include <linux/regulator/machine.h>
25
26#define MAX1586_V3 0
27#define MAX1586_V6 1
28
29/* precalculated values for v3_gain */
30#define MAX1586_GAIN_NO_R24 1000000 /* 700000 .. 1475000 mV */
31#define MAX1586_GAIN_R24_3k32 1051098 /* 735768 .. 1550369 mV */
32#define MAX1586_GAIN_R24_5k11 1078648 /* 755053 .. 1591005 mV */
33#define MAX1586_GAIN_R24_7k5 1115432 /* 780802 .. 1645262 mV */
34
35/**
36 * max1586_subdev_data - regulator data
37 * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
38 * @name: regulator cute name (example for V3: "vcc_core")
39 * @platform_data: regulator init data (contraints, supplies, ...)
40 */
41struct max1586_subdev_data {
42 int id;
43 char *name;
44 struct regulator_init_data *platform_data;
45};
46
47/**
48 * max1586_platform_data - platform data for max1586
49 * @num_subdevs: number of regultors used (may be 1 or 2)
50 * @subdevs: regulator used
51 * At most, there will be a regulator for V3 and one for V6 voltages.
52 * @v3_gain: gain on the V3 voltage output multiplied by 1e6.
53 * This can be calculated as ((1 + R24/R25 + R24/185.5kOhm) * 1e6)
54 * for an external resistor configuration as described in the
55 * data sheet (R25=100kOhm).
56 */
57struct max1586_platform_data {
58 int num_subdevs;
59 struct max1586_subdev_data *subdevs;
60 int v3_gain;
61};
62
63#endif
diff --git a/include/linux/regulator/userspace-consumer.h b/include/linux/regulator/userspace-consumer.h
new file mode 100644
index 000000000000..b4554ce9d4bb
--- /dev/null
+++ b/include/linux/regulator/userspace-consumer.h
@@ -0,0 +1,25 @@
1#ifndef __REGULATOR_PLATFORM_CONSUMER_H_
2#define __REGULATOR_PLATFORM_CONSUMER_H_
3
4struct regulator_consumer_supply;
5
6/**
7 * struct regulator_userspace_consumer_data - line consumer
8 * initialisation data.
9 *
10 * @name: Name for the consumer line
11 * @num_supplies: Number of supplies feeding the line
12 * @supplies: Supplies configuration.
13 * @init_on: Set if the regulators supplying the line should be
14 * enabled during initialisation
15 */
16struct regulator_userspace_consumer_data {
17 const char *name;
18
19 int num_supplies;
20 struct regulator_bulk_data *supplies;
21
22 bool init_on;
23};
24
25#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */