]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/regulator/wm831x-ldo.c
regulator: wm831x-isink: Convert to devm_regulator_register()
[mirror_ubuntu-bionic-kernel.git] / drivers / regulator / wm831x-ldo.c
CommitLineData
d1c6b4fe
MB
1/*
2 * wm831x-ldo.c -- LDO driver for the WM831x series
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/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/driver.h>
5a0e3ad6 22#include <linux/slab.h>
d1c6b4fe
MB
23
24#include <linux/mfd/wm831x/core.h>
25#include <linux/mfd/wm831x/regulator.h>
26#include <linux/mfd/wm831x/pdata.h>
27
f1aba13f 28#define WM831X_LDO_MAX_NAME 9
d1c6b4fe
MB
29
30#define WM831X_LDO_CONTROL 0
31#define WM831X_LDO_ON_CONTROL 1
32#define WM831X_LDO_SLEEP_CONTROL 2
33
34#define WM831X_ALIVE_LDO_ON_CONTROL 0
35#define WM831X_ALIVE_LDO_SLEEP_CONTROL 1
36
37struct wm831x_ldo {
38 char name[WM831X_LDO_MAX_NAME];
f1aba13f 39 char supply_name[WM831X_LDO_MAX_NAME];
d1c6b4fe
MB
40 struct regulator_desc desc;
41 int base;
42 struct wm831x *wm831x;
43 struct regulator_dev *regulator;
44};
45
46/*
47 * Shared
48 */
49
d1c6b4fe
MB
50static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
51{
52 struct wm831x_ldo *ldo = data;
53
54 regulator_notifier_call_chain(ldo->regulator,
55 REGULATOR_EVENT_UNDER_VOLTAGE,
56 NULL);
57
58 return IRQ_HANDLED;
59}
60
61/*
62 * General purpose LDOs
63 */
64
5ff26a14
MB
65static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = {
66 { .min_uV = 900000, .max_uV = 1650000, .min_sel = 0, .max_sel = 14,
67 .uV_step = 50000 },
68 { .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31,
69 .uV_step = 100000 },
70};
d1c6b4fe
MB
71
72static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
73 int uV)
74{
75 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
0a479689
AL
76 struct wm831x *wm831x = ldo->wm831x;
77 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
d1c6b4fe 78
5ff26a14 79 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
0a479689
AL
80 if (sel < 0)
81 return sel;
82
83 return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, sel);
d1c6b4fe
MB
84}
85
d1c6b4fe
MB
86static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
87{
88 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
89 struct wm831x *wm831x = ldo->wm831x;
90 int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
91 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
9a767d43 92 int ret;
d1c6b4fe
MB
93
94 ret = wm831x_reg_read(wm831x, on_reg);
95 if (ret < 0)
9a767d43 96 return ret;
d1c6b4fe
MB
97
98 if (!(ret & WM831X_LDO1_ON_MODE))
99 return REGULATOR_MODE_NORMAL;
100
101 ret = wm831x_reg_read(wm831x, ctrl_reg);
102 if (ret < 0)
9a767d43 103 return ret;
d1c6b4fe
MB
104
105 if (ret & WM831X_LDO1_LP_MODE)
106 return REGULATOR_MODE_STANDBY;
107 else
108 return REGULATOR_MODE_IDLE;
109}
110
111static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
112 unsigned int mode)
113{
114 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
115 struct wm831x *wm831x = ldo->wm831x;
116 int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
117 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
118 int ret;
119
120
121 switch (mode) {
122 case REGULATOR_MODE_NORMAL:
123 ret = wm831x_set_bits(wm831x, on_reg,
124 WM831X_LDO1_ON_MODE, 0);
125 if (ret < 0)
126 return ret;
127 break;
128
129 case REGULATOR_MODE_IDLE:
130 ret = wm831x_set_bits(wm831x, ctrl_reg,
e260999c 131 WM831X_LDO1_LP_MODE, 0);
d1c6b4fe
MB
132 if (ret < 0)
133 return ret;
134
135 ret = wm831x_set_bits(wm831x, on_reg,
136 WM831X_LDO1_ON_MODE,
137 WM831X_LDO1_ON_MODE);
138 if (ret < 0)
139 return ret;
e260999c 140 break;
d1c6b4fe
MB
141
142 case REGULATOR_MODE_STANDBY:
143 ret = wm831x_set_bits(wm831x, ctrl_reg,
e260999c
AL
144 WM831X_LDO1_LP_MODE,
145 WM831X_LDO1_LP_MODE);
d1c6b4fe
MB
146 if (ret < 0)
147 return ret;
148
149 ret = wm831x_set_bits(wm831x, on_reg,
150 WM831X_LDO1_ON_MODE,
151 WM831X_LDO1_ON_MODE);
152 if (ret < 0)
153 return ret;
154 break;
155
156 default:
157 return -EINVAL;
158 }
159
160 return 0;
161}
162
163static int wm831x_gp_ldo_get_status(struct regulator_dev *rdev)
164{
165 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
166 struct wm831x *wm831x = ldo->wm831x;
167 int mask = 1 << rdev_get_id(rdev);
168 int ret;
169
170 /* Is the regulator on? */
171 ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
172 if (ret < 0)
173 return ret;
174 if (!(ret & mask))
175 return REGULATOR_STATUS_OFF;
176
177 /* Is it reporting under voltage? */
178 ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
363506cd
AL
179 if (ret < 0)
180 return ret;
d1c6b4fe
MB
181 if (ret & mask)
182 return REGULATOR_STATUS_ERROR;
183
184 ret = wm831x_gp_ldo_get_mode(rdev);
185 if (ret < 0)
186 return ret;
187 else
188 return regulator_mode_to_status(ret);
189}
190
191static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
192 int input_uV,
193 int output_uV, int load_uA)
194{
195 if (load_uA < 20000)
196 return REGULATOR_MODE_STANDBY;
197 if (load_uA < 50000)
198 return REGULATOR_MODE_IDLE;
199 return REGULATOR_MODE_NORMAL;
200}
201
202
203static struct regulator_ops wm831x_gp_ldo_ops = {
5ff26a14
MB
204 .list_voltage = regulator_list_voltage_linear_range,
205 .map_voltage = regulator_map_voltage_linear_range,
ac663b47 206 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0a479689 207 .set_voltage_sel = regulator_set_voltage_sel_regmap,
d1c6b4fe
MB
208 .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
209 .get_mode = wm831x_gp_ldo_get_mode,
210 .set_mode = wm831x_gp_ldo_set_mode,
211 .get_status = wm831x_gp_ldo_get_status,
212 .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
22c5fb6a
MB
213 .get_bypass = regulator_get_bypass_regmap,
214 .set_bypass = regulator_set_bypass_regmap,
d1c6b4fe 215
ca8c361b
MB
216 .is_enabled = regulator_is_enabled_regmap,
217 .enable = regulator_enable_regmap,
218 .disable = regulator_disable_regmap,
d1c6b4fe
MB
219};
220
a5023574 221static int wm831x_gp_ldo_probe(struct platform_device *pdev)
d1c6b4fe
MB
222{
223 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
dff91d0b 224 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
c172708d 225 struct regulator_config config = { };
137a6354 226 int id;
d1c6b4fe
MB
227 struct wm831x_ldo *ldo;
228 struct resource *res;
229 int ret, irq;
230
137a6354
MB
231 if (pdata && pdata->wm831x_num)
232 id = (pdata->wm831x_num * 10) + 1;
233 else
234 id = 0;
235 id = pdev->id - id;
236
d1c6b4fe
MB
237 dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
238
fded2f4f 239 ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
d1c6b4fe
MB
240 if (ldo == NULL) {
241 dev_err(&pdev->dev, "Unable to allocate private data\n");
242 return -ENOMEM;
243 }
244
245 ldo->wm831x = wm831x;
246
5656098e 247 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
d1c6b4fe 248 if (res == NULL) {
5656098e 249 dev_err(&pdev->dev, "No REG resource\n");
d1c6b4fe
MB
250 ret = -EINVAL;
251 goto err;
252 }
253 ldo->base = res->start;
254
255 snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
256 ldo->desc.name = ldo->name;
f1aba13f
MB
257
258 snprintf(ldo->supply_name, sizeof(ldo->supply_name),
259 "LDO%dVDD", id + 1);
260 ldo->desc.supply_name = ldo->supply_name;
261
d1c6b4fe
MB
262 ldo->desc.id = id;
263 ldo->desc.type = REGULATOR_VOLTAGE;
5ff26a14 264 ldo->desc.n_voltages = 32;
d1c6b4fe
MB
265 ldo->desc.ops = &wm831x_gp_ldo_ops;
266 ldo->desc.owner = THIS_MODULE;
ac663b47
MB
267 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
268 ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
ca8c361b
MB
269 ldo->desc.enable_reg = WM831X_LDO_ENABLE;
270 ldo->desc.enable_mask = 1 << id;
22c5fb6a
MB
271 ldo->desc.bypass_reg = ldo->base;
272 ldo->desc.bypass_mask = WM831X_LDO1_SWI;
5ff26a14
MB
273 ldo->desc.linear_ranges = wm831x_gp_ldo_ranges;
274 ldo->desc.n_linear_ranges = ARRAY_SIZE(wm831x_gp_ldo_ranges);
d1c6b4fe 275
c172708d 276 config.dev = pdev->dev.parent;
b7ca8788
MB
277 if (pdata)
278 config.init_data = pdata->ldo[id];
c172708d 279 config.driver_data = ldo;
ac663b47 280 config.regmap = wm831x->regmap;
c172708d
MB
281
282 ldo->regulator = regulator_register(&ldo->desc, &config);
d1c6b4fe
MB
283 if (IS_ERR(ldo->regulator)) {
284 ret = PTR_ERR(ldo->regulator);
285 dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
286 id + 1, ret);
287 goto err;
288 }
289
cd99758b 290 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
41c7a879
MB
291 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
292 wm831x_ldo_uv_irq,
293 IRQF_TRIGGER_RISING, ldo->name,
294 ldo);
d1c6b4fe
MB
295 if (ret != 0) {
296 dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
297 irq, ret);
298 goto err_regulator;
299 }
300
301 platform_set_drvdata(pdev, ldo);
302
303 return 0;
304
305err_regulator:
306 regulator_unregister(ldo->regulator);
307err:
d1c6b4fe
MB
308 return ret;
309}
310
8dc995f5 311static int wm831x_gp_ldo_remove(struct platform_device *pdev)
d1c6b4fe
MB
312{
313 struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
d1c6b4fe 314
d1c6b4fe 315 regulator_unregister(ldo->regulator);
d1c6b4fe
MB
316
317 return 0;
318}
319
320static struct platform_driver wm831x_gp_ldo_driver = {
321 .probe = wm831x_gp_ldo_probe,
5eb9f2b9 322 .remove = wm831x_gp_ldo_remove,
d1c6b4fe
MB
323 .driver = {
324 .name = "wm831x-ldo",
eb66d565 325 .owner = THIS_MODULE,
d1c6b4fe
MB
326 },
327};
328
329/*
330 * Analogue LDOs
331 */
332
5ff26a14
MB
333static const struct regulator_linear_range wm831x_aldo_ranges[] = {
334 { .min_uV = 1000000, .max_uV = 1650000, .min_sel = 0, .max_sel = 12,
335 .uV_step = 50000 },
336 { .min_uV = 1700000, .max_uV = 3500000, .min_sel = 13, .max_sel = 31,
337 .uV_step = 100000 },
338};
d1c6b4fe
MB
339
340static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
341 int uV)
342{
343 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
0a479689
AL
344 struct wm831x *wm831x = ldo->wm831x;
345 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
346
5ff26a14 347 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
0a479689
AL
348 if (sel < 0)
349 return sel;
d1c6b4fe 350
0a479689 351 return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, sel);
d1c6b4fe
MB
352}
353
d1c6b4fe
MB
354static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
355{
356 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
357 struct wm831x *wm831x = ldo->wm831x;
358 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
6f17c652 359 int ret;
d1c6b4fe
MB
360
361 ret = wm831x_reg_read(wm831x, on_reg);
362 if (ret < 0)
363 return 0;
364
365 if (ret & WM831X_LDO7_ON_MODE)
366 return REGULATOR_MODE_IDLE;
367 else
368 return REGULATOR_MODE_NORMAL;
369}
370
371static int wm831x_aldo_set_mode(struct regulator_dev *rdev,
372 unsigned int mode)
373{
374 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
375 struct wm831x *wm831x = ldo->wm831x;
d1c6b4fe
MB
376 int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
377 int ret;
378
379
380 switch (mode) {
381 case REGULATOR_MODE_NORMAL:
e841a36a 382 ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE, 0);
d1c6b4fe
MB
383 if (ret < 0)
384 return ret;
385 break;
386
387 case REGULATOR_MODE_IDLE:
e841a36a 388 ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE,
d1c6b4fe
MB
389 WM831X_LDO7_ON_MODE);
390 if (ret < 0)
391 return ret;
392 break;
393
394 default:
395 return -EINVAL;
396 }
397
398 return 0;
399}
400
401static int wm831x_aldo_get_status(struct regulator_dev *rdev)
402{
403 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
404 struct wm831x *wm831x = ldo->wm831x;
405 int mask = 1 << rdev_get_id(rdev);
406 int ret;
407
408 /* Is the regulator on? */
409 ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
410 if (ret < 0)
411 return ret;
412 if (!(ret & mask))
413 return REGULATOR_STATUS_OFF;
414
415 /* Is it reporting under voltage? */
416 ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
363506cd
AL
417 if (ret < 0)
418 return ret;
d1c6b4fe
MB
419 if (ret & mask)
420 return REGULATOR_STATUS_ERROR;
421
422 ret = wm831x_aldo_get_mode(rdev);
423 if (ret < 0)
424 return ret;
425 else
426 return regulator_mode_to_status(ret);
427}
428
429static struct regulator_ops wm831x_aldo_ops = {
5ff26a14
MB
430 .list_voltage = regulator_list_voltage_linear_range,
431 .map_voltage = regulator_map_voltage_linear_range,
ac663b47 432 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0a479689 433 .set_voltage_sel = regulator_set_voltage_sel_regmap,
d1c6b4fe
MB
434 .set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
435 .get_mode = wm831x_aldo_get_mode,
436 .set_mode = wm831x_aldo_set_mode,
437 .get_status = wm831x_aldo_get_status,
22c5fb6a
MB
438 .set_bypass = regulator_set_bypass_regmap,
439 .get_bypass = regulator_get_bypass_regmap,
d1c6b4fe 440
ca8c361b
MB
441 .is_enabled = regulator_is_enabled_regmap,
442 .enable = regulator_enable_regmap,
443 .disable = regulator_disable_regmap,
d1c6b4fe
MB
444};
445
a5023574 446static int wm831x_aldo_probe(struct platform_device *pdev)
d1c6b4fe
MB
447{
448 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
dff91d0b 449 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
c172708d 450 struct regulator_config config = { };
137a6354 451 int id;
d1c6b4fe
MB
452 struct wm831x_ldo *ldo;
453 struct resource *res;
454 int ret, irq;
455
137a6354
MB
456 if (pdata && pdata->wm831x_num)
457 id = (pdata->wm831x_num * 10) + 1;
458 else
459 id = 0;
460 id = pdev->id - id;
461
d1c6b4fe
MB
462 dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
463
fded2f4f 464 ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
d1c6b4fe
MB
465 if (ldo == NULL) {
466 dev_err(&pdev->dev, "Unable to allocate private data\n");
467 return -ENOMEM;
468 }
469
470 ldo->wm831x = wm831x;
471
5656098e 472 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
d1c6b4fe 473 if (res == NULL) {
5656098e 474 dev_err(&pdev->dev, "No REG resource\n");
d1c6b4fe
MB
475 ret = -EINVAL;
476 goto err;
477 }
478 ldo->base = res->start;
479
480 snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
481 ldo->desc.name = ldo->name;
f1aba13f
MB
482
483 snprintf(ldo->supply_name, sizeof(ldo->supply_name),
484 "LDO%dVDD", id + 1);
485 ldo->desc.supply_name = ldo->supply_name;
486
d1c6b4fe
MB
487 ldo->desc.id = id;
488 ldo->desc.type = REGULATOR_VOLTAGE;
5ff26a14
MB
489 ldo->desc.n_voltages = 32;
490 ldo->desc.linear_ranges = wm831x_aldo_ranges;
491 ldo->desc.n_linear_ranges = ARRAY_SIZE(wm831x_aldo_ranges);
d1c6b4fe
MB
492 ldo->desc.ops = &wm831x_aldo_ops;
493 ldo->desc.owner = THIS_MODULE;
ac663b47
MB
494 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
495 ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
ca8c361b
MB
496 ldo->desc.enable_reg = WM831X_LDO_ENABLE;
497 ldo->desc.enable_mask = 1 << id;
22c5fb6a
MB
498 ldo->desc.bypass_reg = ldo->base;
499 ldo->desc.bypass_mask = WM831X_LDO7_SWI;
d1c6b4fe 500
c172708d 501 config.dev = pdev->dev.parent;
b7ca8788
MB
502 if (pdata)
503 config.init_data = pdata->ldo[id];
c172708d 504 config.driver_data = ldo;
ac663b47 505 config.regmap = wm831x->regmap;
c172708d
MB
506
507 ldo->regulator = regulator_register(&ldo->desc, &config);
d1c6b4fe
MB
508 if (IS_ERR(ldo->regulator)) {
509 ret = PTR_ERR(ldo->regulator);
510 dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
511 id + 1, ret);
512 goto err;
513 }
514
cd99758b 515 irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
41c7a879
MB
516 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
517 wm831x_ldo_uv_irq,
518 IRQF_TRIGGER_RISING, ldo->name, ldo);
d1c6b4fe
MB
519 if (ret != 0) {
520 dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
521 irq, ret);
522 goto err_regulator;
523 }
524
525 platform_set_drvdata(pdev, ldo);
526
527 return 0;
528
529err_regulator:
530 regulator_unregister(ldo->regulator);
531err:
d1c6b4fe
MB
532 return ret;
533}
534
8dc995f5 535static int wm831x_aldo_remove(struct platform_device *pdev)
d1c6b4fe
MB
536{
537 struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
d1c6b4fe 538
d1c6b4fe 539 regulator_unregister(ldo->regulator);
d1c6b4fe
MB
540
541 return 0;
542}
543
544static struct platform_driver wm831x_aldo_driver = {
545 .probe = wm831x_aldo_probe,
5eb9f2b9 546 .remove = wm831x_aldo_remove,
d1c6b4fe
MB
547 .driver = {
548 .name = "wm831x-aldo",
eb66d565 549 .owner = THIS_MODULE,
d1c6b4fe
MB
550 },
551};
552
553/*
554 * Alive LDO
555 */
556
557#define WM831X_ALIVE_LDO_MAX_SELECTOR 0xf
558
d1c6b4fe
MB
559static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev,
560 int uV)
561{
562 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
0a479689
AL
563 struct wm831x *wm831x = ldo->wm831x;
564 int sel, reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL;
565
566 sel = regulator_map_voltage_linear(rdev, uV, uV);
567 if (sel < 0)
568 return sel;
d1c6b4fe 569
0a479689 570 return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, sel);
d1c6b4fe
MB
571}
572
d1c6b4fe
MB
573static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
574{
575 struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
576 struct wm831x *wm831x = ldo->wm831x;
577 int mask = 1 << rdev_get_id(rdev);
578 int ret;
579
580 /* Is the regulator on? */
581 ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
582 if (ret < 0)
583 return ret;
584 if (ret & mask)
585 return REGULATOR_STATUS_ON;
586 else
587 return REGULATOR_STATUS_OFF;
588}
589
590static struct regulator_ops wm831x_alive_ldo_ops = {
d31e954e 591 .list_voltage = regulator_list_voltage_linear,
c2543b5f 592 .map_voltage = regulator_map_voltage_linear,
ac663b47 593 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0a479689 594 .set_voltage_sel = regulator_set_voltage_sel_regmap,
d1c6b4fe
MB
595 .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage,
596 .get_status = wm831x_alive_ldo_get_status,
597
ca8c361b
MB
598 .is_enabled = regulator_is_enabled_regmap,
599 .enable = regulator_enable_regmap,
600 .disable = regulator_disable_regmap,
d1c6b4fe
MB
601};
602
a5023574 603static int wm831x_alive_ldo_probe(struct platform_device *pdev)
d1c6b4fe
MB
604{
605 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
dff91d0b 606 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev);
c172708d 607 struct regulator_config config = { };
137a6354 608 int id;
d1c6b4fe
MB
609 struct wm831x_ldo *ldo;
610 struct resource *res;
611 int ret;
612
137a6354
MB
613 if (pdata && pdata->wm831x_num)
614 id = (pdata->wm831x_num * 10) + 1;
615 else
616 id = 0;
617 id = pdev->id - id;
618
619
d1c6b4fe
MB
620 dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
621
fded2f4f 622 ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
d1c6b4fe
MB
623 if (ldo == NULL) {
624 dev_err(&pdev->dev, "Unable to allocate private data\n");
625 return -ENOMEM;
626 }
627
628 ldo->wm831x = wm831x;
629
5656098e 630 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
d1c6b4fe 631 if (res == NULL) {
5656098e 632 dev_err(&pdev->dev, "No REG resource\n");
d1c6b4fe
MB
633 ret = -EINVAL;
634 goto err;
635 }
636 ldo->base = res->start;
637
638 snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
639 ldo->desc.name = ldo->name;
f1aba13f
MB
640
641 snprintf(ldo->supply_name, sizeof(ldo->supply_name),
642 "LDO%dVDD", id + 1);
643 ldo->desc.supply_name = ldo->supply_name;
644
d1c6b4fe
MB
645 ldo->desc.id = id;
646 ldo->desc.type = REGULATOR_VOLTAGE;
647 ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1;
648 ldo->desc.ops = &wm831x_alive_ldo_ops;
649 ldo->desc.owner = THIS_MODULE;
ac663b47
MB
650 ldo->desc.vsel_reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
651 ldo->desc.vsel_mask = WM831X_LDO11_ON_VSEL_MASK;
ca8c361b
MB
652 ldo->desc.enable_reg = WM831X_LDO_ENABLE;
653 ldo->desc.enable_mask = 1 << id;
d31e954e
MB
654 ldo->desc.min_uV = 800000;
655 ldo->desc.uV_step = 50000;
eefaa3c6 656 ldo->desc.enable_time = 1000;
d1c6b4fe 657
c172708d 658 config.dev = pdev->dev.parent;
b7ca8788
MB
659 if (pdata)
660 config.init_data = pdata->ldo[id];
c172708d 661 config.driver_data = ldo;
ac663b47 662 config.regmap = wm831x->regmap;
c172708d
MB
663
664 ldo->regulator = regulator_register(&ldo->desc, &config);
d1c6b4fe
MB
665 if (IS_ERR(ldo->regulator)) {
666 ret = PTR_ERR(ldo->regulator);
667 dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
668 id + 1, ret);
669 goto err;
670 }
671
672 platform_set_drvdata(pdev, ldo);
673
674 return 0;
675
676err:
d1c6b4fe
MB
677 return ret;
678}
679
8dc995f5 680static int wm831x_alive_ldo_remove(struct platform_device *pdev)
d1c6b4fe
MB
681{
682 struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
683
684 regulator_unregister(ldo->regulator);
d1c6b4fe
MB
685
686 return 0;
687}
688
689static struct platform_driver wm831x_alive_ldo_driver = {
690 .probe = wm831x_alive_ldo_probe,
5eb9f2b9 691 .remove = wm831x_alive_ldo_remove,
d1c6b4fe
MB
692 .driver = {
693 .name = "wm831x-alive-ldo",
eb66d565 694 .owner = THIS_MODULE,
d1c6b4fe
MB
695 },
696};
697
698static int __init wm831x_ldo_init(void)
699{
700 int ret;
701
702 ret = platform_driver_register(&wm831x_gp_ldo_driver);
703 if (ret != 0)
704 pr_err("Failed to register WM831x GP LDO driver: %d\n", ret);
705
706 ret = platform_driver_register(&wm831x_aldo_driver);
707 if (ret != 0)
708 pr_err("Failed to register WM831x ALDO driver: %d\n", ret);
709
710 ret = platform_driver_register(&wm831x_alive_ldo_driver);
711 if (ret != 0)
712 pr_err("Failed to register WM831x alive LDO driver: %d\n",
713 ret);
714
715 return 0;
716}
717subsys_initcall(wm831x_ldo_init);
718
719static void __exit wm831x_ldo_exit(void)
720{
721 platform_driver_unregister(&wm831x_alive_ldo_driver);
722 platform_driver_unregister(&wm831x_aldo_driver);
723 platform_driver_unregister(&wm831x_gp_ldo_driver);
724}
725module_exit(wm831x_ldo_exit);
726
727/* Module information */
728MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
729MODULE_DESCRIPTION("WM831x LDO driver");
730MODULE_LICENSE("GPL");
731MODULE_ALIAS("platform:wm831x-ldo");
732MODULE_ALIAS("platform:wm831x-aldo");
733MODULE_ALIAS("platform:wm831x-aliveldo");