// SPDX-License-Identifier: GPL-2.0+
/*
 * Cirrus Logic CLPS711X PWM driver
 * Author: Alexander Shiyan <shc_work@mail.ru>
 */

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

struct clps711x_chip {
	struct pwm_chip chip;
	void __iomem *pmpcon;
	struct clk *clk;
	spinlock_t lock;
};

static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct clps711x_chip, chip);
}

static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
{
	/* PWM0 - bits 4..7, PWM1 - bits 8..11 */
	u32 shift = (n + 1) * 4;
	unsigned long flags;
	u32 tmp;

	spin_lock_irqsave(&priv->lock, flags);

	tmp = readl(priv->pmpcon);
	tmp &= ~(0xf << shift);
	tmp |= v << shift;
	writel(tmp, priv->pmpcon);

	spin_unlock_irqrestore(&priv->lock, flags);
}

static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
{
	/* Duty cycle 0..15 max */
	return DIV64_U64_ROUND_CLOSEST(v * 0xf, pwm->args.period);
}

static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct clps711x_chip *priv = to_clps711x_chip(chip);
	unsigned int freq = clk_get_rate(priv->clk);

	if (!freq)
		return -EINVAL;

	/* Store constant period value */
	pwm->args.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq);

	return 0;
}

static int clps711x_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			       int duty_ns, int period_ns)
{
	struct clps711x_chip *priv = to_clps711x_chip(chip);
	unsigned int duty;

	if (period_ns != pwm->args.period)
		return -EINVAL;

	duty = clps711x_get_duty(pwm, duty_ns);
	clps711x_pwm_update_val(priv, pwm->hwpwm, duty);

	return 0;
}

static int clps711x_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct clps711x_chip *priv = to_clps711x_chip(chip);
	unsigned int duty;

	duty = clps711x_get_duty(pwm, pwm_get_duty_cycle(pwm));
	clps711x_pwm_update_val(priv, pwm->hwpwm, duty);

	return 0;
}

static void clps711x_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct clps711x_chip *priv = to_clps711x_chip(chip);

	clps711x_pwm_update_val(priv, pwm->hwpwm, 0);
}

static const struct pwm_ops clps711x_pwm_ops = {
	.request = clps711x_pwm_request,
	.config = clps711x_pwm_config,
	.enable = clps711x_pwm_enable,
	.disable = clps711x_pwm_disable,
	.owner = THIS_MODULE,
};

static struct pwm_device *clps711x_pwm_xlate(struct pwm_chip *chip,
					     const struct of_phandle_args *args)
{
	if (args->args[0] >= chip->npwm)
		return ERR_PTR(-EINVAL);

	return pwm_request_from_chip(chip, args->args[0], NULL);
}

static int clps711x_pwm_probe(struct platform_device *pdev)
{
	struct clps711x_chip *priv;

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

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

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

	priv->chip.ops = &clps711x_pwm_ops;
	priv->chip.dev = &pdev->dev;
	priv->chip.npwm = 2;
	priv->chip.of_xlate = clps711x_pwm_xlate;
	priv->chip.of_pwm_n_cells = 1;

	spin_lock_init(&priv->lock);

	return devm_pwmchip_add(&pdev->dev, &priv->chip);
}

static const struct of_device_id __maybe_unused clps711x_pwm_dt_ids[] = {
	{ .compatible = "cirrus,ep7209-pwm", },
	{ }
};
MODULE_DEVICE_TABLE(of, clps711x_pwm_dt_ids);

static struct platform_driver clps711x_pwm_driver = {
	.driver = {
		.name = "clps711x-pwm",
		.of_match_table = of_match_ptr(clps711x_pwm_dt_ids),
	},
	.probe = clps711x_pwm_probe,
};
module_platform_driver(clps711x_pwm_driver);

MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
MODULE_DESCRIPTION("Cirrus Logic CLPS711X PWM driver");
MODULE_LICENSE("GPL");
