/*
 * Copyright (c) 2021 ITE Corporation. All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_adc

#define LOG_LEVEL CONFIG_ADC_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(adc_ite_it8xxx2);

#include <drivers/adc.h>
#include <drivers/pinmux.h>
#include <soc.h>
#include <soc_dt.h>
#include <errno.h>
#include <assert.h>

#define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h"

/* ADC internal reference voltage (Unit:mV) */
#define IT8XXX2_ADC_VREF_VOL 3000
/* ADC channels disabled */
#define IT8XXX2_ADC_CHANNEL_DISABLED 0x1F
/* ADC sample time delay (Unit:us) */
#define IT8XXX2_ADC_SAMPLE_TIME_US 200
/* Wait next clock rising (Clock source 32.768K) */
#define IT8XXX2_WAIT_NEXT_CLOCK_TIME_US 31
/* ADC channels offset */
#define ADC_CHANNEL_SHIFT 5
#define ADC_CHANNEL_OFFSET(ch) ((ch)-CHIP_ADC_CH13-ADC_CHANNEL_SHIFT)

/* List of ADC channels. */
enum chip_adc_channel {
	CHIP_ADC_CH0 = 0,
	CHIP_ADC_CH1,
	CHIP_ADC_CH2,
	CHIP_ADC_CH3,
	CHIP_ADC_CH4,
	CHIP_ADC_CH5,
	CHIP_ADC_CH6,
	CHIP_ADC_CH7,
	CHIP_ADC_CH13,
	CHIP_ADC_CH14,
	CHIP_ADC_CH15,
	CHIP_ADC_CH16,
	CHIP_ADC_COUNT,
};

struct adc_it8xxx2_data {
	struct adc_context ctx;
	struct k_sem sem;
	/* Channel ID */
	uint32_t ch;
	/* Save ADC result to the buffer. */
	uint16_t *buffer;
	/*
	 * The sample buffer pointer should be prepared
	 * for writing of next sampling results.
	 */
	uint16_t *repeat_buffer;
};

/*
 * Structure adc_it8xxx2_cfg is about the setting of adc
 * this config will be used at initial time
 */
struct adc_it8xxx2_cfg {
	/* Pinmux control group */
	const struct device *pinctrls;
	/* GPIO pin */
	uint8_t pin;
	/* Alternate function */
	uint8_t alt_fun;
};

#define ADC_IT8XXX2_REG_BASE	\
	((struct adc_it8xxx2_regs *)(DT_INST_REG_ADDR(0)))

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

	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
		LOG_ERR("Selected ADC acquisition time is not valid");
		return -EINVAL;
	}

	/* Support channels 0~7 and 13~16 */
	if (!((channel_id >= 0 && channel_id <= 7) ||
	    (channel_id >= 13 && channel_id <= 16))) {
		LOG_ERR("Channel %d is not valid", channel_id);
		return -EINVAL;
	}

	/* Channels 13~16 should be shifted by 5 */
	if (channel_id > CHIP_ADC_CH7) {
		channel_id -= ADC_CHANNEL_SHIFT;
	}

	if (channel_cfg->gain != ADC_GAIN_1) {
		LOG_ERR("Invalid channel gain");
		return -EINVAL;
	}

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

	/* The channel is set to ADC alternate function */
	pinmux_pin_set(config[channel_id].pinctrls,
		       config[channel_id].pin,
		       config[channel_id].alt_fun);
	LOG_DBG("Channel setup succeeded!");
	return 0;
}

static void adc_disable_measurement(uint32_t ch)
{
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;

	if (ch <= CHIP_ADC_CH7) {
		/*
		 * Disable measurement.
		 * bit(4:0) = 0x1f : channel disable
		 */
		adc_regs->VCH0CTL = IT8XXX2_ADC_DATVAL |
			IT8XXX2_ADC_CHANNEL_DISABLED;
	} else {
		/*
		 * Channels 13~16 controller setting.
		 * bit7 = 1: End of conversion. New data is available in
		 *           VCHDATL/VCHDATM.
		 */
		adc_regs->adc_vchs_ctrl[ADC_CHANNEL_OFFSET(ch)].VCHCTL =
			IT8XXX2_ADC_DATVAL;
	}

	/* ADC module disable */
	adc_regs->ADCCFG &= ~IT8XXX2_ADC_ADCEN;

	/* disable adc interrupt */
	irq_disable(DT_INST_IRQN(0));
}

static int adc_data_valid(const struct device *dev)
{
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
	struct adc_it8xxx2_data *data = dev->data;

	return (data->ch <= CHIP_ADC_CH7) ?
		(adc_regs->VCH0CTL & IT8XXX2_ADC_DATVAL) :
		(adc_regs->ADCDVSTS2 & BIT(ADC_CHANNEL_OFFSET(data->ch)));
}

/* Get result for each ADC selected channel. */
static void adc_it8xxx2_get_sample(const struct device *dev)
{
	struct adc_it8xxx2_data *data = dev->data;
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;

	if (adc_data_valid(dev)) {
		if (data->ch <= CHIP_ADC_CH7) {
			/* Read adc raw data of msb and lsb */
			*data->buffer++ = adc_regs->VCH0DATM << 8 |
				adc_regs->VCH0DATL;
		} else {
			/* Read adc channels 13~16 raw data of msb and lsb */
			*data->buffer++ =
				adc_regs->adc_vchs_ctrl[ADC_CHANNEL_OFFSET(data->ch)].VCHDATM << 8 |
				adc_regs->adc_vchs_ctrl[ADC_CHANNEL_OFFSET(data->ch)].VCHDATL;
		}
	} else {
		LOG_WRN("ADC failed to read (regs=%x, ch=%d)",
			adc_regs->ADCDVSTS, data->ch);
	}

	adc_disable_measurement(data->ch);
}

static void adc_poll_valid_data(void)
{
	const struct device *dev = DEVICE_DT_INST_GET(0);
	int valid = 0;

	/*
	 * If the polling waits for a valid data longer than
	 * the sampling time limit, the program will return.
	 */
	for (int i = 0U; i < (IT8XXX2_ADC_SAMPLE_TIME_US /
	     IT8XXX2_WAIT_NEXT_CLOCK_TIME_US); i++) {
		/* Wait next clock time (1/32.768K~=30.5us) */
		k_busy_wait(IT8XXX2_WAIT_NEXT_CLOCK_TIME_US);

		if (adc_data_valid(dev)) {
			valid = 1;
			break;
		}
	}

	if (valid) {
		adc_it8xxx2_get_sample(dev);
	} else {
		LOG_ERR("Sampling timeout.");
		return;
	}
}

static void adc_enable_measurement(uint32_t ch)
{
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
	const struct device *dev = DEVICE_DT_INST_GET(0);
	struct adc_it8xxx2_data *data = dev->data;

	if (ch <= CHIP_ADC_CH7) {
		/* Select and enable a voltage channel input for measurement */
		adc_regs->VCH0CTL = (IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_INTDVEN) + ch;
	} else {
		/* Channels 13~16 controller setting */
		adc_regs->adc_vchs_ctrl[ADC_CHANNEL_OFFSET(ch)].VCHCTL =
			IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_INTDVEN | IT8XXX2_ADC_VCHEN;
	}

	/* ADC module enable */
	adc_regs->ADCCFG |= IT8XXX2_ADC_ADCEN;

	/*
	 * In the sampling process, it is possible to read multiple channels
	 * at a time. The ADC sampling of it8xxx2 needs to read each channel
	 * in sequence, so it needs to wait for an interrupt to read data in
	 * the loop through k_sem_take(). But k_timer_start() is used in the
	 * interval test in test_adc.c, so we need to use polling wait instead
	 * of k_sem_take() to wait, otherwise it will cause kernel panic.
	 *
	 * k_is_in_isr() can determine whether to use polling or k_sem_take()
	 * at present.
	 */
	if (k_is_in_isr()) {
		/* polling wait for a valid data */
		adc_poll_valid_data();
	} else {
		/* Enable adc interrupt */
		irq_enable(DT_INST_IRQN(0));
		/* Wait for an interrupt to read valid data. */
		k_sem_take(&data->sem, K_FOREVER);
	}
}

static int check_buffer_size(const struct adc_sequence *sequence,
			     uint8_t active_channels)
{
	size_t needed_buffer_size;

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

	if (sequence->buffer_size < needed_buffer_size) {
		LOG_ERR("Provided buffer is too small (%u/%u)",
				sequence->buffer_size, needed_buffer_size);
		return -ENOMEM;
	}

	return 0;
}

static int adc_it8xxx2_start_read(const struct device *dev,
				  const struct adc_sequence *sequence)
{
	struct adc_it8xxx2_data *data = dev->data;
	uint32_t channel_mask = sequence->channels;

	/* Channels 13~16 should be shifted to the right by 5 */
	if (channel_mask > BIT(CHIP_ADC_CH7)) {
		channel_mask >>= ADC_CHANNEL_SHIFT;
	}

	if (!channel_mask || channel_mask & ~BIT_MASK(CHIP_ADC_COUNT)) {
		LOG_ERR("Invalid selection of channels");
		return -EINVAL;
	}

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

	data->buffer = sequence->buffer;

	adc_context_start_read(&data->ctx, sequence);

	return adc_context_wait_for_completion(&data->ctx);
}

static void adc_context_start_sampling(struct adc_context *ctx)
{
	struct adc_it8xxx2_data *data =
		CONTAINER_OF(ctx, struct adc_it8xxx2_data, ctx);
	uint32_t channels = ctx->sequence.channels;
	uint8_t channel_count = 0;

	data->repeat_buffer = data->buffer;

	/*
	 * The ADC sampling of it8xxx2 needs to read each channel
	 * in sequence.
	 */
	while (channels) {
		data->ch = find_lsb_set(channels) - 1;
		channels &= ~BIT(data->ch);

		adc_enable_measurement(data->ch);

		channel_count++;
	}

	if (check_buffer_size(&ctx->sequence, channel_count)) {
		return;
	}

	adc_context_on_sampling_done(&data->ctx, DEVICE_DT_INST_GET(0));
}

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

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

	return err;
}

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

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

	return err;
}
#endif /* CONFIG_ADC_ASYNC */

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

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

static void adc_it8xxx2_isr(const struct device *dev)
{
	struct adc_it8xxx2_data *data = dev->data;

	LOG_DBG("ADC ISR triggered.");

	adc_it8xxx2_get_sample(dev);

	k_sem_give(&data->sem);
}

static const struct adc_driver_api api_it8xxx2_driver_api = {
	.channel_setup = adc_it8xxx2_channel_setup,
	.read = adc_it8xxx2_read,
#ifdef CONFIG_ADC_ASYNC
	.read_async = adc_it8xxx2_read_async,
#endif
	.ref_internal = IT8XXX2_ADC_VREF_VOL,
};

/*
 * ADC analog accuracy initialization (only once after VSTBY power on)
 *
 * Write 1 to this bit and write 0 to this bit immediately once and
 * only once during the firmware initialization and do not write 1 again
 * after initialization since IT83xx takes much power consumption
 * if this bit is set as 1
 */
static void adc_accuracy_initialization(void)
{
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;

	/* Start adc accuracy initialization */
	adc_regs->ADCSTS |= IT8XXX2_ADC_AINITB;
	/* Enable automatic HW calibration. */
	adc_regs->KDCTL |= IT8XXX2_ADC_AHCE;
	/* Stop adc accuracy initialization */
	adc_regs->ADCSTS &= ~IT8XXX2_ADC_AINITB;
}

static int adc_it8xxx2_init(const struct device *dev)
{
	struct adc_it8xxx2_data *data = dev->data;
	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;

	/* ADC analog accuracy initialization */
	adc_accuracy_initialization();

	/*
	 * The ADC channel conversion time is 30.8*(SCLKDIV+1) us.
	 * (Current setting is 61.6us)
	 *
	 * NOTE: A sample time delay (60us) also need to be included in
	 * conversion time, so the final result is ~= 121.6us.
	 */
	adc_regs->ADCSTS &= ~IT8XXX2_ADC_ADCCTS1;
	adc_regs->ADCCFG &= ~IT8XXX2_ADC_ADCCTS0;
	/*
	 * bit[5-0]@ADCCTL : SCLKDIV
	 * SCLKDIV has to be equal to or greater than 1h;
	 */
	adc_regs->ADCCTL = 1;
	/*
	 * Enable this bit, and data of VCHxDATL/VCHxDATM will be
	 * kept until data valid is cleared.
	 */
	adc_regs->ADCGCR |= IT8XXX2_ADC_DBKEN;

	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
		    adc_it8xxx2_isr, DEVICE_DT_INST_GET(0), 0);

	k_sem_init(&data->sem, 0, 1);
	adc_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static struct adc_it8xxx2_data adc_it8xxx2_data_0 = {
		ADC_CONTEXT_INIT_TIMER(adc_it8xxx2_data_0, ctx),
		ADC_CONTEXT_INIT_LOCK(adc_it8xxx2_data_0, ctx),
		ADC_CONTEXT_INIT_SYNC(adc_it8xxx2_data_0, ctx),
};

static const struct adc_it8xxx2_cfg adc_it8xxx2_cfg_0[CHIP_ADC_COUNT] =
	IT8XXX2_DT_ALT_ITEMS_LIST(0);

DEVICE_DT_INST_DEFINE(0, adc_it8xxx2_init,
		      NULL,
		      &adc_it8xxx2_data_0,
		      &adc_it8xxx2_cfg_0, PRE_KERNEL_1,
		      CONFIG_ADC_INIT_PRIORITY,
		      &api_it8xxx2_driver_api);
