/*
 * linux/arch/arm/mach-pxa/pwm.c
 *
 * simple driver for PWM (Pulse Width Modulator) controller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 2008-02-13	initial version
 * 		eric miao <eric.miao@marvell.com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>

#include <asm/div64.h>
#include <asm/arch/pxa-regs.h>

/* PWM registers and bits definitions */
#define PWMCR		(0x00)
#define PWMDCR		(0x04)
#define PWMPCR		(0x08)

#define PWMCR_SD	(1 << 6)
#define PWMDCR_FD	(1 << 10)

struct pwm_device {
	struct list_head	node;
	struct platform_device *pdev;

	const char	*label;
	struct clk	*clk;
	int		clk_enabled;
	void __iomem	*mmio_base;

	unsigned int	use_count;
	unsigned int	pwm_id;
};

/*
 * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
 * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
 */
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
	unsigned long long c;
	unsigned long period_cycles, prescale, pv, dc;

	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
		return -EINVAL;

	c = clk_get_rate(pwm->clk);
	c = c * period_ns;
	do_div(c, 1000000000);
	period_cycles = c;

	if (period_cycles < 0)
		period_cycles = 1;
	prescale = (period_cycles - 1) / 1024;
	pv = period_cycles / (prescale + 1) - 1;

	if (prescale > 63)
		return -EINVAL;

	if (duty_ns == period_ns)
		dc = PWMDCR_FD;
	else
		dc = (pv + 1) * duty_ns / period_ns;

	/* NOTE: the clock to PWM has to be enabled first
	 * before writing to the registers
	 */
	clk_enable(pwm->clk);
	__raw_writel(prescale, pwm->mmio_base + PWMCR);
	__raw_writel(dc, pwm->mmio_base + PWMDCR);
	__raw_writel(pv, pwm->mmio_base + PWMPCR);
	clk_disable(pwm->clk);

	return 0;
}
EXPORT_SYMBOL(pwm_config);

int pwm_enable(struct pwm_device *pwm)
{
	int rc = 0;

	if (!pwm->clk_enabled) {
		rc = clk_enable(pwm->clk);
		if (!rc)
			pwm->clk_enabled = 1;
	}
	return rc;
}
EXPORT_SYMBOL(pwm_enable);

void pwm_disable(struct pwm_device *pwm)
{
	if (pwm->clk_enabled) {
		clk_disable(pwm->clk);
		pwm->clk_enabled = 0;
	}
}
EXPORT_SYMBOL(pwm_disable);

static DEFINE_MUTEX(pwm_lock);
static LIST_HEAD(pwm_list);

struct pwm_device *pwm_request(int pwm_id, const char *label)
{
	struct pwm_device *pwm;
	int found = 0;

	mutex_lock(&pwm_lock);

	list_for_each_entry(pwm, &pwm_list, node) {
		if (pwm->pwm_id == pwm_id) {
			found = 1;
			break;
		}
	}

	if (found) {
		if (pwm->use_count == 0) {
			pwm->use_count++;
			pwm->label = label;
		} else
			pwm = ERR_PTR(-EBUSY);
	} else
		pwm = ERR_PTR(-ENOENT);

	mutex_unlock(&pwm_lock);
	return pwm;
}
EXPORT_SYMBOL(pwm_request);

void pwm_free(struct pwm_device *pwm)
{
	mutex_lock(&pwm_lock);

	if (pwm->use_count) {
		pwm->use_count--;
		pwm->label = NULL;
	} else
		pr_warning("PWM device already freed\n");

	mutex_unlock(&pwm_lock);
}
EXPORT_SYMBOL(pwm_free);

static inline void __add_pwm(struct pwm_device *pwm)
{
	mutex_lock(&pwm_lock);
	list_add_tail(&pwm->node, &pwm_list);
	mutex_unlock(&pwm_lock);
}

static struct pwm_device *pwm_probe(struct platform_device *pdev,
		unsigned int pwm_id, struct pwm_device *parent_pwm)
{
	struct pwm_device *pwm;
	struct resource *r;
	int ret = 0;

	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
	if (pwm == NULL) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return ERR_PTR(-ENOMEM);
	}

	pwm->clk = clk_get(&pdev->dev, "PWMCLK");
	if (IS_ERR(pwm->clk)) {
		ret = PTR_ERR(pwm->clk);
		goto err_free;
	}
	pwm->clk_enabled = 0;

	pwm->use_count = 0;
	pwm->pwm_id = pwm_id;
	pwm->pdev = pdev;

	if (parent_pwm != NULL) {
		/* registers for the second PWM has offset of 0x10 */
		pwm->mmio_base = parent_pwm->mmio_base + 0x10;
		__add_pwm(pwm);
		return pwm;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto err_free_clk;
	}

	r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
	if (r == NULL) {
		dev_err(&pdev->dev, "failed to request memory resource\n");
		ret = -EBUSY;
		goto err_free_clk;
	}

	pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
	if (pwm->mmio_base == NULL) {
		dev_err(&pdev->dev, "failed to ioremap() registers\n");
		ret = -ENODEV;
		goto err_free_mem;
	}

	__add_pwm(pwm);
	platform_set_drvdata(pdev, pwm);
	return pwm;

err_free_mem:
	release_mem_region(r->start, r->end - r->start + 1);
err_free_clk:
	clk_put(pwm->clk);
err_free:
	kfree(pwm);
	return ERR_PTR(ret);
}

static int __devinit pxa25x_pwm_probe(struct platform_device *pdev)
{
	struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL);

	if (IS_ERR(pwm))
		return PTR_ERR(pwm);

	return 0;
}

static int __devinit pxa27x_pwm_probe(struct platform_device *pdev)
{
	struct pwm_device *pwm;

	pwm = pwm_probe(pdev, pdev->id, NULL);
	if (IS_ERR(pwm))
		return PTR_ERR(pwm);

	pwm = pwm_probe(pdev, pdev->id + 2, pwm);
	if (IS_ERR(pwm))
		return PTR_ERR(pwm);

	return 0;
}

static int __devexit pwm_remove(struct platform_device *pdev)
{
	struct pwm_device *pwm;
	struct resource *r;

	pwm = platform_get_drvdata(pdev);
	if (pwm == NULL)
		return -ENODEV;

	mutex_lock(&pwm_lock);
	list_del(&pwm->node);
	mutex_unlock(&pwm_lock);

	iounmap(pwm->mmio_base);

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(r->start, r->end - r->start + 1);

	clk_put(pwm->clk);
	kfree(pwm);
	return 0;
}

static struct platform_driver pxa25x_pwm_driver = {
	.driver		= {
		.name	= "pxa25x-pwm",
	},
	.probe		= pxa25x_pwm_probe,
	.remove		= __devexit_p(pwm_remove),
};

static struct platform_driver pxa27x_pwm_driver = {
	.driver		= {
		.name	= "pxa27x-pwm",
	},
	.probe		= pxa27x_pwm_probe,
	.remove		= __devexit_p(pwm_remove),
};

static int __init pwm_init(void)
{
	int ret = 0;

	ret = platform_driver_register(&pxa25x_pwm_driver);
	if (ret) {
		printk(KERN_ERR "failed to register pxa25x_pwm_driver\n");
		return ret;
	}

	ret = platform_driver_register(&pxa27x_pwm_driver);
	if (ret) {
		printk(KERN_ERR "failed to register pxa27x_pwm_driver\n");
		return ret;
	}

	return ret;
}
arch_initcall(pwm_init);

static void __exit pwm_exit(void)
{
	platform_driver_unregister(&pxa25x_pwm_driver);
	platform_driver_unregister(&pxa27x_pwm_driver);
}
module_exit(pwm_exit);

MODULE_LICENSE("GPL v2");
