/*
 * Blackfin Pulse Width Modulation (PWM) core
 *
 * Copyright (c) 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/slab.h>

#include <asm/gptimers.h>
#include <asm/portmux.h>

struct bfin_pwm_chip {
	struct pwm_chip chip;
};

struct bfin_pwm {
	unsigned short pin;
};

static const unsigned short pwm_to_gptimer_per[] = {
	P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR4, P_TMR5,
	P_TMR6, P_TMR7, P_TMR8, P_TMR9, P_TMR10, P_TMR11,
};

static int bfin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct bfin_pwm *priv;
	int ret;

	if (pwm->hwpwm >= ARRAY_SIZE(pwm_to_gptimer_per))
		return -EINVAL;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->pin = pwm_to_gptimer_per[pwm->hwpwm];

	ret = peripheral_request(priv->pin, NULL);
	if (ret) {
		kfree(priv);
		return ret;
	}

	pwm_set_chip_data(pwm, priv);

	return 0;
}

static void bfin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct bfin_pwm *priv = pwm_get_chip_data(pwm);

	if (priv) {
		peripheral_free(priv->pin);
		kfree(priv);
	}
}

static int bfin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
		int duty_ns, int period_ns)
{
	struct bfin_pwm *priv = pwm_get_chip_data(pwm);
	unsigned long period, duty;
	unsigned long long val;

	val = (unsigned long long)get_sclk() * period_ns;
	do_div(val, NSEC_PER_SEC);
	period = val;

	val = (unsigned long long)period * duty_ns;
	do_div(val, period_ns);
	duty = period - val;

	if (duty >= period)
		duty = period - 1;

	set_gptimer_config(priv->pin, TIMER_MODE_PWM | TIMER_PERIOD_CNT);
	set_gptimer_pwidth(priv->pin, duty);
	set_gptimer_period(priv->pin, period);

	return 0;
}

static int bfin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct bfin_pwm *priv = pwm_get_chip_data(pwm);

	enable_gptimer(priv->pin);

	return 0;
}

static void bfin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct bfin_pwm *priv = pwm_get_chip_data(pwm);

	disable_gptimer(priv->pin);
}

static struct pwm_ops bfin_pwm_ops = {
	.request = bfin_pwm_request,
	.free = bfin_pwm_free,
	.config = bfin_pwm_config,
	.enable = bfin_pwm_enable,
	.disable = bfin_pwm_disable,
	.owner = THIS_MODULE,
};

static int bfin_pwm_probe(struct platform_device *pdev)
{
	struct bfin_pwm_chip *pwm;
	int ret;

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

	platform_set_drvdata(pdev, pwm);

	pwm->chip.dev = &pdev->dev;
	pwm->chip.ops = &bfin_pwm_ops;
	pwm->chip.base = -1;
	pwm->chip.npwm = 12;

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

	return 0;
}

static int bfin_pwm_remove(struct platform_device *pdev)
{
	struct bfin_pwm_chip *pwm = platform_get_drvdata(pdev);

	return pwmchip_remove(&pwm->chip);
}

static struct platform_driver bfin_pwm_driver = {
	.driver = {
		.name = "bfin-pwm",
	},
	.probe = bfin_pwm_probe,
	.remove = bfin_pwm_remove,
};

module_platform_driver(bfin_pwm_driver);

MODULE_LICENSE("GPL");
