Regulators: twl-regulator - mark probe function as __devinit
[safe/jmp/linux-2.6] / drivers / regulator / wm8994-regulator.c
1 /*
2  * wm8994-regulator.c  --  Regulator driver for the WM8994
3  *
4  * Copyright 2009 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  */
13
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/bitops.h>
18 #include <linux/err.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/driver.h>
21 #include <linux/gpio.h>
22
23 #include <linux/mfd/wm8994/core.h>
24 #include <linux/mfd/wm8994/registers.h>
25 #include <linux/mfd/wm8994/pdata.h>
26
27 struct wm8994_ldo {
28         int enable;
29         int is_enabled;
30         struct regulator_dev *regulator;
31         struct wm8994 *wm8994;
32 };
33
34 #define WM8994_LDO1_MAX_SELECTOR 0x7
35 #define WM8994_LDO2_MAX_SELECTOR 0x3
36
37 static int wm8994_ldo_enable(struct regulator_dev *rdev)
38 {
39         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
40
41         /* If we have no soft control assume that the LDO is always enabled. */
42         if (!ldo->enable)
43                 return 0;
44
45         gpio_set_value(ldo->enable, 1);
46         ldo->is_enabled = 1;
47
48         return 0;
49 }
50
51 static int wm8994_ldo_disable(struct regulator_dev *rdev)
52 {
53         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
54
55         /* If we have no soft control assume that the LDO is always enabled. */
56         if (!ldo->enable)
57                 return -EINVAL;
58
59         gpio_set_value(ldo->enable, 0);
60         ldo->is_enabled = 0;
61
62         return 0;
63 }
64
65 static int wm8994_ldo_is_enabled(struct regulator_dev *rdev)
66 {
67         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
68
69         return ldo->is_enabled;
70 }
71
72 static int wm8994_ldo_enable_time(struct regulator_dev *rdev)
73 {
74         /* 3ms is fairly conservative but this shouldn't be too performance
75          * critical; can be tweaked per-system if required. */
76         return 3000;
77 }
78
79 static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev,
80                                     unsigned int selector)
81 {
82         if (selector > WM8994_LDO1_MAX_SELECTOR)
83                 return -EINVAL;
84
85         return (selector * 100000) + 2400000;
86 }
87
88 static int wm8994_ldo1_get_voltage(struct regulator_dev *rdev)
89 {
90         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
91         int val;
92
93         val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1);
94         if (val < 0)
95                 return val;
96
97         val = (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT;
98
99         return wm8994_ldo1_list_voltage(rdev, val);
100 }
101
102 static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev,
103                                    int min_uV, int max_uV)
104 {
105         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
106         int selector, v;
107
108         selector = (min_uV - 2400000) / 100000;
109         v = wm8994_ldo1_list_voltage(rdev, selector);
110         if (v < 0 || v > max_uV)
111                 return -EINVAL;
112
113         selector <<= WM8994_LDO1_VSEL_SHIFT;
114
115         return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1,
116                                WM8994_LDO1_VSEL_MASK, selector);
117 }
118
119 static struct regulator_ops wm8994_ldo1_ops = {
120         .enable = wm8994_ldo_enable,
121         .disable = wm8994_ldo_disable,
122         .is_enabled = wm8994_ldo_is_enabled,
123         .enable_time = wm8994_ldo_enable_time,
124
125         .list_voltage = wm8994_ldo1_list_voltage,
126         .get_voltage = wm8994_ldo1_get_voltage,
127         .set_voltage = wm8994_ldo1_set_voltage,
128 };
129
130 static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
131                                     unsigned int selector)
132 {
133         if (selector > WM8994_LDO2_MAX_SELECTOR)
134                 return -EINVAL;
135
136         return (selector * 100000) + 900000;
137 }
138
139 static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev)
140 {
141         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
142         int val;
143
144         val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2);
145         if (val < 0)
146                 return val;
147
148         val = (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT;
149
150         return wm8994_ldo2_list_voltage(rdev, val);
151 }
152
153 static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
154                                    int min_uV, int max_uV)
155 {
156         struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
157         int selector, v;
158
159         selector = (min_uV - 900000) / 100000;
160         v = wm8994_ldo2_list_voltage(rdev, selector);
161         if (v < 0 || v > max_uV)
162                 return -EINVAL;
163
164         selector <<= WM8994_LDO2_VSEL_SHIFT;
165
166         return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2,
167                                WM8994_LDO2_VSEL_MASK, selector);
168 }
169
170 static struct regulator_ops wm8994_ldo2_ops = {
171         .enable = wm8994_ldo_enable,
172         .disable = wm8994_ldo_disable,
173         .is_enabled = wm8994_ldo_is_enabled,
174         .enable_time = wm8994_ldo_enable_time,
175
176         .list_voltage = wm8994_ldo2_list_voltage,
177         .get_voltage = wm8994_ldo2_get_voltage,
178         .set_voltage = wm8994_ldo2_set_voltage,
179 };
180
181 static struct regulator_desc wm8994_ldo_desc[] = {
182         {
183                 .name = "LDO1",
184                 .id = 1,
185                 .type = REGULATOR_VOLTAGE,
186                 .n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
187                 .ops = &wm8994_ldo1_ops,
188                 .owner = THIS_MODULE,
189         },
190         {
191                 .name = "LDO2",
192                 .id = 2,
193                 .type = REGULATOR_VOLTAGE,
194                 .n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
195                 .ops = &wm8994_ldo2_ops,
196                 .owner = THIS_MODULE,
197         },
198 };
199
200 static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
201 {
202         struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
203         struct wm8994_pdata *pdata = wm8994->dev->platform_data;
204         int id = pdev->id % ARRAY_SIZE(pdata->ldo);
205         struct wm8994_ldo *ldo;
206         int ret;
207
208         dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
209
210         if (!pdata)
211                 return -ENODEV;
212
213         ldo = kzalloc(sizeof(struct wm8994_ldo), GFP_KERNEL);
214         if (ldo == NULL) {
215                 dev_err(&pdev->dev, "Unable to allocate private data\n");
216                 return -ENOMEM;
217         }
218
219         ldo->wm8994 = wm8994;
220
221         ldo->is_enabled = 1;
222
223         if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) {
224                 ldo->enable = pdata->ldo[id].enable;
225
226                 ret = gpio_request(ldo->enable, "WM8994 LDO enable");
227                 if (ret < 0) {
228                         dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n",
229                                 ret);
230                         goto err;
231                 }
232
233                 ret = gpio_direction_output(ldo->enable, ldo->is_enabled);
234                 if (ret < 0) {
235                         dev_err(&pdev->dev, "Failed to set GPIO up: %d\n",
236                                 ret);
237                         goto err_gpio;
238                 }
239         }
240
241         ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
242                                              pdata->ldo[id].init_data, ldo);
243         if (IS_ERR(ldo->regulator)) {
244                 ret = PTR_ERR(ldo->regulator);
245                 dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
246                         id + 1, ret);
247                 goto err_gpio;
248         }
249
250         platform_set_drvdata(pdev, ldo);
251
252         return 0;
253
254 err_gpio:
255         if (gpio_is_valid(ldo->enable))
256                 gpio_free(ldo->enable);
257 err:
258         kfree(ldo);
259         return ret;
260 }
261
262 static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
263 {
264         struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
265
266         regulator_unregister(ldo->regulator);
267         if (gpio_is_valid(ldo->enable))
268                 gpio_free(ldo->enable);
269         kfree(ldo);
270
271         return 0;
272 }
273
274 static struct platform_driver wm8994_ldo_driver = {
275         .probe = wm8994_ldo_probe,
276         .remove = __devexit_p(wm8994_ldo_remove),
277         .driver         = {
278                 .name   = "wm8994-ldo",
279         },
280 };
281
282 static int __init wm8994_ldo_init(void)
283 {
284         int ret;
285
286         ret = platform_driver_register(&wm8994_ldo_driver);
287         if (ret != 0)
288                 pr_err("Failed to register Wm8994 GP LDO driver: %d\n", ret);
289
290         return ret;
291 }
292 subsys_initcall(wm8994_ldo_init);
293
294 static void __exit wm8994_ldo_exit(void)
295 {
296         platform_driver_unregister(&wm8994_ldo_driver);
297 }
298 module_exit(wm8994_ldo_exit);
299
300 /* Module information */
301 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
302 MODULE_DESCRIPTION("WM8994 LDO driver");
303 MODULE_LICENSE("GPL");
304 MODULE_ALIAS("platform:wm8994-ldo");