// SPDX-License-Identifier: GPL-2.0
/*
 * Clock based PWM controller
 *
 * Copyright (c) 2021 Nikita Travkin <nikita@trvn.ru>
 *
 * This is an "adapter" driver that allows PWM consumers to use
 * system clocks with duty cycle control as PWM outputs.
 *
 * Limitations:
 * - Due to the fact that exact behavior depends on the underlying
 *   clock driver, various limitations are possible.
 * - Underlying clock may not be able to give 0% or 100% duty cycle
 *   (constant off or on), exact behavior will depend on the clock.
 * - When the PWM is disabled, the clock will be disabled as well,
 *   line state will depend on the clock.
 * - The clk API doesn't expose the necessary calls to implement
 *   .get_state().
 */

#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/pwm.h>

struct pwm_clk_chip {
	struct pwm_chip chip;
	struct clk *clk;
	bool clk_enabled;
};

#define to_pwm_clk_chip(_chip) container_of(_chip, struct pwm_clk_chip, chip)

static int pwm_clk_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			 const struct pwm_state *state)
{
	struct pwm_clk_chip *pcchip = to_pwm_clk_chip(chip);
	int ret;
	u32 rate;
	u64 period = state->period;
	u64 duty_cycle = state->duty_cycle;

	if (!state->enabled) {
		if (pwm->state.enabled) {
			clk_disable(pcchip->clk);
			pcchip->clk_enabled = false;
		}
		return 0;
	} else if (!pwm->state.enabled) {
		ret = clk_enable(pcchip->clk);
		if (ret)
			return ret;
		pcchip->clk_enabled = true;
	}

	/*
	 * We have to enable the clk before setting the rate and duty_cycle,
	 * that however results in a window where the clk is on with a
	 * (potentially) different setting. Also setting period and duty_cycle
	 * are two separate calls, so that probably isn't atomic either.
	 */

	rate = DIV64_U64_ROUND_UP(NSEC_PER_SEC, period);
	ret = clk_set_rate(pcchip->clk, rate);
	if (ret)
		return ret;

	if (state->polarity == PWM_POLARITY_INVERSED)
		duty_cycle = period - duty_cycle;

	return clk_set_duty_cycle(pcchip->clk, duty_cycle, period);
}

static const struct pwm_ops pwm_clk_ops = {
	.apply = pwm_clk_apply,
	.owner = THIS_MODULE,
};

static int pwm_clk_probe(struct platform_device *pdev)
{
	struct pwm_clk_chip *pcchip;
	int ret;

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

	pcchip->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(pcchip->clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(pcchip->clk),
				     "Failed to get clock\n");

	pcchip->chip.dev = &pdev->dev;
	pcchip->chip.ops = &pwm_clk_ops;
	pcchip->chip.npwm = 1;

	ret = clk_prepare(pcchip->clk);
	if (ret < 0)
		return dev_err_probe(&pdev->dev, ret, "Failed to prepare clock\n");

	ret = pwmchip_add(&pcchip->chip);
	if (ret < 0) {
		clk_unprepare(pcchip->clk);
		return dev_err_probe(&pdev->dev, ret, "Failed to add pwm chip\n");
	}

	platform_set_drvdata(pdev, pcchip);
	return 0;
}

static int pwm_clk_remove(struct platform_device *pdev)
{
	struct pwm_clk_chip *pcchip = platform_get_drvdata(pdev);

	pwmchip_remove(&pcchip->chip);

	if (pcchip->clk_enabled)
		clk_disable(pcchip->clk);

	clk_unprepare(pcchip->clk);

	return 0;
}

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

static struct platform_driver pwm_clk_driver = {
	.driver = {
		.name = "pwm-clk",
		.of_match_table = pwm_clk_dt_ids,
	},
	.probe = pwm_clk_probe,
	.remove = pwm_clk_remove,
};
module_platform_driver(pwm_clk_driver);

MODULE_ALIAS("platform:pwm-clk");
MODULE_AUTHOR("Nikita Travkin <nikita@trvn.ru>");
MODULE_DESCRIPTION("Clock based PWM driver");
MODULE_LICENSE("GPL");
