/*
 * wm831x-dcdc.c  --  DC-DC buck convertor driver for the WM831x series
 *
 * Copyright 2009 Wolfson Microelectronics PLC.
 *
 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>

#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/regulator.h>
#include <linux/mfd/wm831x/pdata.h>

#define WM831X_BUCKV_MAX_SELECTOR 0x68
#define WM831X_BUCKP_MAX_SELECTOR 0x66

#define WM831X_DCDC_MODE_FAST    0
#define WM831X_DCDC_MODE_NORMAL  1
#define WM831X_DCDC_MODE_IDLE    2
#define WM831X_DCDC_MODE_STANDBY 3

#define WM831X_DCDC_MAX_NAME 6

/* Register offsets in control block */
#define WM831X_DCDC_CONTROL_1     0
#define WM831X_DCDC_CONTROL_2     1
#define WM831X_DCDC_ON_CONFIG     2
#define WM831X_DCDC_SLEEP_CONTROL 3

/*
 * Shared
 */

struct wm831x_dcdc {
	char name[WM831X_DCDC_MAX_NAME];
	struct regulator_desc desc;
	int base;
	struct wm831x *wm831x;
	struct regulator_dev *regulator;
};

static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	int mask = 1 << rdev_get_id(rdev);
	int reg;

	reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
	if (reg < 0)
		return reg;

	if (reg & mask)
		return 1;
	else
		return 0;
}

static int wm831x_dcdc_enable(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	int mask = 1 << rdev_get_id(rdev);

	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
}

static int wm831x_dcdc_disable(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	int mask = 1 << rdev_get_id(rdev);

	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
}

static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)

{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
	int val;

	val = wm831x_reg_read(wm831x, reg);
	if (val < 0)
		return val;

	val = (val & WM831X_DC1_ON_MODE_MASK) >> WM831X_DC1_ON_MODE_SHIFT;

	switch (val) {
	case WM831X_DCDC_MODE_FAST:
		return REGULATOR_MODE_FAST;
	case WM831X_DCDC_MODE_NORMAL:
		return REGULATOR_MODE_NORMAL;
	case WM831X_DCDC_MODE_STANDBY:
		return REGULATOR_MODE_STANDBY;
	case WM831X_DCDC_MODE_IDLE:
		return REGULATOR_MODE_IDLE;
	default:
		BUG();
	}
}

static int wm831x_dcdc_set_mode_int(struct wm831x *wm831x, int reg,
				    unsigned int mode)
{
	int val;

	switch (mode) {
	case REGULATOR_MODE_FAST:
		val = WM831X_DCDC_MODE_FAST;
		break;
	case REGULATOR_MODE_NORMAL:
		val = WM831X_DCDC_MODE_NORMAL;
		break;
	case REGULATOR_MODE_STANDBY:
		val = WM831X_DCDC_MODE_STANDBY;
		break;
	case REGULATOR_MODE_IDLE:
		val = WM831X_DCDC_MODE_IDLE;
		break;
	default:
		return -EINVAL;
	}

	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_MODE_MASK,
			       val << WM831X_DC1_ON_MODE_SHIFT);
}

static int wm831x_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;

	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
}

static int wm831x_dcdc_set_suspend_mode(struct regulator_dev *rdev,
					unsigned int mode)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;

	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
}

static int wm831x_dcdc_get_status(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	int ret;

	/* First, check for errors */
	ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
	if (ret < 0)
		return ret;

	if (ret & (1 << rdev_get_id(rdev))) {
		dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
			rdev_get_id(rdev) + 1);
		return REGULATOR_STATUS_ERROR;
	}

	/* DCDC1 and DCDC2 can additionally detect high voltage/current */
	if (rdev_get_id(rdev) < 2) {
		if (ret & (WM831X_DC1_OV_STS << rdev_get_id(rdev))) {
			dev_dbg(wm831x->dev, "DCDC%d over voltage\n",
				rdev_get_id(rdev) + 1);
			return REGULATOR_STATUS_ERROR;
		}

		if (ret & (WM831X_DC1_HC_STS << rdev_get_id(rdev))) {
			dev_dbg(wm831x->dev, "DCDC%d over current\n",
				rdev_get_id(rdev) + 1);
			return REGULATOR_STATUS_ERROR;
		}
	}

	/* Is the regulator on? */
	ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
	if (ret < 0)
		return ret;
	if (!(ret & (1 << rdev_get_id(rdev))))
		return REGULATOR_STATUS_OFF;

	/* TODO: When we handle hardware control modes so we can report the
	 * current mode. */
	return REGULATOR_STATUS_ON;
}

static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
{
	struct wm831x_dcdc *dcdc = data;

	regulator_notifier_call_chain(dcdc->regulator,
				      REGULATOR_EVENT_UNDER_VOLTAGE,
				      NULL);

	return IRQ_HANDLED;
}

static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
{
	struct wm831x_dcdc *dcdc = data;

	regulator_notifier_call_chain(dcdc->regulator,
				      REGULATOR_EVENT_OVER_CURRENT,
				      NULL);

	return IRQ_HANDLED;
}

/*
 * BUCKV specifics
 */

static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
				      unsigned selector)
{
	if (selector <= 0x8)
		return 600000;
	if (selector <= WM831X_BUCKV_MAX_SELECTOR)
		return 600000 + ((selector - 0x8) * 12500);
	return -EINVAL;
}

static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
					 int min_uV, int max_uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 vsel;

	if (min_uV < 600000)
		vsel = 0;
	else if (min_uV <= 1800000)
		vsel = ((min_uV - 600000) / 12500) + 8;
	else
		return -EINVAL;

	if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
		return -EINVAL;

	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel);
}

static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
				     int min_uV, int max_uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;

	return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV);
}

static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
					     int uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;

	return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV);
}

static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
	int val;

	val = wm831x_reg_read(wm831x, reg);
	if (val < 0)
		return val;

	return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
}

/* Current limit options */
static u16 wm831x_dcdc_ilim[] = {
	125, 250, 375, 500, 625, 750, 875, 1000
};

static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
					   int min_uA, int max_uA)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
	int i;

	for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) {
		if (max_uA <= wm831x_dcdc_ilim[i])
			break;
	}
	if (i == ARRAY_SIZE(wm831x_dcdc_ilim))
		return -EINVAL;

	return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i);
}

static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
	int val;

	val = wm831x_reg_read(wm831x, reg);
	if (val < 0)
		return val;

	return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK];
}

static struct regulator_ops wm831x_buckv_ops = {
	.set_voltage = wm831x_buckv_set_voltage,
	.get_voltage = wm831x_buckv_get_voltage,
	.list_voltage = wm831x_buckv_list_voltage,
	.set_suspend_voltage = wm831x_buckv_set_suspend_voltage,
	.set_current_limit = wm831x_buckv_set_current_limit,
	.get_current_limit = wm831x_buckv_get_current_limit,

	.is_enabled = wm831x_dcdc_is_enabled,
	.enable = wm831x_dcdc_enable,
	.disable = wm831x_dcdc_disable,
	.get_status = wm831x_dcdc_get_status,
	.get_mode = wm831x_dcdc_get_mode,
	.set_mode = wm831x_dcdc_set_mode,
	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
};

static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
	struct wm831x_dcdc *dcdc;
	struct resource *res;
	int ret, irq;

	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);

	if (pdata == NULL || pdata->dcdc[id] == NULL)
		return -ENODEV;

	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
	if (dcdc == NULL) {
		dev_err(&pdev->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	dcdc->wm831x = wm831x;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "No I/O resource\n");
		ret = -EINVAL;
		goto err;
	}
	dcdc->base = res->start;

	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
	dcdc->desc.name = dcdc->name;
	dcdc->desc.id = id;
	dcdc->desc.type = REGULATOR_VOLTAGE;
	dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
	dcdc->desc.ops = &wm831x_buckv_ops;
	dcdc->desc.owner = THIS_MODULE;

	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
					     pdata->dcdc[id], dcdc);
	if (IS_ERR(dcdc->regulator)) {
		ret = PTR_ERR(dcdc->regulator);
		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
			id + 1, ret);
		goto err;
	}

	irq = platform_get_irq_byname(pdev, "UV");
	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
				 IRQF_TRIGGER_RISING, dcdc->name,
				 dcdc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
			irq, ret);
		goto err_regulator;
	}

	irq = platform_get_irq_byname(pdev, "HC");
	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq,
				 IRQF_TRIGGER_RISING, dcdc->name,
				 dcdc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
			irq, ret);
		goto err_uv;
	}

	platform_set_drvdata(pdev, dcdc);

	return 0;

err_uv:
	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
err_regulator:
	regulator_unregister(dcdc->regulator);
err:
	kfree(dcdc);
	return ret;
}

static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
{
	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
	struct wm831x *wm831x = dcdc->wm831x;

	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
	regulator_unregister(dcdc->regulator);
	kfree(dcdc);

	return 0;
}

static struct platform_driver wm831x_buckv_driver = {
	.probe = wm831x_buckv_probe,
	.remove = __devexit_p(wm831x_buckv_remove),
	.driver		= {
		.name	= "wm831x-buckv",
	},
};

/*
 * BUCKP specifics
 */

static int wm831x_buckp_list_voltage(struct regulator_dev *rdev,
				      unsigned selector)
{
	if (selector <= WM831X_BUCKP_MAX_SELECTOR)
		return 850000 + (selector * 25000);
	else
		return -EINVAL;
}

static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg,
					int min_uV, int max_uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 vsel;

	if (min_uV <= 34000000)
		vsel = (min_uV - 850000) / 25000;
	else
		return -EINVAL;

	if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV)
		return -EINVAL;

	return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel);
}

static int wm831x_buckp_set_voltage(struct regulator_dev *rdev,
				    int min_uV, int max_uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;

	return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV);
}

static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
					    int uV)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;

	return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV);
}

static int wm831x_buckp_get_voltage(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
	int val;

	val = wm831x_reg_read(wm831x, reg);
	if (val < 0)
		return val;

	return wm831x_buckp_list_voltage(rdev, val & WM831X_DC3_ON_VSEL_MASK);
}

static struct regulator_ops wm831x_buckp_ops = {
	.set_voltage = wm831x_buckp_set_voltage,
	.get_voltage = wm831x_buckp_get_voltage,
	.list_voltage = wm831x_buckp_list_voltage,
	.set_suspend_voltage = wm831x_buckp_set_suspend_voltage,

	.is_enabled = wm831x_dcdc_is_enabled,
	.enable = wm831x_dcdc_enable,
	.disable = wm831x_dcdc_disable,
	.get_status = wm831x_dcdc_get_status,
	.get_mode = wm831x_dcdc_get_mode,
	.set_mode = wm831x_dcdc_set_mode,
	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
};

static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
	struct wm831x_dcdc *dcdc;
	struct resource *res;
	int ret, irq;

	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);

	if (pdata == NULL || pdata->dcdc[id] == NULL)
		return -ENODEV;

	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
	if (dcdc == NULL) {
		dev_err(&pdev->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	dcdc->wm831x = wm831x;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "No I/O resource\n");
		ret = -EINVAL;
		goto err;
	}
	dcdc->base = res->start;

	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
	dcdc->desc.name = dcdc->name;
	dcdc->desc.id = id;
	dcdc->desc.type = REGULATOR_VOLTAGE;
	dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
	dcdc->desc.ops = &wm831x_buckp_ops;
	dcdc->desc.owner = THIS_MODULE;

	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
					     pdata->dcdc[id], dcdc);
	if (IS_ERR(dcdc->regulator)) {
		ret = PTR_ERR(dcdc->regulator);
		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
			id + 1, ret);
		goto err;
	}

	irq = platform_get_irq_byname(pdev, "UV");
	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
				 IRQF_TRIGGER_RISING, dcdc->name,
				 dcdc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
			irq, ret);
		goto err_regulator;
	}

	platform_set_drvdata(pdev, dcdc);

	return 0;

err_regulator:
	regulator_unregister(dcdc->regulator);
err:
	kfree(dcdc);
	return ret;
}

static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
{
	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
	struct wm831x *wm831x = dcdc->wm831x;

	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
	regulator_unregister(dcdc->regulator);
	kfree(dcdc);

	return 0;
}

static struct platform_driver wm831x_buckp_driver = {
	.probe = wm831x_buckp_probe,
	.remove = __devexit_p(wm831x_buckp_remove),
	.driver		= {
		.name	= "wm831x-buckp",
	},
};

/*
 * DCDC boost convertors
 */

static int wm831x_boostp_get_status(struct regulator_dev *rdev)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
	struct wm831x *wm831x = dcdc->wm831x;
	int ret;

	/* First, check for errors */
	ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
	if (ret < 0)
		return ret;

	if (ret & (1 << rdev_get_id(rdev))) {
		dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
			rdev_get_id(rdev) + 1);
		return REGULATOR_STATUS_ERROR;
	}

	/* Is the regulator on? */
	ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
	if (ret < 0)
		return ret;
	if (ret & (1 << rdev_get_id(rdev)))
		return REGULATOR_STATUS_ON;
	else
		return REGULATOR_STATUS_OFF;
}

static struct regulator_ops wm831x_boostp_ops = {
	.get_status = wm831x_boostp_get_status,

	.is_enabled = wm831x_dcdc_is_enabled,
	.enable = wm831x_dcdc_enable,
	.disable = wm831x_dcdc_disable,
};

static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
	struct wm831x_dcdc *dcdc;
	struct resource *res;
	int ret, irq;

	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);

	if (pdata == NULL || pdata->dcdc[id] == NULL)
		return -ENODEV;

	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
	if (dcdc == NULL) {
		dev_err(&pdev->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	dcdc->wm831x = wm831x;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "No I/O resource\n");
		ret = -EINVAL;
		goto err;
	}
	dcdc->base = res->start;

	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
	dcdc->desc.name = dcdc->name;
	dcdc->desc.id = id;
	dcdc->desc.type = REGULATOR_VOLTAGE;
	dcdc->desc.ops = &wm831x_boostp_ops;
	dcdc->desc.owner = THIS_MODULE;

	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
					     pdata->dcdc[id], dcdc);
	if (IS_ERR(dcdc->regulator)) {
		ret = PTR_ERR(dcdc->regulator);
		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
			id + 1, ret);
		goto err;
	}

	irq = platform_get_irq_byname(pdev, "UV");
	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
				 IRQF_TRIGGER_RISING, dcdc->name,
				 dcdc);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
			irq, ret);
		goto err_regulator;
	}

	platform_set_drvdata(pdev, dcdc);

	return 0;

err_regulator:
	regulator_unregister(dcdc->regulator);
err:
	kfree(dcdc);
	return ret;
}

static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
{
	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
	struct wm831x *wm831x = dcdc->wm831x;

	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
	regulator_unregister(dcdc->regulator);
	kfree(dcdc);

	return 0;
}

static struct platform_driver wm831x_boostp_driver = {
	.probe = wm831x_boostp_probe,
	.remove = __devexit_p(wm831x_boostp_remove),
	.driver		= {
		.name	= "wm831x-boostp",
	},
};

/*
 * External Power Enable
 *
 * These aren't actually DCDCs but look like them in hardware so share
 * code.
 */

#define WM831X_EPE_BASE 6

static struct regulator_ops wm831x_epe_ops = {
	.is_enabled = wm831x_dcdc_is_enabled,
	.enable = wm831x_dcdc_enable,
	.disable = wm831x_dcdc_disable,
	.get_status = wm831x_dcdc_get_status,
};

static __devinit int wm831x_epe_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->epe);
	struct wm831x_dcdc *dcdc;
	int ret;

	dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);

	if (pdata == NULL || pdata->epe[id] == NULL)
		return -ENODEV;

	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
	if (dcdc == NULL) {
		dev_err(&pdev->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	dcdc->wm831x = wm831x;

	/* For current parts this is correct; probably need to revisit
	 * in future.
	 */
	snprintf(dcdc->name, sizeof(dcdc->name), "EPE%d", id + 1);
	dcdc->desc.name = dcdc->name;
	dcdc->desc.id = id + WM831X_EPE_BASE; /* Offset in DCDC registers */
	dcdc->desc.ops = &wm831x_epe_ops;
	dcdc->desc.type = REGULATOR_VOLTAGE;
	dcdc->desc.owner = THIS_MODULE;

	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
					     pdata->epe[id], dcdc);
	if (IS_ERR(dcdc->regulator)) {
		ret = PTR_ERR(dcdc->regulator);
		dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
			id + 1, ret);
		goto err;
	}

	platform_set_drvdata(pdev, dcdc);

	return 0;

err:
	kfree(dcdc);
	return ret;
}

static __devexit int wm831x_epe_remove(struct platform_device *pdev)
{
	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);

	regulator_unregister(dcdc->regulator);
	kfree(dcdc);

	return 0;
}

static struct platform_driver wm831x_epe_driver = {
	.probe = wm831x_epe_probe,
	.remove = __devexit_p(wm831x_epe_remove),
	.driver		= {
		.name	= "wm831x-epe",
	},
};

static int __init wm831x_dcdc_init(void)
{
	int ret;
	ret = platform_driver_register(&wm831x_buckv_driver);
	if (ret != 0)
		pr_err("Failed to register WM831x BUCKV driver: %d\n", ret);

	ret = platform_driver_register(&wm831x_buckp_driver);
	if (ret != 0)
		pr_err("Failed to register WM831x BUCKP driver: %d\n", ret);

	ret = platform_driver_register(&wm831x_boostp_driver);
	if (ret != 0)
		pr_err("Failed to register WM831x BOOST driver: %d\n", ret);

	ret = platform_driver_register(&wm831x_epe_driver);
	if (ret != 0)
		pr_err("Failed to register WM831x EPE driver: %d\n", ret);

	return 0;
}
subsys_initcall(wm831x_dcdc_init);

static void __exit wm831x_dcdc_exit(void)
{
	platform_driver_unregister(&wm831x_epe_driver);
	platform_driver_unregister(&wm831x_boostp_driver);
	platform_driver_unregister(&wm831x_buckp_driver);
	platform_driver_unregister(&wm831x_buckv_driver);
}
module_exit(wm831x_dcdc_exit);

/* Module information */
MODULE_AUTHOR("Mark Brown");
MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm831x-buckv");
MODULE_ALIAS("platform:wm831x-buckp");
