// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 Intel Corporation.
 *
 * Limitations:
 * - The hardware supports fixed period & configures only 2-wire mode.
 * - Supports normal polarity. Does not support changing polarity.
 * - When PWM is disabled, output of PWM will become 0(inactive). It doesn't
 *   keep track of running period.
 * - When duty cycle is changed, PWM output may be a mix of previous setting
 *   and new setting for the first period. From second period, the output is
 *   based on new setting.
 * - It is a dedicated PWM fan controller. There are no other consumers for
 *   this PWM controller.
 */
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/reset.h>

#define LGM_PWM_FAN_CON0		0x0
#define LGM_PWM_FAN_EN_EN		BIT(0)
#define LGM_PWM_FAN_EN_DIS		0x0
#define LGM_PWM_FAN_EN_MSK		BIT(0)
#define LGM_PWM_FAN_MODE_2WIRE		0x0
#define LGM_PWM_FAN_MODE_MSK		BIT(1)
#define LGM_PWM_FAN_DC_MSK		GENMASK(23, 16)

#define LGM_PWM_FAN_CON1		0x4
#define LGM_PWM_FAN_MAX_RPM_MSK		GENMASK(15, 0)

#define LGM_PWM_MAX_RPM			(BIT(16) - 1)
#define LGM_PWM_DEFAULT_RPM		4000
#define LGM_PWM_MAX_DUTY_CYCLE		(BIT(8) - 1)

#define LGM_PWM_DC_BITS			8

#define LGM_PWM_PERIOD_2WIRE_NS		(40 * NSEC_PER_MSEC)

struct lgm_pwm_chip {
	struct regmap *regmap;
	u32 period;
};

static inline struct lgm_pwm_chip *to_lgm_pwm_chip(struct pwm_chip *chip)
{
	return pwmchip_get_drvdata(chip);
}

static int lgm_pwm_enable(struct pwm_chip *chip, bool enable)
{
	struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
	struct regmap *regmap = pc->regmap;

	return regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_EN_MSK,
				  enable ? LGM_PWM_FAN_EN_EN : LGM_PWM_FAN_EN_DIS);
}

static int lgm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			 const struct pwm_state *state)
{
	struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
	u32 duty_cycle, val;
	int ret;

	/* The hardware only supports normal polarity and fixed period. */
	if (state->polarity != PWM_POLARITY_NORMAL || state->period < pc->period)
		return -EINVAL;

	if (!state->enabled)
		return lgm_pwm_enable(chip, 0);

	duty_cycle = min_t(u64, state->duty_cycle, pc->period);
	val = duty_cycle * LGM_PWM_MAX_DUTY_CYCLE / pc->period;

	ret = regmap_update_bits(pc->regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_DC_MSK,
				 FIELD_PREP(LGM_PWM_FAN_DC_MSK, val));
	if (ret)
		return ret;

	return lgm_pwm_enable(chip, 1);
}

static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			     struct pwm_state *state)
{
	struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
	u32 duty, val;

	state->enabled = regmap_test_bits(pc->regmap, LGM_PWM_FAN_CON0,
					  LGM_PWM_FAN_EN_EN);
	state->polarity = PWM_POLARITY_NORMAL;
	state->period = pc->period; /* fixed period */

	regmap_read(pc->regmap, LGM_PWM_FAN_CON0, &val);
	duty = FIELD_GET(LGM_PWM_FAN_DC_MSK, val);
	state->duty_cycle = DIV_ROUND_UP(duty * pc->period, LGM_PWM_MAX_DUTY_CYCLE);

	return 0;
}

static const struct pwm_ops lgm_pwm_ops = {
	.get_state = lgm_pwm_get_state,
	.apply = lgm_pwm_apply,
};

static void lgm_pwm_init(struct lgm_pwm_chip *pc)
{
	struct regmap *regmap = pc->regmap;
	u32 con0_val;

	con0_val = FIELD_PREP(LGM_PWM_FAN_MODE_MSK, LGM_PWM_FAN_MODE_2WIRE);
	pc->period = LGM_PWM_PERIOD_2WIRE_NS;
	regmap_update_bits(regmap, LGM_PWM_FAN_CON1, LGM_PWM_FAN_MAX_RPM_MSK,
			   LGM_PWM_DEFAULT_RPM);
	regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_MODE_MSK,
			   con0_val);
}

static const struct regmap_config lgm_pwm_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
};

static void lgm_clk_release(void *data)
{
	struct clk *clk = data;

	clk_disable_unprepare(clk);
}

static int lgm_clk_enable(struct device *dev, struct clk *clk)
{
	int ret;

	ret = clk_prepare_enable(clk);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, lgm_clk_release, clk);
}

static void lgm_reset_control_release(void *data)
{
	struct reset_control *rst = data;

	reset_control_assert(rst);
}

static int lgm_reset_control_deassert(struct device *dev, struct reset_control *rst)
{
	int ret;

	ret = reset_control_deassert(rst);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, lgm_reset_control_release, rst);
}

static int lgm_pwm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct reset_control *rst;
	struct pwm_chip *chip;
	struct lgm_pwm_chip *pc;
	void __iomem *io_base;
	struct clk *clk;
	int ret;

	chip = devm_pwmchip_alloc(dev, 1, sizeof(*pc));
	if (IS_ERR(chip))
		return PTR_ERR(chip);
	pc = to_lgm_pwm_chip(chip);

	io_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(io_base))
		return PTR_ERR(io_base);

	pc->regmap = devm_regmap_init_mmio(dev, io_base, &lgm_pwm_regmap_config);
	if (IS_ERR(pc->regmap))
		return dev_err_probe(dev, PTR_ERR(pc->regmap),
				     "failed to init register map\n");

	clk = devm_clk_get(dev, NULL);
	if (IS_ERR(clk))
		return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n");

	ret = lgm_clk_enable(dev, clk);
	if (ret)
		return dev_err_probe(dev, ret, "failed to enable clock\n");

	rst = devm_reset_control_get_exclusive(dev, NULL);
	if (IS_ERR(rst))
		return dev_err_probe(dev, PTR_ERR(rst),
				     "failed to get reset control\n");

	ret = lgm_reset_control_deassert(dev, rst);
	if (ret)
		return dev_err_probe(dev, ret, "cannot deassert reset control\n");

	chip->ops = &lgm_pwm_ops;

	lgm_pwm_init(pc);

	ret = devm_pwmchip_add(dev, chip);
	if (ret < 0)
		return dev_err_probe(dev, ret, "failed to add PWM chip\n");

	return 0;
}

static const struct of_device_id lgm_pwm_of_match[] = {
	{ .compatible = "intel,lgm-pwm" },
	{ }
};
MODULE_DEVICE_TABLE(of, lgm_pwm_of_match);

static struct platform_driver lgm_pwm_driver = {
	.driver = {
		.name = "intel-pwm",
		.of_match_table = lgm_pwm_of_match,
	},
	.probe = lgm_pwm_probe,
};
module_platform_driver(lgm_pwm_driver);

MODULE_DESCRIPTION("Intel LGM Pulse Width Modulator driver");
MODULE_LICENSE("GPL v2");
