/*
 * Copyright 2017 NXP.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/slab.h>

#define TPM_GLOBAL	0x8
#define TPM_SC		0x10
#define TPM_CNT		0x14
#define TPM_MOD		0x18
#define TPM_C0SC	0x20
#define TPM_C0V		0x24

#define SC_CMOD		3
#define SC_CPWMS	BIT(5)
#define MSnB		BIT(5)
#define MSnA		BIT(4)
#define ELSnB		BIT(3)
#define ELSnA		BIT(2)

#define PERIOD_PERIOD_MAX 0x10000
#define PERIOD_DIV_MAX	8

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

static const unsigned int prediv[8] = {
	1, 2, 4, 8, 16, 32, 64, 128
};

#define to_tpm_pwm_chip(_chip)	container_of(_chip, struct tpm_pwm_chip, chip)

static int tpm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			  int duty_ns, int period_ns)
{
	struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
	int ret, div = 0;
	unsigned int period_cycles, duty_cycles;
	unsigned long rate;
	u64 c;

	rate = clk_get_rate(tpm->clk);
	/* calculate the period_cycles and duty_cycles */
	while (1) {
		c = rate / prediv[div];
		c = c * period_ns;
		do_div(c, 1000000000);
		if (c < PERIOD_PERIOD_MAX)
			break;
		div++;
		if (div >= 8)
			return -EINVAL;
	}

	/* enable the clock before writing the register */
	if (!pwm_is_enabled(pwm)) {
		ret = clk_prepare_enable(tpm->clk);
		if (ret)
			return ret;
	}

	period_cycles = c;
	c *= duty_ns;
	do_div(c, period_ns);
	duty_cycles = c;

	writel(period_cycles & 0xffff, tpm->base + TPM_MOD);
	writel(duty_cycles & 0xffff, tpm->base + TPM_C0V + pwm->hwpwm * 0x8);

	/* if pwm is not enabled, disable clk after setting */
	if (!pwm_is_enabled(pwm))
		clk_disable_unprepare(tpm->clk);

	return 0;
}

static int tpm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
	int val;

	clk_prepare_enable(tpm->clk);
	/*
	 * To enable a tpm channel, CPWMS = 0, MSnB:MSnA = 0x0,
	 * for TPM normal polarity ELSnB:ELSnA = 2b'10,
	 * inverse ELSnB:ELSnA = 2b'01
	 */
	val = readl(tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);

	val &= ~(MSnB | MSnA | ELSnB | ELSnA);
	val |= MSnB;
	val |= pwm->state.polarity ? ELSnA : ELSnB;

	writel(val, tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);

	/* start the counter */
	val = readl(tpm->base + TPM_SC);
	val |= 0x1 << SC_CMOD;
	writel(val, tpm->base + TPM_SC);

	return 0;
}

static void tpm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);

	clk_disable_unprepare(tpm->clk);
}

static int tpm_pwm_set_polarity(struct pwm_chip *chip,
				    struct pwm_device *pwm,
				    enum pwm_polarity polarity)
{
	struct tpm_pwm_chip *tpm = to_tpm_pwm_chip(chip);
	int ret, val;

	/* enable the clock before writing the register */
	if (!pwm_is_enabled(pwm)) {
		ret = clk_prepare_enable(tpm->clk);
		if (ret)
			return ret;
	}

	val = readl(tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);
	val &= ~(ELSnB | ELSnA);
	val |= pwm->state.polarity ? ELSnA : ELSnB;
	writel(val, tpm->base + TPM_C0SC + pwm->hwpwm * 0x8);

	if (!pwm_is_enabled(pwm))
		clk_disable_unprepare(tpm->clk);

	return  0;
}

static const struct pwm_ops tpm_pwm_ops = {
	.config		= tpm_pwm_config,
	.enable		= tpm_pwm_enable,
	.disable	= tpm_pwm_disable,
	.set_polarity	= tpm_pwm_set_polarity,
	.owner   = THIS_MODULE,
};

static int tpm_pwm_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct tpm_pwm_chip *tpm;
	struct resource *res;
	int ret;

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

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

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

	tpm->chip.dev = &pdev->dev;
	tpm->chip.ops = &tpm_pwm_ops;
	tpm->chip.base = -1;
	tpm->chip.can_sleep = true;
	/*
	 * init the number of pwm in the pwm chip. if no "fsl,pwm-number"
	 * found, init the npwm to 2, as tpm module has at least two pwm channel
	 */
	ret = of_property_read_u32(np, "nxp,pwm-number", &tpm->chip.npwm);
	if (ret < 0) {
		dev_info(&pdev->dev, "default two pwm channel");
		tpm->chip.npwm = 2;
	}

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

	platform_set_drvdata(pdev, tpm);

	return 0;
}

static int tpm_pwm_remove(struct platform_device *pdev)
{
	struct tpm_pwm_chip *tpm = platform_get_drvdata(pdev);

	return pwmchip_remove(&tpm->chip);
}

#ifdef CONFIG_PM_SLEEP
static int tpm_pwm_suspend(struct device *dev)
{
	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int tpm_pwm_resume(struct device *dev)
{
	pinctrl_pm_select_default_state(dev);

	return 0;
};
#endif

static SIMPLE_DEV_PM_OPS(tpm_pwm_pm, tpm_pwm_suspend, tpm_pwm_resume);

static const struct of_device_id tpm_pwm_dt_ids[] = {
	{ .compatible = "nxp,tpm-pwm", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tpm_pwm_dt_ids);

static struct platform_driver tpm_pwm_driver = {
	.driver = {
		.name = "tpm-pwm",
		.of_match_table = tpm_pwm_dt_ids,
		.pm = &tpm_pwm_pm,
	},
	.probe	= tpm_pwm_probe,
	.remove = tpm_pwm_remove,
};
module_platform_driver(tpm_pwm_driver);

MODULE_ALIAS("platform:tpm-pwm");
MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>");
MODULE_DESCRIPTION("NXP TPM PWM Driver");
MODULE_LICENSE("GPL v2");
