/*
 * linux/arch/unicore32/kernel/pwm.c
 *
 * Code specific to PKUnity SoC and UniCore ISA
 *
 *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
 *	Copyright (C) 2001-2010 Guan Xuetao
 *
 * 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.
 */

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

#include <asm/div64.h>
#include <mach/hardware.h>

struct puv3_pwm_chip {
	struct pwm_chip chip;
	void __iomem *base;
	struct clk *clk;
};

static inline struct puv3_pwm_chip *to_puv3(struct pwm_chip *chip)
{
	return container_of(chip, struct puv3_pwm_chip, chip);
}

/*
 * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
 * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
 */
static int puv3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			   int duty_ns, int period_ns)
{
	unsigned long period_cycles, prescale, pv, dc;
	struct puv3_pwm_chip *puv3 = to_puv3(chip);
	unsigned long long c;

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

	if (period_cycles < 1)
		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 = OST_PWMDCCR_FDCYCLE;
	else
		dc = (pv + 1) * duty_ns / period_ns;

	/*
	 * NOTE: the clock to PWM has to be enabled first
	 * before writing to the registers
	 */
	clk_prepare_enable(puv3->clk);

	writel(prescale, puv3->base + OST_PWM_PWCR);
	writel(pv - dc, puv3->base + OST_PWM_DCCR);
	writel(pv, puv3->base + OST_PWM_PCR);

	clk_disable_unprepare(puv3->clk);

	return 0;
}

static int puv3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct puv3_pwm_chip *puv3 = to_puv3(chip);

	return clk_prepare_enable(puv3->clk);
}

static void puv3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct puv3_pwm_chip *puv3 = to_puv3(chip);

	clk_disable_unprepare(puv3->clk);
}

static const struct pwm_ops puv3_pwm_ops = {
	.config = puv3_pwm_config,
	.enable = puv3_pwm_enable,
	.disable = puv3_pwm_disable,
	.owner = THIS_MODULE,
};

static int pwm_probe(struct platform_device *pdev)
{
	struct puv3_pwm_chip *puv3;
	struct resource *r;
	int ret;

	puv3 = devm_kzalloc(&pdev->dev, sizeof(*puv3), GFP_KERNEL);
	if (puv3 == NULL) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	puv3->clk = devm_clk_get(&pdev->dev, "OST_CLK");
	if (IS_ERR(puv3->clk))
		return PTR_ERR(puv3->clk);

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	puv3->base = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(puv3->base))
		return PTR_ERR(puv3->base);

	puv3->chip.dev = &pdev->dev;
	puv3->chip.ops = &puv3_pwm_ops;
	puv3->chip.base = -1;
	puv3->chip.npwm = 1;

	ret = pwmchip_add(&puv3->chip);
	if (ret < 0) {
		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, puv3);
	return 0;
}

static int pwm_remove(struct platform_device *pdev)
{
	struct puv3_pwm_chip *puv3 = platform_get_drvdata(pdev);

	return pwmchip_remove(&puv3->chip);
}

static struct platform_driver puv3_pwm_driver = {
	.driver = {
		.name = "PKUnity-v3-PWM",
	},
	.probe = pwm_probe,
	.remove = pwm_remove,
};
module_platform_driver(puv3_pwm_driver);

MODULE_LICENSE("GPL v2");
