/*
 * Copyright (c) 2019 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_adc

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

#include <drivers/adc.h>
#include <soc.h>
#include <errno.h>

#define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h"

#define XEC_ADC_VREF_ANALOG 3300

/* ADC Control Register */
#define XEC_ADC_CTRL_SINGLE_DONE_STATUS		BIT(7)
#define XEC_ADC_CTRL_REPEAT_DONE_STATUS		BIT(6)
#define XER_ADC_CTRL_SOFT_RESET			BIT(4)
#define XEC_ADC_CTRL_POWER_SAVER_DIS		BIT(3)
#define XEC_ADC_CTRL_START_REPEAT		BIT(2)
#define XEC_ADC_CTRL_START_SINGLE		BIT(1)
#define XEC_ADC_CTRL_ACTIVATE			BIT(0)

struct adc_xec_data {
	struct adc_context ctx;
	uint16_t *buffer;
	uint16_t *repeat_buffer;
};

struct adc_xec_regs {
	uint32_t control_reg;
	uint32_t delay_reg;
	uint32_t status_reg;
	uint32_t single_reg;
	uint32_t repeat_reg;
	uint32_t channel_read_reg[8];
	uint32_t unused[18];
	uint32_t config_reg;
	uint32_t vref_channel_reg;
	uint32_t vref_control_reg;
	uint32_t sar_control_reg;
};

#define ADC_XEC_REG_BASE						\
	((struct adc_xec_regs *)(DT_INST_REG_ADDR(0)))

static void adc_context_start_sampling(struct adc_context *ctx)
{
	struct adc_xec_data *data = CONTAINER_OF(ctx, struct adc_xec_data, ctx);
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;

	data->repeat_buffer = data->buffer;

	adc_regs->single_reg = ctx->sequence.channels;
	adc_regs->control_reg |= XEC_ADC_CTRL_START_SINGLE;
}

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

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

static int adc_xec_channel_setup(const struct device *dev,
				 const struct adc_channel_cfg *channel_cfg)
{
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;
	uint32_t reg;

	ARG_UNUSED(dev);

	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
		return -EINVAL;
	}

	if (channel_cfg->channel_id >= MCHP_ADC_MAX_CHAN) {
		return -EINVAL;
	}

	if (channel_cfg->gain != ADC_GAIN_1) {
		return -EINVAL;
	}

	/* Setup VREF */
	reg = adc_regs->vref_channel_reg;
	reg &= ~MCHP_ADC_CH_VREF_SEL_MASK(channel_cfg->channel_id);

	if (channel_cfg->reference == ADC_REF_INTERNAL) {
		reg |= MCHP_ADC_CH_VREF_SEL_PAD(channel_cfg->channel_id);
	} else if (channel_cfg->reference == ADC_REF_EXTERNAL0) {
		reg |= MCHP_ADC_CH_VREF_SEL_GPIO(channel_cfg->channel_id);
	} else {
		return -EINVAL;
	}

	adc_regs->vref_channel_reg = reg;

	/* Differential mode? */
	reg = adc_regs->sar_control_reg;
	reg &= ~BIT(MCHP_ADC_SAR_CTRL_SELDIFF_POS);
	if (channel_cfg->differential != 0) {
		reg |= MCHP_ADC_SAR_CTRL_SELDIFF_EN;
	}
	adc_regs->sar_control_reg = reg;

	return 0;
}

static bool adc_xec_validate_buffer_size(const struct adc_sequence *sequence)
{
	int chan_count = 0;
	size_t buff_need;
	uint32_t chan_mask;

	for (chan_mask = 0x80; chan_mask != 0; chan_mask >>= 1) {
		if (chan_mask & sequence->channels) {
			chan_count++;
		}
	}

	buff_need = chan_count * sizeof(uint16_t);

	if (sequence->options) {
		buff_need *= 1 + sequence->options->extra_samplings;
	}

	if (buff_need > sequence->buffer_size) {
		return false;
	}

	return true;
}

static int adc_xec_start_read(const struct device *dev,
			      const struct adc_sequence *sequence)
{
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;
	struct adc_xec_data *data = dev->data;
	uint32_t reg;

	if (sequence->channels & ~BIT_MASK(MCHP_ADC_MAX_CHAN)) {
		LOG_ERR("Incorrect channels, bitmask 0x%x", sequence->channels);
		return -EINVAL;
	}

	if (sequence->channels == 0UL) {
		LOG_ERR("No channel selected");
		return -EINVAL;
	}

	if (!adc_xec_validate_buffer_size(sequence)) {
		LOG_ERR("Incorrect buffer size");
		return -ENOMEM;
	}

	/* Setup ADC resolution */
	reg = adc_regs->sar_control_reg;
	reg &= ~(MCHP_ADC_SAR_CTRL_RES_MASK |
		 (1 << MCHP_ADC_SAR_CTRL_SHIFTD_POS));

	if (sequence->resolution == 12) {
		reg |= MCHP_ADC_SAR_CTRL_RES_12_BITS;
	} else if (sequence->resolution == 10) {
		reg |= MCHP_ADC_SAR_CTRL_RES_10_BITS;
		reg |= MCHP_ADC_SAR_CTRL_SHIFTD_EN;
	} else {
		return -EINVAL;
	}

	adc_regs->sar_control_reg = reg;

	data->buffer = sequence->buffer;

	adc_context_start_read(&data->ctx, sequence);

	return adc_context_wait_for_completion(&data->ctx);
}

static int adc_xec_read(const struct device *dev,
			const struct adc_sequence *sequence)
{
	struct adc_xec_data *data = dev->data;
	int error;

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

	return error;
}

#if defined(CONFIG_ADC_ASYNC)
static int adc_xec_read_async(const struct device *dev,
			      const struct adc_sequence *sequence,
			      struct k_poll_signal *async)
{
	struct adc_xec_data *data = dev->data;
	int error;

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

	return error;
}
#endif /* CONFIG_ADC_ASYNC */

static void xec_adc_get_sample(const struct device *dev)
{
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;
	struct adc_xec_data *data = dev->data;
	uint32_t idx;
	uint32_t channels = adc_regs->status_reg;
	uint32_t ch_status = channels;
	uint32_t bit;

	/*
	 * Using the enabled channel bit set, from
	 * lowest channel number to highest, find out
	 * which channel is enabled and copy the ADC
	 * values from hardware registers to the data
	 * buffer.
	 */
	bit = find_lsb_set(channels);
	while (bit != 0) {
		idx = bit - 1;

		*data->buffer = (uint16_t)adc_regs->channel_read_reg[idx];
		data->buffer++;

		channels &= ~BIT(idx);
		bit = find_lsb_set(channels);
	}

	/* Clear the status register */
	adc_regs->status_reg = ch_status;
}

static void adc_xec_isr(const struct device *dev)
{
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;
	struct adc_xec_data *data = dev->data;
	uint32_t reg;

	/* Clear START_SINGLE bit and clear SINGLE_DONE_STATUS */
	reg = adc_regs->control_reg;
	reg &= ~XEC_ADC_CTRL_START_SINGLE;
	reg |= XEC_ADC_CTRL_SINGLE_DONE_STATUS;
	adc_regs->control_reg = reg;

	/* Also clear GIRQ source status bit */
	MCHP_GIRQ_SRC(MCHP_ADC_GIRQ) = MCHP_ADC_SNG_DONE_GIRQ_VAL;

	xec_adc_get_sample(dev);

	adc_context_on_sampling_done(&data->ctx, dev);

	LOG_DBG("ADC ISR triggered.");
}

struct adc_driver_api adc_xec_api = {
	.channel_setup = adc_xec_channel_setup,
	.read = adc_xec_read,
#if defined(CONFIG_ADC_ASYNC)
	.read_async = adc_xec_read_async,
#endif
	.ref_internal = XEC_ADC_VREF_ANALOG,
};

/* ADC Config Register */
#define XEC_ADC_CFG_CLK_VAL(clk_time)	(		\
	(clk_time << MCHP_ADC_CFG_CLK_LO_TIME_POS) |	\
	(clk_time << MCHP_ADC_CFG_CLK_HI_TIME_POS))

static int adc_xec_init(const struct device *dev)
{
	struct adc_xec_regs *adc_regs = ADC_XEC_REG_BASE;
	struct adc_xec_data *data = dev->data;

	adc_regs->config_reg = XEC_ADC_CFG_CLK_VAL(DT_INST_PROP(0, clktime));

	adc_regs->control_reg =  XEC_ADC_CTRL_ACTIVATE
		| XEC_ADC_CTRL_POWER_SAVER_DIS
		| XEC_ADC_CTRL_SINGLE_DONE_STATUS
		| XEC_ADC_CTRL_REPEAT_DONE_STATUS;

	MCHP_GIRQ_SRC(MCHP_ADC_GIRQ) = MCHP_ADC_SNG_DONE_GIRQ_VAL;
	MCHP_GIRQ_ENSET(MCHP_ADC_GIRQ) = MCHP_ADC_SNG_DONE_GIRQ_VAL;

	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    adc_xec_isr, DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));

	adc_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static struct adc_xec_data adc_xec_dev_data_0 = {
	ADC_CONTEXT_INIT_TIMER(adc_xec_dev_data_0, ctx),
	ADC_CONTEXT_INIT_LOCK(adc_xec_dev_data_0, ctx),
	ADC_CONTEXT_INIT_SYNC(adc_xec_dev_data_0, ctx),
};

DEVICE_DT_INST_DEFINE(0, adc_xec_init, NULL,
		    &adc_xec_dev_data_0, NULL,
		    PRE_KERNEL_1, CONFIG_ADC_INIT_PRIORITY,
		    &adc_xec_api);
