/*
 * Copyright (c) 2018, Diego Sueiro <diego.sueiro@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <pwm.h>
#include <soc.h>
#include <device_imx.h>

#define LOG_LEVEL CONFIG_PWM_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(pwm_imx);

#define PWM_PWMSR_FIFOAV_4WORDS	0x4

#define PWM_PWMCR_SWR(x) (((uint32_t)(((uint32_t)(x)) \
				<<PWM_PWMCR_SWR_SHIFT))&PWM_PWMCR_SWR_MASK)

#define DEV_CFG(dev) \
	((const struct imx_pwm_config * const)(dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct imx_pwm_data * const)(dev)->driver_data)
#define DEV_BASE(dev) \
	((PWM_Type *)(DEV_CFG(dev))->base)

struct imx_pwm_config {
	PWM_Type *base;
	u16_t prescaler;
};

struct imx_pwm_data {
	u32_t period_cycles;
};


static bool imx_pwm_is_enabled(PWM_Type *base)
{
	return PWM_PWMCR_REG(base) & PWM_PWMCR_EN_MASK;
}

static int imx_pwm_get_cycles_per_sec(struct device *dev, u32_t pwm,
				       u64_t *cycles)
{
	PWM_Type *base = DEV_BASE(dev);
	const struct imx_pwm_config *config = DEV_CFG(dev);

	*cycles = get_pwm_clock_freq(base) >> config->prescaler;

	return 0;
}

static int imx_pwm_pin_set(struct device *dev, u32_t pwm,
			    u32_t period_cycles, u32_t pulse_cycles)
{
	PWM_Type *base = DEV_BASE(dev);
	const struct imx_pwm_config *config = DEV_CFG(dev);
	struct imx_pwm_data *data = DEV_DATA(dev);
	unsigned int period_ms;
	bool enabled = imx_pwm_is_enabled(base);
	int wait_count = 0, fifoav;
	u32_t cr, sr;


	if ((period_cycles == 0U) || (pulse_cycles > period_cycles)) {
		LOG_ERR("Invalid combination: period_cycles=%d, "
			    "pulse_cycles=%d", period_cycles, pulse_cycles);
		return -EINVAL;
	}

	LOG_DBG("enabled=%d, pulse_cycles=%d, period_cycles=%d,"
		    " duty_cycle=%d\n", enabled, pulse_cycles, period_cycles,
		    (pulse_cycles * 100U / period_cycles));

	/*
	 * i.MX PWMv2 has a 4-word sample FIFO.
	 * In order to avoid FIFO overflow issue, we do software reset
	 * to clear all sample FIFO if the controller is disabled or
	 * wait for a full PWM cycle to get a relinquished FIFO slot
	 * when the controller is enabled and the FIFO is fully loaded.
	 */
	if (enabled) {
		sr = PWM_PWMSR_REG(base);
		fifoav = PWM_PWMSR_FIFOAV(sr);
		if (fifoav == PWM_PWMSR_FIFOAV_4WORDS) {
			period_ms = (get_pwm_clock_freq(base) >>
					config->prescaler) * MSEC_PER_SEC;
			k_sleep(K_MSEC(period_ms));

			sr = PWM_PWMSR_REG(base);
			if (fifoav == PWM_PWMSR_FIFOAV(sr)) {
				LOG_WRN("there is no free FIFO slot\n");
			}
		}
	} else {
		PWM_PWMCR_REG(base) = PWM_PWMCR_SWR(1);
		do {
			k_sleep(1);
			cr = PWM_PWMCR_REG(base);
		} while ((PWM_PWMCR_SWR(cr)) &&
			 (++wait_count < CONFIG_PWM_PWMSWR_LOOP));

		if (PWM_PWMCR_SWR(cr)) {
			LOG_WRN("software reset timeout\n");
		}

	}

	/*
	 * according to imx pwm RM, the real period value should be
	 * PERIOD value in PWMPR plus 2.
	 */
	if (period_cycles > 2) {
		period_cycles -= 2U;
	} else {
		return -EINVAL;
	}

	PWM_PWMSAR_REG(base) = pulse_cycles;

	if (data->period_cycles != period_cycles) {
		LOG_WRN("Changing period cycles from %d to %d in %s",
			    data->period_cycles, period_cycles,
			    dev->config->name);

		data->period_cycles = period_cycles;
		PWM_PWMPR_REG(base) = period_cycles;
	}

	cr = PWM_PWMCR_EN_MASK | PWM_PWMCR_PRESCALER(config->prescaler) |
		PWM_PWMCR_DOZEN_MASK | PWM_PWMCR_WAITEN_MASK |
		PWM_PWMCR_DBGEN_MASK | PWM_PWMCR_CLKSRC(2);

	PWM_PWMCR_REG(base) = cr;

	return 0;
}

static int imx_pwm_init(struct device *dev)
{
	struct imx_pwm_data *data = DEV_DATA(dev);
	PWM_Type *base = DEV_BASE(dev);

	PWM_PWMPR_REG(base) = data->period_cycles;

	return 0;
}

static const struct pwm_driver_api imx_pwm_driver_api = {
	.pin_set = imx_pwm_pin_set,
	.get_cycles_per_sec = imx_pwm_get_cycles_per_sec,
};

#ifdef CONFIG_PWM_1
static const struct imx_pwm_config imx_pwm_config_1 = {
	.base = (PWM_Type *)PWM_1_BASE_ADDRESS,
	.prescaler = PWM_1_PRESCALER,
};

static struct imx_pwm_data imx_pwm_data_1;

DEVICE_AND_API_INIT(imx_pwm_1, PWM_1_LABEL, &imx_pwm_init,
		    &imx_pwm_data_1, &imx_pwm_config_1,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &imx_pwm_driver_api);
#endif /* CONFIG_PWM_1 */

#ifdef CONFIG_PWM_2
static const struct imx_pwm_config imx_pwm_config_2 = {
	.base = (PWM_Type *)PWM_2_BASE_ADDRESS,
	.prescaler = PWM_2_PRESCALER,
};

static struct imx_pwm_data imx_pwm_data_2;

DEVICE_AND_API_INIT(imx_pwm_2, PWM_2_LABEL, &imx_pwm_init,
		    &imx_pwm_data_2, &imx_pwm_config_2,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &imx_pwm_driver_api);
#endif /* CONFIG_PWM_2 */

#ifdef CONFIG_PWM_3
static const struct imx_pwm_config imx_pwm_config_3 = {
	.base = (PWM_Type *)PWM_3_BASE_ADDRESS,
	.prescaler = PWM_3_PRESCALER,
};

static struct imx_pwm_data imx_pwm_data_3;

DEVICE_AND_API_INIT(imx_pwm_3, PWM_3_LABEL, &imx_pwm_init,
		    &imx_pwm_data_3, &imx_pwm_config_3,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &imx_pwm_driver_api);
#endif /* CONFIG_PWM_3 */

#ifdef CONFIG_PWM_4
static const struct imx_pwm_config imx_pwm_config_4 = {
	.base = (PWM_Type *)PWM_4_BASE_ADDRESS,
	.prescaler = PWM_4_PRESCALER,
};

static struct imx_pwm_data imx_pwm_data_4;

DEVICE_AND_API_INIT(imx_pwm_4, PWM_4_LABEL, &imx_pwm_init,
		    &imx_pwm_data_4, &imx_pwm_config_4,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &imx_pwm_driver_api);
#endif /* CONFIG_PWM_4 */
