// 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_device.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 void 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;
}

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");
