/*
 * Marvell Berlin PWM driver
 *
 * Copyright (C) 2015 Marvell Technology Group Ltd.
 *
 * Author: Antoine Tenart <antoine.tenart@free-electrons.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

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

#define BERLIN_PWM_EN			0x0
#define  BERLIN_PWM_ENABLE		BIT(0)
#define BERLIN_PWM_CONTROL		0x4
/*
 * The prescaler claims to support 8 different moduli, configured using the
 * low three bits of PWM_CONTROL. (Sequentially, they are 1, 4, 8, 16, 64,
 * 256, 1024, and 4096.)  However, the moduli from 4 to 1024 appear to be
 * implemented by internally shifting TCNT left without adding additional
 * bits. So, the max TCNT that actually works for a modulus of 4 is 0x3fff;
 * for 8, 0x1fff; and so on. This means that those moduli are entirely
 * useless, as we could just do the shift ourselves. The 4096 modulus is
 * implemented with a real prescaler, so we do use that, but we treat it
 * as a flag instead of pretending the modulus is actually configurable.
 */
#define  BERLIN_PWM_PRESCALE_4096	0x7
#define  BERLIN_PWM_INVERT_POLARITY	BIT(3)
#define BERLIN_PWM_DUTY			0x8
#define BERLIN_PWM_TCNT			0xc
#define  BERLIN_PWM_MAX_TCNT		65535

#define BERLIN_PWM_NUMPWMS		4

struct berlin_pwm_channel {
	u32 enable;
	u32 ctrl;
	u32 duty;
	u32 tcnt;
};

struct berlin_pwm_chip {
	struct pwm_chip chip;
	struct clk *clk;
	void __iomem *base;
	struct berlin_pwm_channel channel[BERLIN_PWM_NUMPWMS];
};

static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct berlin_pwm_chip, chip);
}

static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *bpc,
				   unsigned int channel, unsigned long offset)
{
	return readl_relaxed(bpc->base + channel * 0x10 + offset);
}

static inline void berlin_pwm_writel(struct berlin_pwm_chip *bpc,
				     unsigned int channel, u32 value,
				     unsigned long offset)
{
	writel_relaxed(value, bpc->base + channel * 0x10 + offset);
}

static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			     u64 duty_ns, u64 period_ns)
{
	struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);
	bool prescale_4096 = false;
	u32 value, duty, period;
	u64 cycles;

	cycles = clk_get_rate(bpc->clk);
	cycles *= period_ns;
	do_div(cycles, NSEC_PER_SEC);

	if (cycles > BERLIN_PWM_MAX_TCNT) {
		prescale_4096 = true;
		cycles >>= 12; // Prescaled by 4096

		if (cycles > BERLIN_PWM_MAX_TCNT)
			return -ERANGE;
	}

	period = cycles;
	cycles *= duty_ns;
	do_div(cycles, period_ns);
	duty = cycles;

	value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_CONTROL);
	if (prescale_4096)
		value |= BERLIN_PWM_PRESCALE_4096;
	else
		value &= ~BERLIN_PWM_PRESCALE_4096;
	berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_CONTROL);

	berlin_pwm_writel(bpc, pwm->hwpwm, duty, BERLIN_PWM_DUTY);
	berlin_pwm_writel(bpc, pwm->hwpwm, period, BERLIN_PWM_TCNT);

	return 0;
}

static int berlin_pwm_set_polarity(struct pwm_chip *chip,
				   struct pwm_device *pwm,
				   enum pwm_polarity polarity)
{
	struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);
	u32 value;

	value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_CONTROL);

	if (polarity == PWM_POLARITY_NORMAL)
		value &= ~BERLIN_PWM_INVERT_POLARITY;
	else
		value |= BERLIN_PWM_INVERT_POLARITY;

	berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_CONTROL);

	return 0;
}

static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);
	u32 value;

	value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_EN);
	value |= BERLIN_PWM_ENABLE;
	berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_EN);

	return 0;
}

static void berlin_pwm_disable(struct pwm_chip *chip,
			       struct pwm_device *pwm)
{
	struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip);
	u32 value;

	value = berlin_pwm_readl(bpc, pwm->hwpwm, BERLIN_PWM_EN);
	value &= ~BERLIN_PWM_ENABLE;
	berlin_pwm_writel(bpc, pwm->hwpwm, value, BERLIN_PWM_EN);
}

static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			    const struct pwm_state *state)
{
	int err;
	bool enabled = pwm->state.enabled;

	if (state->polarity != pwm->state.polarity) {
		if (enabled) {
			berlin_pwm_disable(chip, pwm);
			enabled = false;
		}

		err = berlin_pwm_set_polarity(chip, pwm, state->polarity);
		if (err)
			return err;
	}

	if (!state->enabled) {
		if (enabled)
			berlin_pwm_disable(chip, pwm);
		return 0;
	}

	err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period);
	if (err)
		return err;

	if (!enabled)
		return berlin_pwm_enable(chip, pwm);

	return 0;
}

static const struct pwm_ops berlin_pwm_ops = {
	.apply = berlin_pwm_apply,
};

static const struct of_device_id berlin_pwm_match[] = {
	{ .compatible = "marvell,berlin-pwm" },
	{ },
};
MODULE_DEVICE_TABLE(of, berlin_pwm_match);

static int berlin_pwm_probe(struct platform_device *pdev)
{
	struct berlin_pwm_chip *bpc;
	int ret;

	bpc = devm_kzalloc(&pdev->dev, sizeof(*bpc), GFP_KERNEL);
	if (!bpc)
		return -ENOMEM;

	bpc->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(bpc->base))
		return PTR_ERR(bpc->base);

	bpc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
	if (IS_ERR(bpc->clk))
		return PTR_ERR(bpc->clk);

	bpc->chip.dev = &pdev->dev;
	bpc->chip.ops = &berlin_pwm_ops;
	bpc->chip.npwm = BERLIN_PWM_NUMPWMS;

	ret = devm_pwmchip_add(&pdev->dev, &bpc->chip);
	if (ret < 0)
		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");

	platform_set_drvdata(pdev, bpc);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int berlin_pwm_suspend(struct device *dev)
{
	struct berlin_pwm_chip *bpc = dev_get_drvdata(dev);
	unsigned int i;

	for (i = 0; i < bpc->chip.npwm; i++) {
		struct berlin_pwm_channel *channel = &bpc->channel[i];

		channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE);
		channel->ctrl = berlin_pwm_readl(bpc, i, BERLIN_PWM_CONTROL);
		channel->duty = berlin_pwm_readl(bpc, i, BERLIN_PWM_DUTY);
		channel->tcnt = berlin_pwm_readl(bpc, i, BERLIN_PWM_TCNT);
	}

	clk_disable_unprepare(bpc->clk);

	return 0;
}

static int berlin_pwm_resume(struct device *dev)
{
	struct berlin_pwm_chip *bpc = dev_get_drvdata(dev);
	unsigned int i;
	int ret;

	ret = clk_prepare_enable(bpc->clk);
	if (ret)
		return ret;

	for (i = 0; i < bpc->chip.npwm; i++) {
		struct berlin_pwm_channel *channel = &bpc->channel[i];

		berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL);
		berlin_pwm_writel(bpc, i, channel->duty, BERLIN_PWM_DUTY);
		berlin_pwm_writel(bpc, i, channel->tcnt, BERLIN_PWM_TCNT);
		berlin_pwm_writel(bpc, i, channel->enable, BERLIN_PWM_ENABLE);
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,
			 berlin_pwm_resume);

static struct platform_driver berlin_pwm_driver = {
	.probe = berlin_pwm_probe,
	.driver = {
		.name = "berlin-pwm",
		.of_match_table = berlin_pwm_match,
		.pm = &berlin_pwm_pm_ops,
	},
};
module_platform_driver(berlin_pwm_driver);

MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");
MODULE_DESCRIPTION("Marvell Berlin PWM driver");
MODULE_LICENSE("GPL v2");
