xref: /linux/drivers/regulator/wm831x-dcdc.c (revision e4ee831f949a7c7746a56bcf1e7ca057d6f69e2a)
1 /*
2  * wm831x-dcdc.c  --  DC-DC buck convertor 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>
22 
23 #include <linux/mfd/wm831x/core.h>
24 #include <linux/mfd/wm831x/regulator.h>
25 #include <linux/mfd/wm831x/pdata.h>
26 
27 #define WM831X_BUCKV_MAX_SELECTOR 0x68
28 #define WM831X_BUCKP_MAX_SELECTOR 0x66
29 
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
34 
35 #define WM831X_DCDC_MAX_NAME 6
36 
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
42 
43 /*
44  * Shared
45  */
46 
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;
53 };
54 
55 static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
56 {
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;
61 
62 	reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
63 	if (reg < 0)
64 		return reg;
65 
66 	if (reg & mask)
67 		return 1;
68 	else
69 		return 0;
70 }
71 
72 static int wm831x_dcdc_enable(struct regulator_dev *rdev)
73 {
74 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
75 	struct wm831x *wm831x = dcdc->wm831x;
76 	int mask = 1 << rdev_get_id(rdev);
77 
78 	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
79 }
80 
81 static int wm831x_dcdc_disable(struct regulator_dev *rdev)
82 {
83 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
84 	struct wm831x *wm831x = dcdc->wm831x;
85 	int mask = 1 << rdev_get_id(rdev);
86 
87 	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
88 }
89 
90 static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
91 
92 {
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;
97 
98 	val = wm831x_reg_read(wm831x, reg);
99 	if (val < 0)
100 		return val;
101 
102 	val = (val & WM831X_DC1_ON_MODE_MASK) >> WM831X_DC1_ON_MODE_SHIFT;
103 
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();
115 	}
116 }
117 
118 static int wm831x_dcdc_set_mode_int(struct wm831x *wm831x, int reg,
119 				    unsigned int mode)
120 {
121 	int val;
122 
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;
138 	}
139 
140 	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_MODE_MASK,
141 			       val << WM831X_DC1_ON_MODE_SHIFT);
142 }
143 
144 static int wm831x_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
145 {
146 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
147 	struct wm831x *wm831x = dcdc->wm831x;
148 	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
149 
150 	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
151 }
152 
153 static int wm831x_dcdc_set_suspend_mode(struct regulator_dev *rdev,
154 					unsigned int mode)
155 {
156 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
157 	struct wm831x *wm831x = dcdc->wm831x;
158 	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
159 
160 	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
161 }
162 
163 static int wm831x_dcdc_get_status(struct regulator_dev *rdev)
164 {
165 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
166 	struct wm831x *wm831x = dcdc->wm831x;
167 	int ret;
168 
169 	/* First, check for errors */
170 	ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
171 	if (ret < 0)
172 		return ret;
173 
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;
178 	}
179 
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;
186 		}
187 
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;
192 		}
193 	}
194 
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;
201 
202 	/* TODO: When we handle hardware control modes so we can report the
203 	 * current mode. */
204 	return REGULATOR_STATUS_ON;
205 }
206 
207 static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
208 {
209 	struct wm831x_dcdc *dcdc = data;
210 
211 	regulator_notifier_call_chain(dcdc->regulator,
212 				      REGULATOR_EVENT_UNDER_VOLTAGE,
213 				      NULL);
214 
215 	return IRQ_HANDLED;
216 }
217 
218 static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
219 {
220 	struct wm831x_dcdc *dcdc = data;
221 
222 	regulator_notifier_call_chain(dcdc->regulator,
223 				      REGULATOR_EVENT_OVER_CURRENT,
224 				      NULL);
225 
226 	return IRQ_HANDLED;
227 }
228 
229 /*
230  * BUCKV specifics
231  */
232 
233 static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
234 				      unsigned selector)
235 {
236 	if (selector <= 0x8)
237 		return 600000;
238 	if (selector <= WM831X_BUCKV_MAX_SELECTOR)
239 		return 600000 + ((selector - 0x8) * 12500);
240 	return -EINVAL;
241 }
242 
243 static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
244 					 int min_uV, int max_uV)
245 {
246 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
247 	struct wm831x *wm831x = dcdc->wm831x;
248 	u16 vsel;
249 
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;
256 
257 	if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
258 		return -EINVAL;
259 
260 	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel);
261 }
262 
263 static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
264 				     int min_uV, int max_uV)
265 {
266 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
267 	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
268 
269 	return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV);
270 }
271 
272 static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
273 					     int uV)
274 {
275 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
276 	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
277 
278 	return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV);
279 }
280 
281 static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
282 {
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;
287 
288 	val = wm831x_reg_read(wm831x, reg);
289 	if (val < 0)
290 		return val;
291 
292 	return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
293 }
294 
295 /* Current limit options */
296 static u16 wm831x_dcdc_ilim[] = {
297 	125, 250, 375, 500, 625, 750, 875, 1000
298 };
299 
300 static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
301 					   int min_uA, int max_uA)
302 {
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;
307 
308 	for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) {
309 		if (max_uA <= wm831x_dcdc_ilim[i])
310 			break;
311 	}
312 	if (i == ARRAY_SIZE(wm831x_dcdc_ilim))
313 		return -EINVAL;
314 
315 	return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i);
316 }
317 
318 static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
319 {
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;
324 
325 	val = wm831x_reg_read(wm831x, reg);
326 	if (val < 0)
327 		return val;
328 
329 	return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK];
330 }
331 
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,
339 
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,
347 };
348 
349 static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
350 {
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;
357 
358 	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
359 
360 	if (pdata == NULL || pdata->dcdc[id] == NULL)
361 		return -ENODEV;
362 
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;
367 	}
368 
369 	dcdc->wm831x = wm831x;
370 
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;
376 	}
377 	dcdc->base = res->start;
378 
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;
386 
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;
394 	}
395 
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;
404 	}
405 
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;
414 	}
415 
416 	platform_set_drvdata(pdev, dcdc);
417 
418 	return 0;
419 
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;
427 }
428 
429 static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
430 {
431 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
432 	struct wm831x *wm831x = dcdc->wm831x;
433 
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);
438 
439 	return 0;
440 }
441 
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",
447 	},
448 };
449 
450 /*
451  * BUCKP specifics
452  */
453 
454 static int wm831x_buckp_list_voltage(struct regulator_dev *rdev,
455 				      unsigned selector)
456 {
457 	if (selector <= WM831X_BUCKP_MAX_SELECTOR)
458 		return 850000 + (selector * 25000);
459 	else
460 		return -EINVAL;
461 }
462 
463 static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg,
464 					int min_uV, int max_uV)
465 {
466 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
467 	struct wm831x *wm831x = dcdc->wm831x;
468 	u16 vsel;
469 
470 	if (min_uV <= 34000000)
471 		vsel = (min_uV - 850000) / 25000;
472 	else
473 		return -EINVAL;
474 
475 	if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV)
476 		return -EINVAL;
477 
478 	return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel);
479 }
480 
481 static int wm831x_buckp_set_voltage(struct regulator_dev *rdev,
482 				    int min_uV, int max_uV)
483 {
484 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
485 	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
486 
487 	return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV);
488 }
489 
490 static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
491 					    int uV)
492 {
493 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
494 	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
495 
496 	return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV);
497 }
498 
499 static int wm831x_buckp_get_voltage(struct regulator_dev *rdev)
500 {
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;
505 
506 	val = wm831x_reg_read(wm831x, reg);
507 	if (val < 0)
508 		return val;
509 
510 	return wm831x_buckp_list_voltage(rdev, val & WM831X_DC3_ON_VSEL_MASK);
511 }
512 
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,
518 
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,
526 };
527 
528 static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
529 {
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;
536 
537 	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
538 
539 	if (pdata == NULL || pdata->dcdc[id] == NULL)
540 		return -ENODEV;
541 
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;
546 	}
547 
548 	dcdc->wm831x = wm831x;
549 
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;
555 	}
556 	dcdc->base = res->start;
557 
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;
565 
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;
573 	}
574 
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;
583 	}
584 
585 	platform_set_drvdata(pdev, dcdc);
586 
587 	return 0;
588 
589 err_regulator:
590 	regulator_unregister(dcdc->regulator);
591 err:
592 	kfree(dcdc);
593 	return ret;
594 }
595 
596 static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
597 {
598 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
599 	struct wm831x *wm831x = dcdc->wm831x;
600 
601 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
602 	regulator_unregister(dcdc->regulator);
603 	kfree(dcdc);
604 
605 	return 0;
606 }
607 
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",
613 	},
614 };
615 
616 static int __init wm831x_dcdc_init(void)
617 {
618 	int ret;
619 	ret = platform_driver_register(&wm831x_buckv_driver);
620 	if (ret != 0)
621 		pr_err("Failed to register WM831x BUCKV driver: %d\n", ret);
622 
623 	ret = platform_driver_register(&wm831x_buckp_driver);
624 	if (ret != 0)
625 		pr_err("Failed to register WM831x BUCKP driver: %d\n", ret);
626 
627 	return 0;
628 }
629 subsys_initcall(wm831x_dcdc_init);
630 
631 static void __exit wm831x_dcdc_exit(void)
632 {
633 	platform_driver_unregister(&wm831x_buckp_driver);
634 	platform_driver_unregister(&wm831x_buckv_driver);
635 }
636 module_exit(wm831x_dcdc_exit);
637 
638 /* Module information */
639 MODULE_AUTHOR("Mark Brown");
640 MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
641 MODULE_LICENSE("GPL");
642 MODULE_ALIAS("platform:wm831x-buckv");
643 MODULE_ALIAS("platform:wm831x-buckp");
644