// SPDX-License-Identifier: GPL-2.0-only
/*
 * Toshiba Visconti pulse-width-modulation controller driver
 *
 * Copyright (c) 2020 - 2021 TOSHIBA CORPORATION
 * Copyright (c) 2020 - 2021 Toshiba Electronic Devices & Storage Corporation
 *
 * Authors: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
 *
 * Limitations:
 * - The fixed input clock is running at 1 MHz and is divided by either 1,
 *   2, 4 or 8.
 * - When the settings of the PWM are modified, the new values are shadowed
 *   in hardware until the PIPGM_PCSR register is written and the currently
 *   running period is completed. This way the hardware switches atomically
 *   from the old setting to the new.
 * - Disabling the hardware completes the currently running period and keeps
 *   the output at low level at all times.
 */

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

#define PIPGM_PCSR(ch) (0x400 + 4 * (ch))
#define PIPGM_PDUT(ch) (0x420 + 4 * (ch))
#define PIPGM_PWMC(ch) (0x440 + 4 * (ch))

#define PIPGM_PWMC_PWMACT		BIT(5)
#define PIPGM_PWMC_CLK_MASK		GENMASK(1, 0)
#define PIPGM_PWMC_POLARITY_MASK	GENMASK(5, 5)

struct visconti_pwm_chip {
	struct pwm_chip chip;
	void __iomem *base;
};

static inline struct visconti_pwm_chip *visconti_pwm_from_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct visconti_pwm_chip, chip);
}

static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			      const struct pwm_state *state)
{
	struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
	u32 period, duty_cycle, pwmc0;

	if (!state->enabled) {
		writel(0, priv->base + PIPGM_PCSR(pwm->hwpwm));
		return 0;
	}

	/*
	 * The biggest period the hardware can provide is
	 *	(0xffff << 3) * 1000 ns
	 * This value fits easily in an u32, so simplify the maths by
	 * capping the values to 32 bit integers.
	 */
	if (state->period > (0xffff << 3) * 1000)
		period = (0xffff << 3) * 1000;
	else
		period = state->period;

	if (state->duty_cycle > period)
		duty_cycle = period;
	else
		duty_cycle = state->duty_cycle;

	/*
	 * The input clock runs fixed at 1 MHz, so we have only
	 * microsecond resolution and so can divide by
	 * NSEC_PER_SEC / CLKFREQ = 1000 without losing precision.
	 */
	period /= 1000;
	duty_cycle /= 1000;

	if (!period)
		return -ERANGE;

	/*
	 * PWMC controls a divider that divides the input clk by a power of two
	 * between 1 and 8. As a smaller divider yields higher precision, pick
	 * the smallest possible one. As period is at most 0xffff << 3, pwmc0 is
	 * in the intended range [0..3].
	 */
	pwmc0 = fls(period >> 16);
	if (WARN_ON(pwmc0 > 3))
		return -EINVAL;

	period >>= pwmc0;
	duty_cycle >>= pwmc0;

	if (state->polarity == PWM_POLARITY_INVERSED)
		pwmc0 |= PIPGM_PWMC_PWMACT;
	writel(pwmc0, priv->base + PIPGM_PWMC(pwm->hwpwm));
	writel(duty_cycle, priv->base + PIPGM_PDUT(pwm->hwpwm));
	writel(period, priv->base + PIPGM_PCSR(pwm->hwpwm));

	return 0;
}

static int visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
				  struct pwm_state *state)
{
	struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
	u32 period, duty, pwmc0, pwmc0_clk;

	period = readl(priv->base + PIPGM_PCSR(pwm->hwpwm));
	duty = readl(priv->base + PIPGM_PDUT(pwm->hwpwm));
	pwmc0 = readl(priv->base + PIPGM_PWMC(pwm->hwpwm));
	pwmc0_clk = pwmc0 & PIPGM_PWMC_CLK_MASK;

	state->period = (period << pwmc0_clk) * NSEC_PER_USEC;
	state->duty_cycle = (duty << pwmc0_clk) * NSEC_PER_USEC;
	if (pwmc0 & PIPGM_PWMC_POLARITY_MASK)
		state->polarity = PWM_POLARITY_INVERSED;
	else
		state->polarity = PWM_POLARITY_NORMAL;

	state->enabled = true;

	return 0;
}

static const struct pwm_ops visconti_pwm_ops = {
	.apply = visconti_pwm_apply,
	.get_state = visconti_pwm_get_state,
	.owner = THIS_MODULE,
};

static int visconti_pwm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct visconti_pwm_chip *priv;
	int ret;

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

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

	priv->chip.dev = dev;
	priv->chip.ops = &visconti_pwm_ops;
	priv->chip.npwm = 4;

	ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
	if (ret < 0)
		return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n");

	return 0;
}

static const struct of_device_id visconti_pwm_of_match[] = {
	{ .compatible = "toshiba,visconti-pwm", },
	{ }
};
MODULE_DEVICE_TABLE(of, visconti_pwm_of_match);

static struct platform_driver visconti_pwm_driver = {
	.driver = {
		.name = "pwm-visconti",
		.of_match_table = visconti_pwm_of_match,
	},
	.probe = visconti_pwm_probe,
};
module_platform_driver(visconti_pwm_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>");
MODULE_ALIAS("platform:pwm-visconti");
