/*
 * Copyright (c) 2017, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "qm_adc.h"
#include "clk.h"
#include <string.h>

/* FIFO_INTERRUPT_THRESHOLD is used by qm_adc_irq_convert to set the threshold
 * at which the FIFO will trigger an interrupt. */
#define FIFO_INTERRUPT_THRESHOLD (16)

#define QM_ADC_CHAN_SEQ_MAX (32)

/* ADC commands. */
#define QM_ADC_CMD_START_SINGLE (0)
#define QM_ADC_CMD_START_CONT (1)
#define QM_ADC_CMD_RESET_CAL (2)
#define QM_ADC_CMD_START_CAL (3)
#define QM_ADC_CMD_LOAD_CAL (4)
#define QM_ADC_CMD_STOP_CONT (5)

static uint8_t sample_window[QM_ADC_NUM];
static qm_adc_resolution_t resolution[QM_ADC_NUM];

static qm_adc_xfer_t *irq_xfer[QM_ADC_NUM];
static uint32_t count[QM_ADC_NUM];
static bool dummy_conversion = false;

/* Callbacks for mode change and calibration. */
static void (*mode_callback[QM_ADC_NUM])(void *data, int error,
					 qm_adc_status_t status,
					 qm_adc_cb_source_t source);
static void (*cal_callback[QM_ADC_NUM])(void *data, int error,
					qm_adc_status_t status,
					qm_adc_cb_source_t source);
static void *mode_callback_data[QM_ADC_NUM];
static void *cal_callback_data[QM_ADC_NUM];

/* ISR handler for command/calibration complete. */
static void qm_adc_isr_handler(const qm_adc_t adc)
{
	uint32_t int_status = 0;
	uint32_t i, samples_to_read;

	int_status = QM_ADC[adc].adc_intr_status;

	/* FIFO overrun interrupt. */
	if (int_status & QM_ADC_INTR_STATUS_FO) {
		/* Stop the transfer. */
		QM_ADC[adc].adc_cmd = QM_ADC_CMD_STOP_CONT;
		/* Disable all interrupts. */
		QM_ADC[adc].adc_intr_enable = 0;
		/* Call the user callback. */
		if (irq_xfer[adc]->callback) {
			irq_xfer[adc]->callback(irq_xfer[adc]->callback_data,
						-EIO, QM_ADC_OVERFLOW,
						QM_ADC_TRANSFER);
		}
	}

	/* Continuous mode command complete interrupt. */
	if (int_status & QM_ADC_INTR_STATUS_CONT_CC) {
		/* Clear the interrupt. */
		QM_ADC[adc].adc_intr_status &= QM_ADC_INTR_STATUS_CONT_CC;

		/* Calculate the number of samples to read. */
		samples_to_read = QM_ADC[adc].adc_fifo_count;
		if (samples_to_read >
		    (irq_xfer[adc]->samples_len - count[adc])) {
			samples_to_read =
			    irq_xfer[adc]->samples_len - count[adc];
		}

		/* Copy data out of FIFO. The sample must be shifted right by
		 * 2, 4 or 6 bits for 10, 8 and 6 bit resolution respectively
		 * to get the correct value. */
		for (i = 0; i < samples_to_read; i++) {
			irq_xfer[adc]->samples[count[adc]] =
			    (QM_ADC[adc].adc_sample >>
			     (2 * (3 - resolution[adc])));
			count[adc]++;
		}

		/* Check if we have the requested number of samples, stop the
		 * conversion and call the user callback function. */
		if (count[adc] == irq_xfer[adc]->samples_len) {
			/* Stop the transfer. */
			QM_ADC[adc].adc_cmd = QM_ADC_CMD_STOP_CONT;
			/* Disable all interrupts. */
			QM_ADC[adc].adc_intr_enable = 0;
			/* Call the user callback. */
			if (irq_xfer[adc]->callback) {
				irq_xfer[adc]->callback(
				    irq_xfer[adc]->callback_data, 0,
				    QM_ADC_COMPLETE, QM_ADC_TRANSFER);
			}
		}
	}

	/* The Command Complete interrupt is currently used to notify of the
	 * completion of a calibration command or a dummy conversion. */
	if ((int_status & QM_ADC_INTR_STATUS_CC) && (!dummy_conversion)) {
		/* Disable and clear the Command Complete interrupt */
		QM_ADC[adc].adc_intr_enable &= ~QM_ADC_INTR_ENABLE_CC;
		QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

		/* Call the user callback if it is set. */
		if (cal_callback[adc]) {
			cal_callback[adc](irq_xfer[adc]->callback_data, 0,
					  QM_ADC_IDLE, QM_ADC_CAL_COMPLETE);
		}
	}

	/* This dummy conversion is needed when switching to normal mode or
	 * normal mode with calibration. */
	if ((int_status & QM_ADC_INTR_STATUS_CC) && (dummy_conversion)) {
		/* Flush the FIFO to get rid of the dummy values. */
		QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
		/* Disable and clear the Command Complete interrupt. */
		QM_ADC[adc].adc_intr_enable &= ~QM_ADC_INTR_ENABLE_CC;
		QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

		dummy_conversion = false;

		/* Call the user callback if it is set. */
		if (mode_callback[adc]) {
			mode_callback[adc](irq_xfer[adc]->callback_data, 0,
					   QM_ADC_IDLE, QM_ADC_MODE_CHANGED);
		}
	}
}

/* ISR handler for mode change. */
static void qm_adc_pwr_0_isr_handler(const qm_adc_t adc)
{
	/* Clear the interrupt. Note that this operates differently to the
	 * QM_ADC_INTR_STATUS regiseter because you have to write to the
	 * QM_ADC_OP_MODE register, Interrupt Enable bit to clear. */
	QM_ADC[adc].adc_op_mode &= ~QM_ADC_OP_MODE_IE;

	/* Perform a dummy conversion if we are transitioning to Normal Mode or
	 * Normal Mode With Calibration */
	if ((QM_ADC[adc].adc_op_mode & QM_ADC_OP_MODE_OM_MASK) >=
	    QM_ADC_MODE_NORM_CAL) {

		/* Set the first sequence register back to its default (ch 0) */
		QM_ADC[adc].adc_seq0 = QM_ADC_CAL_SEQ_TABLE_DEFAULT;
		/* Clear the command complete interrupt status field */
		QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

		dummy_conversion = true;

		/* Run a dummy conversion */
		QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_SINGLE);
	} else {
		/* Call the user callback function */
		if (mode_callback[adc]) {
			mode_callback[adc](irq_xfer[adc]->callback_data, 0,
					   QM_ADC_IDLE, QM_ADC_MODE_CHANGED);
		}
	}
}

/* ISR for ADC 0 Command/Calibration Complete. */
QM_ISR_DECLARE(qm_adc_0_cal_isr)
{
	qm_adc_isr_handler(QM_ADC_0);

	QM_ISR_EOI(QM_IRQ_ADC_0_CAL_INT_VECTOR);
}

/* ISR for ADC 0 Mode Change. */
QM_ISR_DECLARE(qm_adc_0_pwr_isr)
{
	qm_adc_pwr_0_isr_handler(QM_ADC_0);

	QM_ISR_EOI(QM_IRQ_ADC_0_PWR_0_VECTOR);
}

static void setup_seq_table(const qm_adc_t adc, qm_adc_xfer_t *xfer)
{
	uint32_t i, offset = 0;
	volatile uint32_t *reg_pointer = NULL;

	/* Loop over all of the channels to be added. */
	for (i = 0; i < xfer->ch_len; i++) {
		/* Get a pointer to the correct address. */
		reg_pointer = &QM_ADC[adc].adc_seq0 + (i / 4);
		/* Get the offset within the register */
		offset = ((i % 4) * 8);
		/* Clear the Last bit from all entries we will use. */
		*reg_pointer &= ~(1 << (offset + 7));
		/* Place the channel numnber into the sequence table. */
		*reg_pointer |= (xfer->ch[i] << offset);
	}

	if (reg_pointer) {
		/* Set the correct Last bit. */
		*reg_pointer |= (1 << (offset + 7));
	}
}

int qm_adc_calibrate(const qm_adc_t adc)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);

	/* Clear the command complete interrupt status field. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
	/* Start the calibration and wait for it to complete. */
	QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_CAL);
	while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
		;
	/* Clear the command complete interrupt status field again. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

	return 0;
}

int qm_adc_irq_calibrate(const qm_adc_t adc,
			 void (*callback)(void *data, int error,
					  qm_adc_status_t status,
					  qm_adc_cb_source_t source),
			 void *callback_data)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);

	/* Set the callback. */
	cal_callback[adc] = callback;
	cal_callback_data[adc] = callback_data;

	/* Clear and enable the command complete interrupt. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
	QM_ADC[adc].adc_intr_enable |= QM_ADC_INTR_ENABLE_CC;

	/* Start the calibration */
	QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_CAL);

	return 0;
}

int qm_adc_set_calibration(const qm_adc_t adc, const qm_adc_calibration_t cal)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(cal < 0x3F, -EINVAL);

	/* Clear the command complete interrupt status field. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

	/* Set the calibration data and wait for it to complete. */
	QM_ADC[adc].adc_cmd = ((cal << QM_ADC_CMD_CAL_DATA_OFFSET) |
			       QM_ADC_CMD_IE | QM_ADC_CMD_LOAD_CAL);
	while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
		;
	/* Clear the command complete interrupt status field again. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;

	return 0;
}

int qm_adc_get_calibration(const qm_adc_t adc, qm_adc_calibration_t *const cal)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(NULL != cal, -EINVAL);

	*cal = QM_ADC[adc].adc_calibration;

	return 0;
}

int qm_adc_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(mode <= QM_ADC_MODE_NORM_NO_CAL, -EINVAL);

	/* Issue mode change command and wait for it to complete. */
	QM_ADC[adc].adc_op_mode = mode;
	while ((QM_ADC[adc].adc_op_mode & QM_ADC_OP_MODE_OM_MASK) != mode)
		;

	/* Perform a dummy conversion if we are transitioning to Normal Mode. */
	if ((mode >= QM_ADC_MODE_NORM_CAL)) {
		/* Set the first sequence register back to its default. */
		QM_ADC[adc].adc_seq0 = QM_ADC_CAL_SEQ_TABLE_DEFAULT;

		/* Clear the command complete interrupt status field. */
		QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
		/* Run a dummy convert and wait for it to complete. */
		QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_SINGLE);
		while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
			;

		/* Flush the FIFO to get rid of the dummy values. */
		QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
		/* Clear the command complete interrupt status field. */
		QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
	}

	return 0;
}

int qm_adc_irq_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode,
			void (*callback)(void *data, int error,
					 qm_adc_status_t status,
					 qm_adc_cb_source_t source),
			void *callback_data)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(mode <= QM_ADC_MODE_NORM_NO_CAL, -EINVAL);

	/* Set the callback. */
	mode_callback[adc] = callback;
	mode_callback_data[adc] = callback_data;

	/* When transitioning to Normal Mode or Normal Mode With Calibration,
	 * enable command complete interrupt to perform a dummy conversion. */
	if ((mode >= QM_ADC_MODE_NORM_CAL)) {
		QM_ADC[adc].adc_intr_enable |= QM_ADC_INTR_ENABLE_CC;
	}

	/* Issue mode change command. Completion if this command is notified via
	 * the ADC Power interrupt source, which is serviced separately to the
	 * Command/Calibration Complete interrupt. */
	QM_ADC[adc].adc_op_mode = (QM_ADC_OP_MODE_IE | mode);

	return 0;
}

int qm_adc_set_config(const qm_adc_t adc, const qm_adc_config_t *const cfg)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(NULL != cfg, -EINVAL);
	QM_CHECK(cfg->resolution <= QM_ADC_RES_12_BITS, -EINVAL);
	/* Convert cfg->resolution to actual resolution (2x+6) and add 2 to get
	 * minimum value for window size. */
	QM_CHECK(cfg->window >= ((cfg->resolution * 2) + 8), -EINVAL);

	/* Set the sample window and resolution. */
	sample_window[adc] = cfg->window;
	resolution[adc] = cfg->resolution;

	return 0;
}

int qm_adc_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer,
		   qm_adc_status_t *const status)
{
	uint32_t i;

	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(NULL != xfer, -EINVAL);
	QM_CHECK(NULL != xfer->ch, -EINVAL);
	QM_CHECK(NULL != xfer->samples, -EINVAL);
	QM_CHECK(xfer->ch_len > 0, -EINVAL);
	QM_CHECK(xfer->ch_len <= QM_ADC_CHAN_SEQ_MAX, -EINVAL);
	QM_CHECK(xfer->samples_len > 0, -EINVAL);
	QM_CHECK(xfer->samples_len <= QM_ADC_FIFO_LEN, -EINVAL);

	/* Flush the FIFO. */
	QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;

	/* Populate the sample sequence table. */
	setup_seq_table(adc, xfer);

	/* Issue cmd: window & resolution, number of samples, command. */
	QM_ADC[adc].adc_cmd =
	    (sample_window[adc] << QM_ADC_CMD_SW_OFFSET |
	     resolution[adc] << QM_ADC_CMD_RESOLUTION_OFFSET |
	     ((xfer->samples_len - 1) << QM_ADC_CMD_NS_OFFSET) |
	     QM_ADC_CMD_START_SINGLE);

	/* Wait for fifo count to reach number of samples. */
	while (QM_ADC[adc].adc_fifo_count != xfer->samples_len)
		;

	if (status) {
		*status = QM_ADC_COMPLETE;
	}

	/* Read the value into the data structure. The sample must be shifted
	 * right by 2, 4 or 6 bits for 10, 8 and 6 bit resolution respectively
	 * to get the correct value. */
	for (i = 0; i < xfer->samples_len; i++) {
		xfer->samples[i] =
		    (QM_ADC[adc].adc_sample >> (2 * (3 - resolution[adc])));
	}

	return 0;
}

int qm_adc_irq_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer)
{
	QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
	QM_CHECK(NULL != xfer, -EINVAL);
	QM_CHECK(NULL != xfer->ch, -EINVAL);
	QM_CHECK(NULL != xfer->samples, -EINVAL);
	QM_CHECK(xfer->ch_len > 0, -EINVAL);
	QM_CHECK(xfer->ch_len <= QM_ADC_CHAN_SEQ_MAX, -EINVAL);
	QM_CHECK(xfer->samples_len > 0, -EINVAL);

	/* Reset the count and flush the FIFO. */
	count[adc] = 0;
	QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;

	/* Populate the sample sequence table. */
	setup_seq_table(adc, xfer);

	/* Copy the xfer struct so we can get access from the ISR. */
	irq_xfer[adc] = xfer;

	/* Clear all pending interrupts. */
	QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC |
				      QM_ADC_INTR_STATUS_FO |
				      QM_ADC_INTR_STATUS_CONT_CC;
	/* Enable the continuous command and fifo overrun interupts. */
	QM_ADC[adc].adc_intr_enable =
	    QM_ADC_INTR_ENABLE_FO | QM_ADC_INTR_ENABLE_CONT_CC;

	/* Issue cmd: window & resolution, number of samples, interrupt enable
	 * and start continuous coversion command. If xfer->samples_len is less
	 * than FIFO_INTERRUPT_THRESHOLD extra samples will be discarded in the
	 * ISR. */
	QM_ADC[adc].adc_cmd =
	    (sample_window[adc] << QM_ADC_CMD_SW_OFFSET |
	     resolution[adc] << QM_ADC_CMD_RESOLUTION_OFFSET |
	     ((FIFO_INTERRUPT_THRESHOLD - 1) << QM_ADC_CMD_NS_OFFSET) |
	     QM_ADC_CMD_IE | QM_ADC_CMD_START_CONT);

	return 0;
}
