/*
 * Copyright (c) 2023 Nuvoton Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nuvoton_numaker_adc

#include <zephyr/kernel.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/clock_control_numaker.h>
#include <zephyr/logging/log.h>
#include <soc.h>
#include <NuMicro.h>

#define ADC_CONTEXT_USES_KERNEL_TIMER
#define ADC_CONTEXT_ENABLE_ON_COMPLETE
#include "adc_context.h"

LOG_MODULE_REGISTER(adc_numaker, CONFIG_ADC_LOG_LEVEL);

/* Device config */
struct adc_numaker_config {
	/* eadc base address */
	EADC_T *eadc_base;
	uint8_t channel_cnt;
	const struct reset_dt_spec reset;
	/* clock configuration */
	uint32_t clk_modidx;
	uint32_t clk_src;
	uint32_t clk_div;
	const struct device *clk_dev;
	const struct pinctrl_dev_config *pincfg;
	void (*irq_config_func)(const struct device *dev);
};

/* Driver context/data */
struct adc_numaker_data {
	struct adc_context ctx;
	const struct device *dev;
	uint16_t *buffer;
	uint16_t *buf_end;
	uint16_t *repeat_buffer;
	bool is_differential;
	uint32_t channels;
	uint32_t acq_time;
};

static int adc_numaker_channel_setup(const struct device *dev,
				     const struct adc_channel_cfg *chan_cfg)
{
	const struct adc_numaker_config *cfg = dev->config;
	struct adc_numaker_data *data = dev->data;

	if (chan_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
		if ((ADC_ACQ_TIME_UNIT(chan_cfg->acquisition_time) != ADC_ACQ_TIME_TICKS) ||
		    (ADC_ACQ_TIME_VALUE(chan_cfg->acquisition_time) > 255)) {
			LOG_ERR("Selected ADC acquisition time is not in 0~255 ticks");
			return -EINVAL;
		}
	}
	data->acq_time = ADC_ACQ_TIME_VALUE(chan_cfg->acquisition_time);

	if (chan_cfg->gain != ADC_GAIN_1) {
		LOG_ERR("Not support channel gain");
		return -ENOTSUP;
	}

	if (chan_cfg->reference != ADC_REF_INTERNAL) {
		LOG_ERR("Not support channel reference");
		return -ENOTSUP;
	}

	if (chan_cfg->channel_id >= cfg->channel_cnt) {
		LOG_ERR("Invalid channel (%u)", chan_cfg->channel_id);
		return -EINVAL;
	}

	data->is_differential = (chan_cfg->differential) ? true : false;

	return 0;
}

static int m_adc_numaker_validate_buffer_size(const struct device *dev,
					      const struct adc_sequence *sequence)
{
	const struct adc_numaker_config *cfg = dev->config;
	uint8_t channel_cnt = 0;
	uint32_t mask;
	size_t needed_size;

	for (mask = BIT(cfg->channel_cnt - 1); mask != 0; mask >>= 1) {
		if (mask & sequence->channels) {
			channel_cnt++;
		}
	}

	needed_size = channel_cnt * sizeof(uint16_t);
	if (sequence->options) {
		needed_size *= (1 + sequence->options->extra_samplings);
	}

	if (sequence->buffer_size < needed_size) {
		return -ENOBUFS;
	}

	return 0;
}

static void adc_numaker_isr(const struct device *dev)
{
	const struct adc_numaker_config *cfg = dev->config;
	EADC_T *eadc = cfg->eadc_base;
	struct adc_numaker_data *const data = dev->data;
	uint32_t channel_mask = data->channels;
	uint32_t module_mask = channel_mask;
	uint32_t module_id;
	uint16_t conv_data;
	uint32_t pend_flag;

	LOG_DBG("ADC ISR pend flag: 0x%X\n", pend_flag);
	LOG_DBG("ADC ISR STATUS2[0x%x] STATUS3[0x%x]", eadc->STATUS2, eadc->STATUS3);
	/* Complete the conversion of channels.
	 * Check EAC idle by EADC_STATUS2_BUSY_Msk
	 * Check trigger source coming by EADC_STATUS2_ADOVIF_Msk
	 * Confirm all sample modules are idle by EADC_STATUS2_ADOVIF_Msk
	 */
	if (!(eadc->STATUS2 & EADC_STATUS2_BUSY_Msk) &&
	    ((eadc->STATUS3 & EADC_STATUS3_CURSPL_Msk) == EADC_STATUS3_CURSPL_Msk)) {
		/* Stop the conversion for sample module */
		EADC_STOP_CONV(eadc, module_mask);

		/* Disable sample module A/D ADINT0 interrupt. */
		EADC_DISABLE_INT(eadc, BIT0);

		/* Disable the sample module ADINT0 interrupt source */
		EADC_DISABLE_SAMPLE_MODULE_INT(eadc, 0, module_mask);

		/* Get conversion data of each sample module for selected channel */
		while (module_mask) {
			module_id = find_lsb_set(module_mask) - 1;

			conv_data = EADC_GET_CONV_DATA(eadc, module_id);
			if (data->buffer < data->buf_end) {
				*data->buffer++ = conv_data;
				LOG_DBG("ADC ISR id=%d, data=0x%x", module_id, conv_data);
			}
			module_mask &= ~BIT(module_id);

			/* Disable all channels on each sample module */
			eadc->SCTL[module_id] = 0;
		}

		/* Inform sampling is done */
		adc_context_on_sampling_done(&data->ctx, data->dev);
	}

	/* Clear the A/D ADINT0 interrupt flag */
	EADC_CLR_INT_FLAG(eadc, EADC_STATUS2_ADIF0_Msk);
}

static void m_adc_numaker_start_scan(const struct device *dev)
{
	const struct adc_numaker_config *cfg = dev->config;
	EADC_T *eadc = cfg->eadc_base;
	struct adc_numaker_data *const data = dev->data;
	uint32_t channel_mask = data->channels;
	uint32_t module_mask = channel_mask;
	uint32_t channel_id;
	uint32_t module_id;

	/* Configure the sample module, analog input channel and software trigger source */
	while (channel_mask) {
		channel_id = find_lsb_set(channel_mask) - 1;
		module_id = channel_id;
		channel_mask &= ~BIT(channel_id);
		EADC_ConfigSampleModule(eadc, module_id,
					EADC_SOFTWARE_TRIGGER, channel_id);
		/* Set sample module external sampling time to 0 */
		EADC_SetExtendSampleTime(eadc, module_id, data->acq_time);
	}

	/* Clear the A/D ADINT0 interrupt flag for safe */
	EADC_CLR_INT_FLAG(eadc, EADC_STATUS2_ADIF0_Msk);

	/* Enable sample module A/D ADINT0 interrupt. */
	EADC_ENABLE_INT(eadc, BIT0);

	/* Enable sample module interrupt ADINT0. */
	EADC_ENABLE_SAMPLE_MODULE_INT(eadc, 0, module_mask);

	/* Start conversion */
	EADC_START_CONV(eadc, module_mask);
}

/* Implement ADC API functions of adc_context.h
 * - adc_context_start_sampling()
 * - adc_context_update_buffer_pointer()
 */
static void adc_context_start_sampling(struct adc_context *ctx)
{
	struct adc_numaker_data *const data =
		CONTAINER_OF(ctx, struct adc_numaker_data, ctx);

	data->repeat_buffer = data->buffer;
	data->channels = ctx->sequence.channels;

	/* Start ADC conversion for sample modules/channels */
	m_adc_numaker_start_scan(data->dev);
}

static void adc_context_update_buffer_pointer(struct adc_context *ctx,
					      bool repeat_sampling)
{
	struct adc_numaker_data *data =
		CONTAINER_OF(ctx, struct adc_numaker_data, ctx);

	if (repeat_sampling) {
		data->buffer = data->repeat_buffer;
	}
}

static void adc_context_on_complete(struct adc_context *ctx, int status)
{
	struct adc_numaker_data *data =
		CONTAINER_OF(ctx, struct adc_numaker_data, ctx);
	const struct adc_numaker_config *cfg = data->dev->config;
	EADC_T *eadc = cfg->eadc_base;

	ARG_UNUSED(status);

	/* Disable ADC */
	EADC_Close(eadc);
}

static int m_adc_numaker_start_read(const struct device *dev,
				  const struct adc_sequence *sequence)
{
	const struct adc_numaker_config *cfg = dev->config;
	struct adc_numaker_data *data = dev->data;
	EADC_T *eadc = cfg->eadc_base;
	int err;

	err = m_adc_numaker_validate_buffer_size(dev, sequence);
	if (err) {
		LOG_ERR("ADC provided buffer is too small");
		return err;
	}

	if (!sequence->resolution) {
		LOG_ERR("ADC resolution is not valid");
		return -EINVAL;
	}
	LOG_DBG("Configure resolution=%d", sequence->resolution);

	/* Enable the A/D converter */
	if (data->is_differential) {
		EADC_Open(eadc, EADC_CTL_DIFFEN_DIFFERENTIAL);
	} else {
		EADC_Open(eadc, EADC_CTL_DIFFEN_SINGLE_END);
	}

	data->buffer = sequence->buffer;
	data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t);

	/* Start ADC conversion */
	adc_context_start_read(&data->ctx, sequence);

	return adc_context_wait_for_completion(&data->ctx);
}

static int adc_numaker_read(const struct device *dev,
			    const struct adc_sequence *sequence)
{
	struct adc_numaker_data *data = dev->data;
	int err;

	adc_context_lock(&data->ctx, false, NULL);
	err = m_adc_numaker_start_read(dev, sequence);
	adc_context_release(&data->ctx, err);

	return err;
}

#ifdef CONFIG_ADC_ASYNC
static int adc_numaker_read_async(const struct device *dev,
				  const struct adc_sequence *sequence,
				  struct k_poll_signal *async)
{
	struct adc_numaker_data *data = dev->data;
	int err;

	adc_context_lock(&data->ctx, true, async);
	err = m_adc_numaker_start_read(dev, sequence);
	adc_context_release(&data->ctx, err);

	return err;
}
#endif

static const struct adc_driver_api adc_numaker_driver_api = {
	.channel_setup = adc_numaker_channel_setup,
	.read = adc_numaker_read,
#ifdef CONFIG_ADC_ASYNC
	.read_async = adc_numaker_read_async,
#endif
};

static int adc_numaker_init(const struct device *dev)
{
	const struct adc_numaker_config *cfg = dev->config;
	struct adc_numaker_data *data = dev->data;
	int err;
	struct numaker_scc_subsys scc_subsys;

	/* Validate this module's reset object */
	if (!device_is_ready(cfg->reset.dev)) {
		LOG_ERR("reset controller not ready");
		return -ENODEV;
	}

	data->dev = dev;

	SYS_UnlockReg();

	/* CLK controller */
	memset(&scc_subsys, 0x00, sizeof(scc_subsys));
	scc_subsys.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC;
	scc_subsys.pcc.clk_modidx = cfg->clk_modidx;
	scc_subsys.pcc.clk_src = cfg->clk_src;
	scc_subsys.pcc.clk_div = cfg->clk_div;

	/* Equivalent to CLK_EnableModuleClock() */
	err = clock_control_on(cfg->clk_dev, (clock_control_subsys_t)&scc_subsys);
	if (err != 0) {
		goto done;
	}
	/* Equivalent to CLK_SetModuleClock() */
	err = clock_control_configure(cfg->clk_dev, (clock_control_subsys_t)&scc_subsys, NULL);
	if (err != 0) {
		goto done;
	}

	err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
	if (err) {
		LOG_ERR("Failed to apply pinctrl state");
		goto done;
	}

	/* Reset EADC to default state, same as BSP's SYS_ResetModule(id_rst) */
	reset_line_toggle_dt(&cfg->reset);

	/* Enable NVIC */
	cfg->irq_config_func(dev);

	/* Init mutex of adc_context */
	adc_context_unlock_unconditionally(&data->ctx);

done:
	SYS_LockReg();
	return err;
}

#define ADC_NUMAKER_IRQ_CONFIG_FUNC(n)                                                       \
	static void adc_numaker_irq_config_func_##n(const struct device *dev)                \
	{                                                                                    \
		IRQ_CONNECT(DT_INST_IRQN(n),                                                 \
			    DT_INST_IRQ(n, priority),                                        \
			    adc_numaker_isr,                                                 \
			    DEVICE_DT_INST_GET(n), 0);                                       \
											     \
		irq_enable(DT_INST_IRQN(n));                                                 \
	}

#define ADC_NUMAKER_INIT(inst)						                     \
	PINCTRL_DT_INST_DEFINE(inst);                                                        \
	ADC_NUMAKER_IRQ_CONFIG_FUNC(inst)                                                    \
											     \
	static const struct adc_numaker_config adc_numaker_cfg_##inst = {                    \
		.eadc_base = (EADC_T *)DT_INST_REG_ADDR(inst),                               \
		.channel_cnt = DT_INST_PROP(inst, channels),                                 \
		.reset = RESET_DT_SPEC_INST_GET(inst),                                       \
		.clk_modidx = DT_INST_CLOCKS_CELL(inst, clock_module_index),                 \
		.clk_src = DT_INST_CLOCKS_CELL(inst, clock_source),                          \
		.clk_div = DT_INST_CLOCKS_CELL(inst, clock_divider),                         \
		.clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))),              \
		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                              \
		.irq_config_func = adc_numaker_irq_config_func_##inst,                       \
	};                                                                                   \
											     \
	static struct adc_numaker_data adc_numaker_data_##inst = {			     \
		ADC_CONTEXT_INIT_TIMER(adc_numaker_data_##inst, ctx),			     \
		ADC_CONTEXT_INIT_LOCK(adc_numaker_data_##inst, ctx),			     \
		ADC_CONTEXT_INIT_SYNC(adc_numaker_data_##inst, ctx),			     \
	};									             \
	DEVICE_DT_INST_DEFINE(inst,                                                          \
			      &adc_numaker_init, NULL,                                       \
			      &adc_numaker_data_##inst, &adc_numaker_cfg_##inst,             \
			      POST_KERNEL, CONFIG_ADC_INIT_PRIORITY,			     \
			      &adc_numaker_driver_api);

DT_INST_FOREACH_STATUS_OKAY(ADC_NUMAKER_INIT)
