/*
 * Copyright (c) 2017, NXP
 * Copyright (c) 2020-2021 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_kinetis_ftm_pwm

#include <drivers/clock_control.h>
#include <errno.h>
#include <drivers/pwm.h>
#include <soc.h>
#include <fsl_ftm.h>
#include <fsl_clock.h>

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

#define MAX_CHANNELS ARRAY_SIZE(FTM0->CONTROLS)

/* PWM capture operates on channel pairs */
#define MAX_CAPTURE_PAIRS (MAX_CHANNELS / 2U)
#define PAIR_1ST_CH(pair) (pair * 2U)
#define PAIR_2ND_CH(pair) (PAIR_1ST_CH(pair) + 1)

struct mcux_ftm_config {
	FTM_Type *base;
	char *clock_name;
	clock_control_subsys_t clock_subsys;
	ftm_clock_source_t ftm_clock_source;
	ftm_clock_prescale_t prescale;
	uint8_t channel_count;
	ftm_pwm_mode_t mode;
#ifdef CONFIG_PWM_CAPTURE
	void (*irq_config_func)(const struct device *dev);
#endif /* CONFIG_PWM_CAPTURE */
};

struct mcux_ftm_capture_data {
	ftm_dual_edge_capture_param_t param;
	pwm_capture_callback_handler_t callback;
	void *user_data;
	uint32_t first_edge_overflows;
	bool pulse_capture;
};

struct mcux_ftm_data {
	uint32_t clock_freq;
	uint32_t period_cycles;
	ftm_chnl_pwm_config_param_t channel[MAX_CHANNELS];
#ifdef CONFIG_PWM_CAPTURE
	uint32_t overflows;
	struct mcux_ftm_capture_data capture[MAX_CAPTURE_PAIRS];
#endif /* CONFIG_PWM_CAPTURE */
};

static int mcux_ftm_pin_set(const struct device *dev, uint32_t pwm,
			    uint32_t period_cycles, uint32_t pulse_cycles,
			    pwm_flags_t flags)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	status_t status;
#ifdef CONFIG_PWM_CAPTURE
	uint32_t pair = pwm / 2U;
	uint32_t irqs;
#endif /* CONFIG_PWM_CAPTURE */

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

	if (pwm >= config->channel_count) {
		LOG_ERR("Invalid channel");
		return -ENOTSUP;
	}

#ifdef CONFIG_PWM_CAPTURE
	irqs = FTM_GetEnabledInterrupts(config->base);
	if (irqs & BIT(PAIR_2ND_CH(pair))) {
		LOG_ERR("Cannot set PWM, capture in progress on pair %d", pair);
		return -EBUSY;
	}
#endif /* CONFIG_PWM_CAPTURE */

	data->channel[pwm].dutyValue = pulse_cycles;

	if ((flags & PWM_POLARITY_INVERTED) == 0) {
		data->channel[pwm].level = kFTM_HighTrue;
	} else {
		data->channel[pwm].level = kFTM_LowTrue;
	}

	LOG_DBG("pulse_cycles=%d, period_cycles=%d, flags=%d",
		pulse_cycles, period_cycles, flags);

	if (period_cycles != data->period_cycles) {
#ifdef CONFIG_PWM_CAPTURE
		if (irqs & BIT_MASK(ARRAY_SIZE(data->channel))) {
			LOG_ERR("Cannot change period, capture in progress");
			return -EBUSY;
		}
#endif /* CONFIG_PWM_CAPTURE */

		if (data->period_cycles != 0) {
			/* Only warn when not changing from zero */
			LOG_WRN("Changing period cycles from %d to %d"
				" affects all %d channels in %s",
				data->period_cycles, period_cycles,
				config->channel_count, dev->name);
		}

		data->period_cycles = period_cycles;

		FTM_StopTimer(config->base);
		FTM_SetTimerPeriod(config->base, period_cycles);

		FTM_SetSoftwareTrigger(config->base, true);
		FTM_StartTimer(config->base, config->ftm_clock_source);
	}

	status = FTM_SetupPwmMode(config->base, data->channel,
				  config->channel_count, config->mode);
	if (status != kStatus_Success) {
		LOG_ERR("Could not set up pwm");
		return -ENOTSUP;
	}
	FTM_SetSoftwareTrigger(config->base, true);

	return 0;
}

#ifdef CONFIG_PWM_CAPTURE
static int mcux_ftm_pin_configure_capture(const struct device *dev,
					  uint32_t pwm,
					  pwm_flags_t flags,
					  pwm_capture_callback_handler_t cb,
					  void *user_data)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	ftm_dual_edge_capture_param_t *param;
	uint32_t pair = pwm / 2U;

	if (pwm & 0x1U) {
		LOG_ERR("PWM capture only supported on even channels");
		return -ENOTSUP;
	}

	if (pair >= ARRAY_SIZE(data->capture)) {
		LOG_ERR("Invalid channel pair %d", pair);
		return -EINVAL;
	}

	if (FTM_GetEnabledInterrupts(config->base) & BIT(PAIR_2ND_CH(pair))) {
		LOG_ERR("Capture already active on channel pair %d", pair);
		return -EBUSY;
	}

	if (!(flags & PWM_CAPTURE_TYPE_MASK)) {
		LOG_ERR("No capture type specified");
		return -EINVAL;
	}

	if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) {
		LOG_ERR("Cannot capture both period and pulse width");
		return -ENOTSUP;
	}

	data->capture[pair].callback = cb;
	data->capture[pair].user_data = user_data;
	param = &data->capture[pair].param;

	if ((flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS) {
		param->mode = kFTM_Continuous;
	} else {
		param->mode = kFTM_OneShot;
	}

	if (flags & PWM_CAPTURE_TYPE_PERIOD) {
		data->capture[pair].pulse_capture = false;

		if (flags & PWM_POLARITY_INVERTED) {
			param->currChanEdgeMode = kFTM_FallingEdge;
			param->nextChanEdgeMode = kFTM_FallingEdge;
		} else {
			param->currChanEdgeMode = kFTM_RisingEdge;
			param->nextChanEdgeMode = kFTM_RisingEdge;
		}
	} else {
		data->capture[pair].pulse_capture = true;

		if (flags & PWM_POLARITY_INVERTED) {
			param->currChanEdgeMode = kFTM_FallingEdge;
			param->nextChanEdgeMode = kFTM_RisingEdge;
		} else {
			param->currChanEdgeMode = kFTM_RisingEdge;
			param->nextChanEdgeMode = kFTM_FallingEdge;
		}
	}

	return 0;
}

static int mcux_ftm_pin_enable_capture(const struct device *dev, uint32_t pwm)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	uint32_t pair = pwm / 2U;

	if (pwm & 0x1U) {
		LOG_ERR("PWM capture only supported on even channels");
		return -ENOTSUP;
	}

	if (pair >= ARRAY_SIZE(data->capture)) {
		LOG_ERR("Invalid channel pair %d", pair);
		return -EINVAL;
	}

	if (!data->capture[pair].callback) {
		LOG_ERR("PWM capture not configured");
		return -EINVAL;
	}

	if (FTM_GetEnabledInterrupts(config->base) & BIT(PAIR_2ND_CH(pair))) {
		LOG_WRN("Capture already active on channel pair %d", pair);
		return 0;
	}

	FTM_ClearStatusFlags(config->base, BIT(PAIR_1ST_CH(pair)) |
			     BIT(PAIR_2ND_CH(pair)));

	FTM_SetupDualEdgeCapture(config->base, pair, &data->capture[pair].param,
				 CONFIG_PWM_CAPTURE_MCUX_FTM_FILTER_VALUE);

	FTM_EnableInterrupts(config->base, BIT(PAIR_1ST_CH(pair)) |
			     BIT(PAIR_2ND_CH(pair)));

	return 0;
}

static int mcux_ftm_pin_disable_capture(const struct device *dev, uint32_t pwm)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	uint32_t pair = pwm / 2U;

	if (pwm & 0x1U) {
		LOG_ERR("PWM capture only supported on even channels");
		return -ENOTSUP;
	}

	if (pair >= ARRAY_SIZE(data->capture)) {
		LOG_ERR("Invalid channel pair %d", pair);
		return -EINVAL;
	}

	FTM_DisableInterrupts(config->base, BIT(PAIR_1ST_CH(pair)) |
			      BIT(PAIR_2ND_CH(pair)));

	/* Clear Dual Edge Capture Enable bit */
	config->base->COMBINE &= ~(1UL << (FTM_COMBINE_DECAP0_SHIFT +
		(FTM_COMBINE_COMBINE1_SHIFT * pair)));

	return 0;
}

static void mcux_ftm_capture_first_edge(const struct device *dev, uint32_t pwm)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	struct mcux_ftm_capture_data *capture;
	uint32_t pair = pwm / 2U;

	__ASSERT_NO_MSG(pair < ARRAY_SIZE(data->capture));
	capture = &data->capture[pair];

	FTM_DisableInterrupts(config->base, BIT(PAIR_1ST_CH(pair)));
	capture->first_edge_overflows = data->overflows;
}

static void mcux_ftm_capture_second_edge(const struct device *dev, uint32_t pwm)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	uint32_t second_edge_overflows = data->overflows;
	struct mcux_ftm_capture_data *capture;
	uint32_t pair = pwm / 2U;
	uint32_t overflows;
	uint32_t first_cnv;
	uint32_t second_cnv;
	uint32_t cycles = 0;
	int status = 0;

	__ASSERT_NO_MSG(pair < ARRAY_SIZE(data->capture));
	capture = &data->capture[pair];

	first_cnv = config->base->CONTROLS[PAIR_1ST_CH(pair)].CnV;
	second_cnv = config->base->CONTROLS[PAIR_2ND_CH(pair)].CnV;

	/* Prepare for next capture */
	if (capture->param.mode == kFTM_Continuous) {
		FTM_ClearStatusFlags(config->base, BIT(PAIR_2ND_CH(pair)));
	}

	/* Calculate cycles, check for overflows */
	overflows = second_edge_overflows - capture->first_edge_overflows;
	if (overflows > 0) {
		if (u32_mul_overflow(overflows, config->base->MOD, &cycles)) {
			LOG_ERR("overflow while calculating cycles");
			status = -ERANGE;
		} else {
			cycles -= first_cnv;
			if (u32_add_overflow(cycles, second_cnv, &cycles)) {
				LOG_ERR("overflow while calculating cycles");
				cycles = 0;
				status = -ERANGE;
			}
		}
	} else {
		cycles = second_cnv - first_cnv;
	}

	LOG_DBG("pair = %d, overflows = %u, cycles = %u", pair, overflows,
		cycles);

	if (capture->pulse_capture) {
		capture->callback(dev, pair, 0, cycles, status,
				  capture->user_data);
	} else {
		capture->callback(dev, pair, cycles, 0, status,
				  capture->user_data);
	}

	if (capture->param.mode == kFTM_OneShot) {
		FTM_DisableInterrupts(config->base, BIT(PAIR_2ND_CH(pair)));
	} else {
		FTM_EnableInterrupts(config->base, BIT(PAIR_1ST_CH(pair)));
	}
}

static void mcux_ftm_isr(const struct device *dev)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	uint32_t flags;
	uint32_t irqs;
	uint32_t ch;

	flags = FTM_GetStatusFlags(config->base);
	irqs = FTM_GetEnabledInterrupts(config->base);

	if (flags & kFTM_TimeOverflowFlag) {
		data->overflows++;
		FTM_ClearStatusFlags(config->base, kFTM_TimeOverflowFlag);
	}

	for (ch = 0; ch < MAX_CHANNELS; ch++) {
		if ((flags & BIT(ch)) && (irqs & BIT(ch))) {
			if (ch & 1) {
				mcux_ftm_capture_second_edge(dev, ch);
			} else {
				mcux_ftm_capture_first_edge(dev, ch);
			}
		}
	}
}
#endif /* CONFIG_PWM_CAPTURE */

static int mcux_ftm_get_cycles_per_sec(const struct device *dev, uint32_t pwm,
				       uint64_t *cycles)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;

	*cycles = data->clock_freq >> config->prescale;

	return 0;
}

static int mcux_ftm_init(const struct device *dev)
{
	const struct mcux_ftm_config *config = dev->config;
	struct mcux_ftm_data *data = dev->data;
	ftm_chnl_pwm_config_param_t *channel = data->channel;
	const struct device *clock_dev;
	ftm_config_t ftm_config;
	int i;

	if (config->channel_count > ARRAY_SIZE(data->channel)) {
		LOG_ERR("Invalid channel count");
		return -EINVAL;
	}

	clock_dev = device_get_binding(config->clock_name);
	if (clock_dev == NULL) {
		LOG_ERR("Could not get clock device");
		return -EINVAL;
	}

	if (clock_control_get_rate(clock_dev, config->clock_subsys,
				   &data->clock_freq)) {
		LOG_ERR("Could not get clock frequency");
		return -EINVAL;
	}

	for (i = 0; i < config->channel_count; i++) {
		channel->chnlNumber = i;
		channel->level = kFTM_NoPwmSignal;
		channel->dutyValue = 0;
		channel->firstEdgeValue = 0;
		channel++;
	}

	FTM_GetDefaultConfig(&ftm_config);
	ftm_config.prescale = config->prescale;

	FTM_Init(config->base, &ftm_config);

#ifdef CONFIG_PWM_CAPTURE
	config->irq_config_func(dev);
	FTM_EnableInterrupts(config->base,
			     kFTM_TimeOverflowInterruptEnable);

	data->period_cycles = 0xFFFFU;
	FTM_SetTimerPeriod(config->base, data->period_cycles);
	FTM_SetSoftwareTrigger(config->base, true);
	FTM_StartTimer(config->base, config->ftm_clock_source);
#endif /* CONFIG_PWM_CAPTURE */

	return 0;
}

static const struct pwm_driver_api mcux_ftm_driver_api = {
	.pin_set = mcux_ftm_pin_set,
	.get_cycles_per_sec = mcux_ftm_get_cycles_per_sec,
#ifdef CONFIG_PWM_CAPTURE
	.pin_configure_capture = mcux_ftm_pin_configure_capture,
	.pin_enable_capture = mcux_ftm_pin_enable_capture,
	.pin_disable_capture = mcux_ftm_pin_disable_capture,
#endif /* CONFIG_PWM_CAPTURE */
};

#define TO_FTM_PRESCALE_DIVIDE(val) _DO_CONCAT(kFTM_Prescale_Divide_, val)

#ifdef CONFIG_PWM_CAPTURE
#define FTM_CONFIG_FUNC(n) \
static void mcux_ftm_config_func_##n(const struct device *dev) \
{ \
	IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
		    mcux_ftm_isr, DEVICE_DT_INST_GET(n), 0); \
	irq_enable(DT_INST_IRQN(n)); \
}
#define FTM_CFG_CAPTURE_INIT(n) \
	.irq_config_func = mcux_ftm_config_func_##n
#define FTM_INIT_CFG(n)	FTM_DECLARE_CFG(n, FTM_CFG_CAPTURE_INIT(n))
#else /* !CONFIG_PWM_CAPTURE */
#define FTM_CONFIG_FUNC(n)
#define FTM_CFG_CAPTURE_INIT
#define FTM_INIT_CFG(n)	FTM_DECLARE_CFG(n, FTM_CFG_CAPTURE_INIT)
#endif /* !CONFIG_PWM_CAPTURE */

#define FTM_DECLARE_CFG(n, CAPTURE_INIT) \
static const struct mcux_ftm_config mcux_ftm_config_##n = { \
	.base = (FTM_Type *)DT_INST_REG_ADDR(n),\
	.clock_name = DT_INST_CLOCKS_LABEL(n), \
	.clock_subsys = (clock_control_subsys_t) \
		DT_INST_CLOCKS_CELL(n, name), \
	.ftm_clock_source = kFTM_FixedClock, \
	.prescale = TO_FTM_PRESCALE_DIVIDE(DT_INST_PROP(n, prescaler)),\
	.channel_count = FSL_FEATURE_FTM_CHANNEL_COUNTn((FTM_Type *) \
		DT_INST_REG_ADDR(n)), \
	.mode = kFTM_EdgeAlignedPwm, \
	CAPTURE_INIT \
}

#define FTM_DEVICE(n) \
	static struct mcux_ftm_data mcux_ftm_data_##n; \
	static const struct mcux_ftm_config mcux_ftm_config_##n; \
	DEVICE_DT_INST_DEFINE(n, &mcux_ftm_init,		       \
			    device_pm_control_nop, &mcux_ftm_data_##n, \
			    &mcux_ftm_config_##n, \
			    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
			    &mcux_ftm_driver_api); \
	FTM_CONFIG_FUNC(n) \
	FTM_INIT_CFG(n);

DT_INST_FOREACH_STATUS_OKAY(FTM_DEVICE)
