// 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 pwm_chip chip;
	struct regmap *regmap;
	u32 period;
};

static inline struct lgm_pwm_chip *to_lgm_pwm_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct lgm_pwm_chip, 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,
	.owner = THIS_MODULE,
};

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 lgm_pwm_chip *pc;
	void __iomem *io_base;
	struct clk *clk;
	int ret;

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

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

	pc->chip.dev = dev;
	pc->chip.ops = &lgm_pwm_ops;
	pc->chip.npwm = 1;

	lgm_pwm_init(pc);

	ret = devm_pwmchip_add(dev, &pc->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_LICENSE("GPL v2");
