// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PWM framework driver for Cirrus Logic EP93xx
 *
 * Copyright (c) 2009        Matthieu Crapet <mcrapet@gmail.com>
 * Copyright (c) 2009, 2013  H Hartley Sweeten <hsweeten@visionengravers.com>
 *
 * EP9301/02 have only one channel:
 *   platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14)
 *
 * EP9307 has only one channel:
 *   platform device ep93xx-pwm.0 - PWMOUT
 *
 * EP9312/15 have two channels:
 *   platform device ep93xx-pwm.0 - PWMOUT
 *   platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14)
 */

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

#include <asm/div64.h>

#include <linux/soc/cirrus/ep93xx.h>	/* for ep93xx_pwm_{acquire,release}_gpio() */

#define EP93XX_PWMx_TERM_COUNT	0x00
#define EP93XX_PWMx_DUTY_CYCLE	0x04
#define EP93XX_PWMx_ENABLE	0x08
#define EP93XX_PWMx_INVERT	0x0c

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

static inline struct ep93xx_pwm *to_ep93xx_pwm(struct pwm_chip *chip)
{
	return container_of(chip, struct ep93xx_pwm, chip);
}

static int ep93xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct platform_device *pdev = to_platform_device(chip->dev);

	return ep93xx_pwm_acquire_gpio(pdev);
}

static void ep93xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct platform_device *pdev = to_platform_device(chip->dev);

	ep93xx_pwm_release_gpio(pdev);
}

static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			    const struct pwm_state *state)
{
	int ret;
	struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
	bool enabled = state->enabled;
	void __iomem *base = ep93xx_pwm->base;
	unsigned long long c;
	unsigned long period_cycles;
	unsigned long duty_cycles;
	unsigned long term;

	if (state->polarity != pwm->state.polarity) {
		if (enabled) {
			writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
			clk_disable_unprepare(ep93xx_pwm->clk);
			enabled = false;
		}

		/*
		 * The clock needs to be enabled to access the PWM registers.
		 * Polarity can only be changed when the PWM is disabled.
		 */
		ret = clk_prepare_enable(ep93xx_pwm->clk);
		if (ret)
			return ret;

		if (state->polarity == PWM_POLARITY_INVERSED)
			writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_INVERT);
		else
			writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_INVERT);

		clk_disable_unprepare(ep93xx_pwm->clk);
	}

	if (!state->enabled) {
		if (enabled) {
			writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
			clk_disable_unprepare(ep93xx_pwm->clk);
		}

		return 0;
	}

	/*
	 * The clock needs to be enabled to access the PWM registers.
	 * Configuration can be changed at any time.
	 */
	if (!pwm_is_enabled(pwm)) {
		ret = clk_prepare_enable(ep93xx_pwm->clk);
		if (ret)
			return ret;
	}

	c = clk_get_rate(ep93xx_pwm->clk);
	c *= state->period;
	do_div(c, 1000000000);
	period_cycles = c;

	c = period_cycles;
	c *= state->duty_cycle;
	do_div(c, state->period);
	duty_cycles = c;

	if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
		term = readw(base + EP93XX_PWMx_TERM_COUNT);

		/* Order is important if PWM is running */
		if (period_cycles > term) {
			writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
			writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
		} else {
			writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
			writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
		}
		ret = 0;
	} else {
		ret = -EINVAL;
	}

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

	if (ret)
		return ret;

	if (!enabled) {
		ret = clk_prepare_enable(ep93xx_pwm->clk);
		if (ret)
			return ret;

		writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
	}

	return 0;
}

static const struct pwm_ops ep93xx_pwm_ops = {
	.request = ep93xx_pwm_request,
	.free = ep93xx_pwm_free,
	.apply = ep93xx_pwm_apply,
};

static int ep93xx_pwm_probe(struct platform_device *pdev)
{
	struct ep93xx_pwm *ep93xx_pwm;
	int ret;

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

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

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

	ep93xx_pwm->chip.dev = &pdev->dev;
	ep93xx_pwm->chip.ops = &ep93xx_pwm_ops;
	ep93xx_pwm->chip.npwm = 1;

	ret = devm_pwmchip_add(&pdev->dev, &ep93xx_pwm->chip);
	if (ret < 0)
		return ret;

	return 0;
}

static struct platform_driver ep93xx_pwm_driver = {
	.driver = {
		.name = "ep93xx-pwm",
	},
	.probe = ep93xx_pwm_probe,
};
module_platform_driver(ep93xx_pwm_driver);

MODULE_DESCRIPTION("Cirrus Logic EP93xx PWM driver");
MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>");
MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
MODULE_ALIAS("platform:ep93xx-pwm");
MODULE_LICENSE("GPL");
