x86: ASUS P4S800 reboot=bios quirk
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / regulator / wm831x-dcdc.c
blob2eefc1a0cf08eedcb68235dcd2dcfe0857910151
1 /*
2 * wm831x-dcdc.c -- DC-DC buck convertor driver for the WM831x series
4 * Copyright 2009 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
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>
23 #include <linux/mfd/wm831x/core.h>
24 #include <linux/mfd/wm831x/regulator.h>
25 #include <linux/mfd/wm831x/pdata.h>
27 #define WM831X_BUCKV_MAX_SELECTOR 0x68
28 #define WM831X_BUCKP_MAX_SELECTOR 0x66
30 #define WM831X_DCDC_MODE_FAST 0
31 #define WM831X_DCDC_MODE_NORMAL 1
32 #define WM831X_DCDC_MODE_IDLE 2
33 #define WM831X_DCDC_MODE_STANDBY 3
35 #define WM831X_DCDC_MAX_NAME 6
37 /* Register offsets in control block */
38 #define WM831X_DCDC_CONTROL_1 0
39 #define WM831X_DCDC_CONTROL_2 1
40 #define WM831X_DCDC_ON_CONFIG 2
41 #define WM831X_DCDC_SLEEP_CONTROL 3
44 * Shared
47 struct wm831x_dcdc {
48 char name[WM831X_DCDC_MAX_NAME];
49 struct regulator_desc desc;
50 int base;
51 struct wm831x *wm831x;
52 struct regulator_dev *regulator;
55 static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
57 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
58 struct wm831x *wm831x = dcdc->wm831x;
59 int mask = 1 << rdev_get_id(rdev);
60 int reg;
62 reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
63 if (reg < 0)
64 return reg;
66 if (reg & mask)
67 return 1;
68 else
69 return 0;
72 static int wm831x_dcdc_enable(struct regulator_dev *rdev)
74 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
75 struct wm831x *wm831x = dcdc->wm831x;
76 int mask = 1 << rdev_get_id(rdev);
78 return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
81 static int wm831x_dcdc_disable(struct regulator_dev *rdev)
83 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
84 struct wm831x *wm831x = dcdc->wm831x;
85 int mask = 1 << rdev_get_id(rdev);
87 return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
90 static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
93 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
94 struct wm831x *wm831x = dcdc->wm831x;
95 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
96 int val;
98 val = wm831x_reg_read(wm831x, reg);
99 if (val < 0)
100 return val;
102 val = (val & WM831X_DC1_ON_MODE_MASK) >> WM831X_DC1_ON_MODE_SHIFT;
104 switch (val) {
105 case WM831X_DCDC_MODE_FAST:
106 return REGULATOR_MODE_FAST;
107 case WM831X_DCDC_MODE_NORMAL:
108 return REGULATOR_MODE_NORMAL;
109 case WM831X_DCDC_MODE_STANDBY:
110 return REGULATOR_MODE_STANDBY;
111 case WM831X_DCDC_MODE_IDLE:
112 return REGULATOR_MODE_IDLE;
113 default:
114 BUG();
118 static int wm831x_dcdc_set_mode_int(struct wm831x *wm831x, int reg,
119 unsigned int mode)
121 int val;
123 switch (mode) {
124 case REGULATOR_MODE_FAST:
125 val = WM831X_DCDC_MODE_FAST;
126 break;
127 case REGULATOR_MODE_NORMAL:
128 val = WM831X_DCDC_MODE_NORMAL;
129 break;
130 case REGULATOR_MODE_STANDBY:
131 val = WM831X_DCDC_MODE_STANDBY;
132 break;
133 case REGULATOR_MODE_IDLE:
134 val = WM831X_DCDC_MODE_IDLE;
135 break;
136 default:
137 return -EINVAL;
140 return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_MODE_MASK,
141 val << WM831X_DC1_ON_MODE_SHIFT);
144 static int wm831x_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
146 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
147 struct wm831x *wm831x = dcdc->wm831x;
148 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
150 return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
153 static int wm831x_dcdc_set_suspend_mode(struct regulator_dev *rdev,
154 unsigned int mode)
156 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
157 struct wm831x *wm831x = dcdc->wm831x;
158 u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
160 return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
163 static int wm831x_dcdc_get_status(struct regulator_dev *rdev)
165 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
166 struct wm831x *wm831x = dcdc->wm831x;
167 int ret;
169 /* First, check for errors */
170 ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
171 if (ret < 0)
172 return ret;
174 if (ret & (1 << rdev_get_id(rdev))) {
175 dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
176 rdev_get_id(rdev) + 1);
177 return REGULATOR_STATUS_ERROR;
180 /* DCDC1 and DCDC2 can additionally detect high voltage/current */
181 if (rdev_get_id(rdev) < 2) {
182 if (ret & (WM831X_DC1_OV_STS << rdev_get_id(rdev))) {
183 dev_dbg(wm831x->dev, "DCDC%d over voltage\n",
184 rdev_get_id(rdev) + 1);
185 return REGULATOR_STATUS_ERROR;
188 if (ret & (WM831X_DC1_HC_STS << rdev_get_id(rdev))) {
189 dev_dbg(wm831x->dev, "DCDC%d over current\n",
190 rdev_get_id(rdev) + 1);
191 return REGULATOR_STATUS_ERROR;
195 /* Is the regulator on? */
196 ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
197 if (ret < 0)
198 return ret;
199 if (!(ret & (1 << rdev_get_id(rdev))))
200 return REGULATOR_STATUS_OFF;
202 /* TODO: When we handle hardware control modes so we can report the
203 * current mode. */
204 return REGULATOR_STATUS_ON;
207 static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
209 struct wm831x_dcdc *dcdc = data;
211 regulator_notifier_call_chain(dcdc->regulator,
212 REGULATOR_EVENT_UNDER_VOLTAGE,
213 NULL);
215 return IRQ_HANDLED;
218 static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
220 struct wm831x_dcdc *dcdc = data;
222 regulator_notifier_call_chain(dcdc->regulator,
223 REGULATOR_EVENT_OVER_CURRENT,
224 NULL);
226 return IRQ_HANDLED;
230 * BUCKV specifics
233 static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
234 unsigned selector)
236 if (selector <= 0x8)
237 return 600000;
238 if (selector <= WM831X_BUCKV_MAX_SELECTOR)
239 return 600000 + ((selector - 0x8) * 12500);
240 return -EINVAL;
243 static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
244 int min_uV, int max_uV)
246 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
247 struct wm831x *wm831x = dcdc->wm831x;
248 u16 vsel;
250 if (min_uV < 600000)
251 vsel = 0;
252 else if (min_uV <= 1800000)
253 vsel = ((min_uV - 600000) / 12500) + 8;
254 else
255 return -EINVAL;
257 if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
258 return -EINVAL;
260 return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel);
263 static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
264 int min_uV, int max_uV)
266 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
267 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
269 return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV);
272 static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
273 int uV)
275 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
276 u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
278 return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV);
281 static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
283 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
284 struct wm831x *wm831x = dcdc->wm831x;
285 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
286 int val;
288 val = wm831x_reg_read(wm831x, reg);
289 if (val < 0)
290 return val;
292 return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
295 /* Current limit options */
296 static u16 wm831x_dcdc_ilim[] = {
297 125, 250, 375, 500, 625, 750, 875, 1000
300 static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
301 int min_uA, int max_uA)
303 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
304 struct wm831x *wm831x = dcdc->wm831x;
305 u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
306 int i;
308 for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) {
309 if (max_uA <= wm831x_dcdc_ilim[i])
310 break;
312 if (i == ARRAY_SIZE(wm831x_dcdc_ilim))
313 return -EINVAL;
315 return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i);
318 static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
320 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
321 struct wm831x *wm831x = dcdc->wm831x;
322 u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
323 int val;
325 val = wm831x_reg_read(wm831x, reg);
326 if (val < 0)
327 return val;
329 return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK];
332 static struct regulator_ops wm831x_buckv_ops = {
333 .set_voltage = wm831x_buckv_set_voltage,
334 .get_voltage = wm831x_buckv_get_voltage,
335 .list_voltage = wm831x_buckv_list_voltage,
336 .set_suspend_voltage = wm831x_buckv_set_suspend_voltage,
337 .set_current_limit = wm831x_buckv_set_current_limit,
338 .get_current_limit = wm831x_buckv_get_current_limit,
340 .is_enabled = wm831x_dcdc_is_enabled,
341 .enable = wm831x_dcdc_enable,
342 .disable = wm831x_dcdc_disable,
343 .get_status = wm831x_dcdc_get_status,
344 .get_mode = wm831x_dcdc_get_mode,
345 .set_mode = wm831x_dcdc_set_mode,
346 .set_suspend_mode = wm831x_dcdc_set_suspend_mode,
349 static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
351 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
352 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
353 int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
354 struct wm831x_dcdc *dcdc;
355 struct resource *res;
356 int ret, irq;
358 dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
360 if (pdata == NULL || pdata->dcdc[id] == NULL)
361 return -ENODEV;
363 dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
364 if (dcdc == NULL) {
365 dev_err(&pdev->dev, "Unable to allocate private data\n");
366 return -ENOMEM;
369 dcdc->wm831x = wm831x;
371 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
372 if (res == NULL) {
373 dev_err(&pdev->dev, "No I/O resource\n");
374 ret = -EINVAL;
375 goto err;
377 dcdc->base = res->start;
379 snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
380 dcdc->desc.name = dcdc->name;
381 dcdc->desc.id = id;
382 dcdc->desc.type = REGULATOR_VOLTAGE;
383 dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
384 dcdc->desc.ops = &wm831x_buckv_ops;
385 dcdc->desc.owner = THIS_MODULE;
387 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
388 pdata->dcdc[id], dcdc);
389 if (IS_ERR(dcdc->regulator)) {
390 ret = PTR_ERR(dcdc->regulator);
391 dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
392 id + 1, ret);
393 goto err;
396 irq = platform_get_irq_byname(pdev, "UV");
397 ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
398 IRQF_TRIGGER_RISING, dcdc->name,
399 dcdc);
400 if (ret != 0) {
401 dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
402 irq, ret);
403 goto err_regulator;
406 irq = platform_get_irq_byname(pdev, "HC");
407 ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq,
408 IRQF_TRIGGER_RISING, dcdc->name,
409 dcdc);
410 if (ret != 0) {
411 dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
412 irq, ret);
413 goto err_uv;
416 platform_set_drvdata(pdev, dcdc);
418 return 0;
420 err_uv:
421 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
422 err_regulator:
423 regulator_unregister(dcdc->regulator);
424 err:
425 kfree(dcdc);
426 return ret;
429 static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
431 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
432 struct wm831x *wm831x = dcdc->wm831x;
434 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
435 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
436 regulator_unregister(dcdc->regulator);
437 kfree(dcdc);
439 return 0;
442 static struct platform_driver wm831x_buckv_driver = {
443 .probe = wm831x_buckv_probe,
444 .remove = __devexit_p(wm831x_buckv_remove),
445 .driver = {
446 .name = "wm831x-buckv",
451 * BUCKP specifics
454 static int wm831x_buckp_list_voltage(struct regulator_dev *rdev,
455 unsigned selector)
457 if (selector <= WM831X_BUCKP_MAX_SELECTOR)
458 return 850000 + (selector * 25000);
459 else
460 return -EINVAL;
463 static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg,
464 int min_uV, int max_uV)
466 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
467 struct wm831x *wm831x = dcdc->wm831x;
468 u16 vsel;
470 if (min_uV <= 34000000)
471 vsel = (min_uV - 850000) / 25000;
472 else
473 return -EINVAL;
475 if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV)
476 return -EINVAL;
478 return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel);
481 static int wm831x_buckp_set_voltage(struct regulator_dev *rdev,
482 int min_uV, int max_uV)
484 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
485 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
487 return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV);
490 static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
491 int uV)
493 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
494 u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
496 return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV);
499 static int wm831x_buckp_get_voltage(struct regulator_dev *rdev)
501 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
502 struct wm831x *wm831x = dcdc->wm831x;
503 u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
504 int val;
506 val = wm831x_reg_read(wm831x, reg);
507 if (val < 0)
508 return val;
510 return wm831x_buckp_list_voltage(rdev, val & WM831X_DC3_ON_VSEL_MASK);
513 static struct regulator_ops wm831x_buckp_ops = {
514 .set_voltage = wm831x_buckp_set_voltage,
515 .get_voltage = wm831x_buckp_get_voltage,
516 .list_voltage = wm831x_buckp_list_voltage,
517 .set_suspend_voltage = wm831x_buckp_set_suspend_voltage,
519 .is_enabled = wm831x_dcdc_is_enabled,
520 .enable = wm831x_dcdc_enable,
521 .disable = wm831x_dcdc_disable,
522 .get_status = wm831x_dcdc_get_status,
523 .get_mode = wm831x_dcdc_get_mode,
524 .set_mode = wm831x_dcdc_set_mode,
525 .set_suspend_mode = wm831x_dcdc_set_suspend_mode,
528 static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
530 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
531 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
532 int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
533 struct wm831x_dcdc *dcdc;
534 struct resource *res;
535 int ret, irq;
537 dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
539 if (pdata == NULL || pdata->dcdc[id] == NULL)
540 return -ENODEV;
542 dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
543 if (dcdc == NULL) {
544 dev_err(&pdev->dev, "Unable to allocate private data\n");
545 return -ENOMEM;
548 dcdc->wm831x = wm831x;
550 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
551 if (res == NULL) {
552 dev_err(&pdev->dev, "No I/O resource\n");
553 ret = -EINVAL;
554 goto err;
556 dcdc->base = res->start;
558 snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
559 dcdc->desc.name = dcdc->name;
560 dcdc->desc.id = id;
561 dcdc->desc.type = REGULATOR_VOLTAGE;
562 dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
563 dcdc->desc.ops = &wm831x_buckp_ops;
564 dcdc->desc.owner = THIS_MODULE;
566 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
567 pdata->dcdc[id], dcdc);
568 if (IS_ERR(dcdc->regulator)) {
569 ret = PTR_ERR(dcdc->regulator);
570 dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
571 id + 1, ret);
572 goto err;
575 irq = platform_get_irq_byname(pdev, "UV");
576 ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
577 IRQF_TRIGGER_RISING, dcdc->name,
578 dcdc);
579 if (ret != 0) {
580 dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
581 irq, ret);
582 goto err_regulator;
585 platform_set_drvdata(pdev, dcdc);
587 return 0;
589 err_regulator:
590 regulator_unregister(dcdc->regulator);
591 err:
592 kfree(dcdc);
593 return ret;
596 static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
598 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
599 struct wm831x *wm831x = dcdc->wm831x;
601 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
602 regulator_unregister(dcdc->regulator);
603 kfree(dcdc);
605 return 0;
608 static struct platform_driver wm831x_buckp_driver = {
609 .probe = wm831x_buckp_probe,
610 .remove = __devexit_p(wm831x_buckp_remove),
611 .driver = {
612 .name = "wm831x-buckp",
617 * DCDC boost convertors
620 static int wm831x_boostp_get_status(struct regulator_dev *rdev)
622 struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
623 struct wm831x *wm831x = dcdc->wm831x;
624 int ret;
626 /* First, check for errors */
627 ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
628 if (ret < 0)
629 return ret;
631 if (ret & (1 << rdev_get_id(rdev))) {
632 dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
633 rdev_get_id(rdev) + 1);
634 return REGULATOR_STATUS_ERROR;
637 /* Is the regulator on? */
638 ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
639 if (ret < 0)
640 return ret;
641 if (ret & (1 << rdev_get_id(rdev)))
642 return REGULATOR_STATUS_ON;
643 else
644 return REGULATOR_STATUS_OFF;
647 static struct regulator_ops wm831x_boostp_ops = {
648 .get_status = wm831x_boostp_get_status,
650 .is_enabled = wm831x_dcdc_is_enabled,
651 .enable = wm831x_dcdc_enable,
652 .disable = wm831x_dcdc_disable,
655 static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
657 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
658 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
659 int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
660 struct wm831x_dcdc *dcdc;
661 struct resource *res;
662 int ret, irq;
664 dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
666 if (pdata == NULL || pdata->dcdc[id] == NULL)
667 return -ENODEV;
669 dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
670 if (dcdc == NULL) {
671 dev_err(&pdev->dev, "Unable to allocate private data\n");
672 return -ENOMEM;
675 dcdc->wm831x = wm831x;
677 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
678 if (res == NULL) {
679 dev_err(&pdev->dev, "No I/O resource\n");
680 ret = -EINVAL;
681 goto err;
683 dcdc->base = res->start;
685 snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
686 dcdc->desc.name = dcdc->name;
687 dcdc->desc.id = id;
688 dcdc->desc.type = REGULATOR_VOLTAGE;
689 dcdc->desc.ops = &wm831x_boostp_ops;
690 dcdc->desc.owner = THIS_MODULE;
692 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
693 pdata->dcdc[id], dcdc);
694 if (IS_ERR(dcdc->regulator)) {
695 ret = PTR_ERR(dcdc->regulator);
696 dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
697 id + 1, ret);
698 goto err;
701 irq = platform_get_irq_byname(pdev, "UV");
702 ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
703 IRQF_TRIGGER_RISING, dcdc->name,
704 dcdc);
705 if (ret != 0) {
706 dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
707 irq, ret);
708 goto err_regulator;
711 platform_set_drvdata(pdev, dcdc);
713 return 0;
715 err_regulator:
716 regulator_unregister(dcdc->regulator);
717 err:
718 kfree(dcdc);
719 return ret;
722 static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
724 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
725 struct wm831x *wm831x = dcdc->wm831x;
727 wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
728 regulator_unregister(dcdc->regulator);
729 kfree(dcdc);
731 return 0;
734 static struct platform_driver wm831x_boostp_driver = {
735 .probe = wm831x_boostp_probe,
736 .remove = __devexit_p(wm831x_boostp_remove),
737 .driver = {
738 .name = "wm831x-boostp",
743 * External Power Enable
745 * These aren't actually DCDCs but look like them in hardware so share
746 * code.
749 #define WM831X_EPE_BASE 6
751 static struct regulator_ops wm831x_epe_ops = {
752 .is_enabled = wm831x_dcdc_is_enabled,
753 .enable = wm831x_dcdc_enable,
754 .disable = wm831x_dcdc_disable,
755 .get_status = wm831x_dcdc_get_status,
758 static __devinit int wm831x_epe_probe(struct platform_device *pdev)
760 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
761 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
762 int id = pdev->id % ARRAY_SIZE(pdata->epe);
763 struct wm831x_dcdc *dcdc;
764 int ret;
766 dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
768 if (pdata == NULL || pdata->epe[id] == NULL)
769 return -ENODEV;
771 dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
772 if (dcdc == NULL) {
773 dev_err(&pdev->dev, "Unable to allocate private data\n");
774 return -ENOMEM;
777 dcdc->wm831x = wm831x;
779 /* For current parts this is correct; probably need to revisit
780 * in future.
782 snprintf(dcdc->name, sizeof(dcdc->name), "EPE%d", id + 1);
783 dcdc->desc.name = dcdc->name;
784 dcdc->desc.id = id + WM831X_EPE_BASE; /* Offset in DCDC registers */
785 dcdc->desc.ops = &wm831x_epe_ops;
786 dcdc->desc.type = REGULATOR_VOLTAGE;
787 dcdc->desc.owner = THIS_MODULE;
789 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
790 pdata->epe[id], dcdc);
791 if (IS_ERR(dcdc->regulator)) {
792 ret = PTR_ERR(dcdc->regulator);
793 dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
794 id + 1, ret);
795 goto err;
798 platform_set_drvdata(pdev, dcdc);
800 return 0;
802 err:
803 kfree(dcdc);
804 return ret;
807 static __devexit int wm831x_epe_remove(struct platform_device *pdev)
809 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
811 regulator_unregister(dcdc->regulator);
812 kfree(dcdc);
814 return 0;
817 static struct platform_driver wm831x_epe_driver = {
818 .probe = wm831x_epe_probe,
819 .remove = __devexit_p(wm831x_epe_remove),
820 .driver = {
821 .name = "wm831x-epe",
825 static int __init wm831x_dcdc_init(void)
827 int ret;
828 ret = platform_driver_register(&wm831x_buckv_driver);
829 if (ret != 0)
830 pr_err("Failed to register WM831x BUCKV driver: %d\n", ret);
832 ret = platform_driver_register(&wm831x_buckp_driver);
833 if (ret != 0)
834 pr_err("Failed to register WM831x BUCKP driver: %d\n", ret);
836 ret = platform_driver_register(&wm831x_boostp_driver);
837 if (ret != 0)
838 pr_err("Failed to register WM831x BOOST driver: %d\n", ret);
840 ret = platform_driver_register(&wm831x_epe_driver);
841 if (ret != 0)
842 pr_err("Failed to register WM831x EPE driver: %d\n", ret);
844 return 0;
846 subsys_initcall(wm831x_dcdc_init);
848 static void __exit wm831x_dcdc_exit(void)
850 platform_driver_unregister(&wm831x_epe_driver);
851 platform_driver_unregister(&wm831x_boostp_driver);
852 platform_driver_unregister(&wm831x_buckp_driver);
853 platform_driver_unregister(&wm831x_buckv_driver);
855 module_exit(wm831x_dcdc_exit);
857 /* Module information */
858 MODULE_AUTHOR("Mark Brown");
859 MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
860 MODULE_LICENSE("GPL");
861 MODULE_ALIAS("platform:wm831x-buckv");
862 MODULE_ALIAS("platform:wm831x-buckp");