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

#define DT_DRV_COMPAT nuvoton_npcx_adc

#include <assert.h>
#include <drivers/adc.h>
#include <drivers/clock_control.h>
#include <kernel.h>
#include <soc.h>

#define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h"

#include <logging/log.h>
LOG_MODULE_REGISTER(adc_npcx, CONFIG_ADC_LOG_LEVEL);

/* ADC speed/delay values during initialization */
#define ADC_REGULAR_DLY_VAL	0x03
#define ADC_REGULAR_ADCCNF2_VAL	0x8B07
#define ADC_REGULAR_GENDLY_VAL	0x0100
#define ADC_REGULAR_MEAST_VAL	0x0001

/* ADC channel number */
#define NPCX_ADC_CH_COUNT DT_INST_NUM_PINCTRLS_BY_IDX(0, 0)

/* ADC targeted operating frequency (2MHz) */
#define NPCX_ADC_CLK 2000000

/* ADC internal reference voltage (Unit:mV) */
#define NPCX_ADC_VREF_VOL 2816

/* ADC conversion mode */
#define NPCX_ADC_CHN_CONVERSION_MODE	0
#define NPCX_ADC_SCAN_CONVERSION_MODE	1

/* Device config */
struct adc_npcx_config {
	/* adc controller base address */
	uintptr_t base;
	/* clock configuration */
	struct npcx_clk_cfg clk_cfg;
	/* pinmux configuration */
	const struct npcx_alt *alts_list;
};

/* Driver data */
struct adc_npcx_data {
	/* Input clock for ADC converter */
	uint32_t input_clk;
	/* mutex of ADC channels */
	struct adc_context ctx;
	/*
	 * Bit-mask indicating the channels to be included in each sampling
	 * of this sequence.
	 */
	uint16_t channels;
	/* ADC Device pointer used in api functions */
	const struct device *adc_dev;
	uint16_t *buffer;
	uint16_t *repeat_buffer;
	/* end pointer of buffer to ensure enough space for storing ADC data. */
	uint16_t *buf_end;
};

/* Driver convenience defines */
#define DRV_CONFIG(dev) ((const struct adc_npcx_config *)(dev)->config)

#define DRV_DATA(dev) ((struct adc_npcx_data *)(dev)->data)

#define HAL_INSTANCE(dev) (struct adc_reg *)(DRV_CONFIG(dev)->base)

/* ADC local functions */
static void adc_npcx_isr(void *arg)
{
	struct adc_npcx_data *const data = DRV_DATA((const struct device *)arg);
	struct adc_reg *const inst = HAL_INSTANCE((const struct device *)arg);
	uint16_t status = inst->ADCSTS;
	uint16_t result, channel;

	/* Clear status pending bits first */
	inst->ADCSTS = status;
	LOG_DBG("%s: status is %04X\n", __func__, status);

	/* Is end of conversion cycle event? ie. Scan conversion is done. */
	if (IS_BIT_SET(status, NPCX_ADCSTS_EOCCEV)) {
		/* Stop conversion for scan conversion mode */
		inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP);

		/* Get result for each ADC selected channel */
		while (data->channels) {
			channel = find_lsb_set(data->channels) - 1;
			result = GET_FIELD(inst->CHNDAT[channel],
					NPCX_CHNDAT_CHDAT_FIELD);
			/*
			 * Save ADC result and adc_npcx_validate_buffer_size()
			 * already ensures that the buffer has enough space for
			 * storing result.
			 */
			if (data->buffer < data->buf_end) {
				*data->buffer++ = result;
			}
			data->channels &= ~BIT(channel);
		}

		/* Turn off ADC and inform sampling is done */
		inst->ADCCNF &= ~(BIT(NPCX_ADCCNF_ADCEN));
		adc_context_on_sampling_done(&data->ctx, data->adc_dev);
	}
}

/*
 * Validate the buffer size with adc channels mask. If it is lower than what
 * we need return -ENOSPC.
 */
static int adc_npcx_validate_buffer_size(const struct device *dev,
					const struct adc_sequence *sequence)
{
	uint8_t channels = 0;
	uint32_t mask;
	size_t needed;

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

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

	if (sequence->buffer_size < needed) {
		return -ENOSPC;
	}

	return 0;
}

static void adc_npcx_start_scan(const struct device *dev)
{
	struct adc_npcx_data *const data = DRV_DATA(dev);
	struct adc_reg *const inst = HAL_INSTANCE(dev);

	/* Turn on ADC first */
	inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCEN);

	/* Update selected channels in scan mode by channels mask */
	inst->ADCCS = data->channels;

	/* Select 'Scan' Conversion mode. */
	SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD,
			NPCX_ADC_SCAN_CONVERSION_MODE);

	/* Select 'One-Shot' Repetitive mode */
	inst->ADCCNF |= BIT(NPCX_ADCCNF_INTECEN);

	/* Start conversion */
	inst->ADCCNF |= BIT(NPCX_ADCCNF_START);

	LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS are (%04X,%04X)\n",
			inst->ADCCNF, inst->ADCCS);
}

static int adc_npcx_start_read(const struct device *dev,
					const struct adc_sequence *sequence)
{
	struct adc_npcx_data *const data = DRV_DATA(dev);
	int error = 0;

	if (!sequence->channels ||
	    (sequence->channels & ~BIT_MASK(NPCX_ADC_CH_COUNT))) {
		LOG_ERR("Invalid ADC channels");
		return -EINVAL;
	}

	/* Fixed 10 bit resolution of npcx ADC */
	if (sequence->resolution != 10) {
		LOG_ERR("Unfixed 10 bit ADC resolution");
		return -ENOTSUP;
	}

	error = adc_npcx_validate_buffer_size(dev, sequence);
	if (error) {
		LOG_ERR("ADC buffer size too small");
		return error;
	}

	/* Save ADC sequence sampling buffer and its end pointer address */
	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);
	error = adc_context_wait_for_completion(&data->ctx);

	return error;
}

/* ADC api functions */
static void adc_context_start_sampling(struct adc_context *ctx)
{
	struct adc_npcx_data *const data =
		CONTAINER_OF(ctx, struct adc_npcx_data, ctx);

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

	/* Start ADC scan conversion */
	adc_npcx_start_scan(data->adc_dev);
}

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

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

static int adc_npcx_channel_setup(const struct device *dev,
				 const struct adc_channel_cfg *channel_cfg)
{
	const struct adc_npcx_config *const config = DRV_CONFIG(dev);
	uint8_t channel_id = channel_cfg->channel_id;

	if (channel_id >= NPCX_ADC_CH_COUNT) {
		LOG_ERR("Invalid channel %d", channel_id);
		return -EINVAL;
	}

	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
		LOG_ERR("Unsupported channel acquisition time");
		return -ENOTSUP;
	}

	if (channel_cfg->differential) {
		LOG_ERR("Differential channels are not supported");
		return -ENOTSUP;
	}

	if (channel_cfg->gain != ADC_GAIN_1) {
		LOG_ERR("Unsupported channel gain %d", channel_cfg->gain);
		return -ENOTSUP;
	}

	if (channel_cfg->reference != ADC_REF_INTERNAL) {
		LOG_ERR("Unsupported channel reference");
		return -ENOTSUP;
	}

	/* Configure pin-mux for ADC channel */
	npcx_pinctrl_mux_configure(config->alts_list + channel_cfg->channel_id,
			1, 1);
	LOG_DBG("ADC channel %d, alts(%d,%d)", channel_cfg->channel_id,
			config->alts_list[channel_cfg->channel_id].group,
			config->alts_list[channel_cfg->channel_id].bit);

	return 0;
}

static int adc_npcx_read(const struct device *dev,
			const struct adc_sequence *sequence)
{
	struct adc_npcx_data *const data = DRV_DATA(dev);
	int error;

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

	return error;
}

#if defined(CONFIG_ADC_ASYNC)
static int adc_npcx_read_async(const struct device *dev,
			      const struct adc_sequence *sequence,
			      struct k_poll_signal *async)
{
	struct adc_npcx_data *const data = DRV_DATA(dev);
	int error;

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

	return error;
}
#endif /* CONFIG_ADC_ASYNC */

/* ADC driver registration */
static const struct adc_driver_api adc_npcx_driver_api = {
	.channel_setup = adc_npcx_channel_setup,
	.read = adc_npcx_read,
#if defined(CONFIG_ADC_ASYNC)
	.read_async = adc_npcx_read_async,
#endif
	.ref_internal = NPCX_ADC_VREF_VOL,
};

static int adc_npcx_init(const struct device *dev);

static const struct npcx_alt adc_alts[] = NPCX_DT_ALT_ITEMS_LIST(0);

static const struct adc_npcx_config adc_npcx_cfg_0 = {
	.base = DT_INST_REG_ADDR(0),
	.clk_cfg = NPCX_DT_CLK_CFG_ITEM(0),
	.alts_list = adc_alts,
};

static struct adc_npcx_data adc_npcx_data_0 = {
	ADC_CONTEXT_INIT_TIMER(adc_npcx_data_0, ctx),
	ADC_CONTEXT_INIT_LOCK(adc_npcx_data_0, ctx),
	ADC_CONTEXT_INIT_SYNC(adc_npcx_data_0, ctx),
};

DEVICE_DT_INST_DEFINE(0,
		    adc_npcx_init, NULL,
		    &adc_npcx_data_0, &adc_npcx_cfg_0,
		    PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		    &adc_npcx_driver_api);

static int adc_npcx_init(const struct device *dev)
{
	const struct adc_npcx_config *const config = DRV_CONFIG(dev);
	struct adc_npcx_data *const data = DRV_DATA(dev);
	struct adc_reg *const inst = HAL_INSTANCE(dev);
	const struct device *const clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
	int prescaler = 0, ret;

	/* Save ADC device in data */
	data->adc_dev = dev;

	/* Turn on device clock first and get source clock freq. */
	ret = clock_control_on(clk_dev, (clock_control_subsys_t *)
							&config->clk_cfg);
	if (ret < 0) {
		LOG_ERR("Turn on ADC clock fail %d", ret);
		return ret;
	}

	ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t *)
			&config->clk_cfg, &data->input_clk);
	if (ret < 0) {
		LOG_ERR("Get ADC clock rate error %d", ret);
		return ret;
	}

	/* Configure the ADC clock */
	prescaler = ceiling_fraction(data->input_clk, NPCX_ADC_CLK);
	if (prescaler > 0x40)
		prescaler = 0x40;

	/* Set Core Clock Division Factor in order to obtain the ADC clock */
	SET_FIELD(inst->ATCTL, NPCX_ATCTL_SCLKDIV_FIELD, prescaler - 1);

	/* Set regular ADC delay */
	SET_FIELD(inst->ATCTL, NPCX_ATCTL_DLY_FIELD, ADC_REGULAR_DLY_VAL);

	/* Set ADC speed sequentially */
	inst->ADCCNF2 = ADC_REGULAR_ADCCNF2_VAL;
	inst->GENDLY = ADC_REGULAR_GENDLY_VAL;
	inst->MEAST = ADC_REGULAR_MEAST_VAL;

	/* Configure ADC interrupt and enable it */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), adc_npcx_isr,
			    DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));

	/* Initialize mutex of ADC channels */
	adc_context_unlock_unconditionally(&data->ctx);

	return 0;
}
BUILD_ASSERT(ARRAY_SIZE(adc_alts) == NPCX_ADC_CH_COUNT,
	"The number of ADC channels and pin-mux configurations don't match!");
