// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2015 Intel Corporation. All rights reserved.
 *
 * Author: Shobhit Kumar <shobhit.kumar@intel.com>
 */

#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/pwm.h>

#define PWM0_CLK_DIV		0x4B
#define  PWM_OUTPUT_ENABLE	BIT(7)
#define  PWM_DIV_CLK_0		0x00 /* DIVIDECLK = BASECLK */
#define  PWM_DIV_CLK_100	0x63 /* DIVIDECLK = BASECLK/100 */
#define  PWM_DIV_CLK_128	0x7F /* DIVIDECLK = BASECLK/128 */

#define PWM0_DUTY_CYCLE		0x4E
#define BACKLIGHT_EN		0x51

#define PWM_MAX_LEVEL		0xFF

#define PWM_BASE_CLK_MHZ	6	/* 6 MHz */
#define PWM_MAX_PERIOD_NS	5461334	/* 183 Hz */

/**
 * struct crystalcove_pwm - Crystal Cove PWM controller
 * @chip: the abstract pwm_chip structure.
 * @regmap: the regmap from the parent device.
 */
struct crystalcove_pwm {
	struct pwm_chip chip;
	struct regmap *regmap;
};

static inline struct crystalcove_pwm *to_crc_pwm(struct pwm_chip *pc)
{
	return container_of(pc, struct crystalcove_pwm, chip);
}

static int crc_pwm_calc_clk_div(int period_ns)
{
	int clk_div;

	clk_div = PWM_BASE_CLK_MHZ * period_ns / (256 * NSEC_PER_USEC);
	/* clk_div 1 - 128, maps to register values 0-127 */
	if (clk_div > 0)
		clk_div--;

	return clk_div;
}

static int crc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			 const struct pwm_state *state)
{
	struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip);
	struct device *dev = crc_pwm->chip.dev;
	int err;

	if (state->period > PWM_MAX_PERIOD_NS) {
		dev_err(dev, "un-supported period_ns\n");
		return -EINVAL;
	}

	if (state->polarity != PWM_POLARITY_NORMAL)
		return -EINVAL;

	if (pwm_is_enabled(pwm) && !state->enabled) {
		err = regmap_write(crc_pwm->regmap, BACKLIGHT_EN, 0);
		if (err) {
			dev_err(dev, "Error writing BACKLIGHT_EN %d\n", err);
			return err;
		}
	}

	if (pwm_get_duty_cycle(pwm) != state->duty_cycle ||
	    pwm_get_period(pwm) != state->period) {
		u64 level = state->duty_cycle * PWM_MAX_LEVEL;

		do_div(level, state->period);

		err = regmap_write(crc_pwm->regmap, PWM0_DUTY_CYCLE, level);
		if (err) {
			dev_err(dev, "Error writing PWM0_DUTY_CYCLE %d\n", err);
			return err;
		}
	}

	if (pwm_is_enabled(pwm) && state->enabled &&
	    pwm_get_period(pwm) != state->period) {
		/* changing the clk divisor, clear PWM_OUTPUT_ENABLE first */
		err = regmap_write(crc_pwm->regmap, PWM0_CLK_DIV, 0);
		if (err) {
			dev_err(dev, "Error writing PWM0_CLK_DIV %d\n", err);
			return err;
		}
	}

	if (pwm_get_period(pwm) != state->period ||
	    pwm_is_enabled(pwm) != state->enabled) {
		int clk_div = crc_pwm_calc_clk_div(state->period);
		int pwm_output_enable = state->enabled ? PWM_OUTPUT_ENABLE : 0;

		err = regmap_write(crc_pwm->regmap, PWM0_CLK_DIV,
				   clk_div | pwm_output_enable);
		if (err) {
			dev_err(dev, "Error writing PWM0_CLK_DIV %d\n", err);
			return err;
		}
	}

	if (!pwm_is_enabled(pwm) && state->enabled) {
		err = regmap_write(crc_pwm->regmap, BACKLIGHT_EN, 1);
		if (err) {
			dev_err(dev, "Error writing BACKLIGHT_EN %d\n", err);
			return err;
		}
	}

	return 0;
}

static int crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			     struct pwm_state *state)
{
	struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip);
	struct device *dev = crc_pwm->chip.dev;
	unsigned int clk_div, clk_div_reg, duty_cycle_reg;
	int error;

	error = regmap_read(crc_pwm->regmap, PWM0_CLK_DIV, &clk_div_reg);
	if (error) {
		dev_err(dev, "Error reading PWM0_CLK_DIV %d\n", error);
		return 0;
	}

	error = regmap_read(crc_pwm->regmap, PWM0_DUTY_CYCLE, &duty_cycle_reg);
	if (error) {
		dev_err(dev, "Error reading PWM0_DUTY_CYCLE %d\n", error);
		return 0;
	}

	clk_div = (clk_div_reg & ~PWM_OUTPUT_ENABLE) + 1;

	state->period =
		DIV_ROUND_UP(clk_div * NSEC_PER_USEC * 256, PWM_BASE_CLK_MHZ);
	state->duty_cycle =
		DIV_ROUND_UP_ULL(duty_cycle_reg * state->period, PWM_MAX_LEVEL);
	state->polarity = PWM_POLARITY_NORMAL;
	state->enabled = !!(clk_div_reg & PWM_OUTPUT_ENABLE);

	return 0;
}

static const struct pwm_ops crc_pwm_ops = {
	.apply = crc_pwm_apply,
	.get_state = crc_pwm_get_state,
};

static int crystalcove_pwm_probe(struct platform_device *pdev)
{
	struct crystalcove_pwm *pwm;
	struct device *dev = pdev->dev.parent;
	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);

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

	pwm->chip.dev = &pdev->dev;
	pwm->chip.ops = &crc_pwm_ops;
	pwm->chip.npwm = 1;

	/* get the PMIC regmap */
	pwm->regmap = pmic->regmap;

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

static struct platform_driver crystalcove_pwm_driver = {
	.probe = crystalcove_pwm_probe,
	.driver = {
		.name = "crystal_cove_pwm",
	},
};

builtin_platform_driver(crystalcove_pwm_driver);
