ite: drivers/adc: it8xxx2: fix adc driver flow

This commit fixes the ADC driver flow. And add internal
reference voltage to ADC driver API. And correct the
data buffer that only need to store raw data.

Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
diff --git a/drivers/adc/adc_ite_it8xxx2.c b/drivers/adc/adc_ite_it8xxx2.c
index a505410..41b635a 100644
--- a/drivers/adc/adc_ite_it8xxx2.c
+++ b/drivers/adc/adc_ite_it8xxx2.c
@@ -11,6 +11,7 @@
 LOG_MODULE_REGISTER(adc_ite_it8xxx2);
 
 #include <drivers/adc.h>
+#include <drivers/pinmux.h>
 #include <soc.h>
 #include <errno.h>
 #include <assert.h>
@@ -20,27 +21,10 @@
 
 #define DEV_DATA(dev) ((struct adc_it8xxx2_data * const)(dev)->data)
 
-/* Data structure to define ADC channel control registers. */
-struct adc_ctrl_t {
-	/* The voltage channel control register. */
-	volatile uint8_t *adc_ctrl;
-	/* The voltage channel data buffer MSB. */
-	volatile uint8_t *adc_datm;
-	/* The voltage channel data buffer LSB. */
-	volatile uint8_t *adc_datl;
-};
-
-/* Data structure of ADC channel control registers. */
-static const struct adc_ctrl_t adc_ctrl_regs[] = {
-	{&IT83XX_ADC_VCH0CTL, &IT83XX_ADC_VCH0DATM, &IT83XX_ADC_VCH0DATL},
-	{&IT83XX_ADC_VCH1CTL, &IT83XX_ADC_VCH1DATM, &IT83XX_ADC_VCH1DATL},
-	{&IT83XX_ADC_VCH2CTL, &IT83XX_ADC_VCH2DATM, &IT83XX_ADC_VCH2DATL},
-	{&IT83XX_ADC_VCH3CTL, &IT83XX_ADC_VCH3DATM, &IT83XX_ADC_VCH3DATL},
-	{&IT83XX_ADC_VCH4CTL, &IT83XX_ADC_VCH4DATM, &IT83XX_ADC_VCH4DATL},
-	{&IT83XX_ADC_VCH5CTL, &IT83XX_ADC_VCH5DATM, &IT83XX_ADC_VCH5DATL},
-	{&IT83XX_ADC_VCH6CTL, &IT83XX_ADC_VCH6DATM, &IT83XX_ADC_VCH6DATL},
-	{&IT83XX_ADC_VCH7CTL, &IT83XX_ADC_VCH7DATM, &IT83XX_ADC_VCH7DATL},
-};
+/* ADC internal reference voltage (Unit:mV) */
+#define IT8XXX2_ADC_VREF_VOL 3000
+/* ADC channels disabled */
+#define IT8XXX2_ADC_CHANNEL_DISABLED 0x1F
 
 /* List of ADC channels. */
 enum chip_adc_channel {
@@ -57,6 +41,8 @@
 
 struct adc_it8xxx2_data {
 	struct adc_context ctx;
+	/* Channel ID */
+	uint32_t ch;
 	/* Save ADC result to the buffer. */
 	uint16_t *buffer;
 	/*
@@ -66,10 +52,14 @@
 	uint16_t *repeat_buffer;
 };
 
+#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_channel_cfg *channel_cfg)
 {
 	ARG_UNUSED(dev);
+	const struct device *porti = DEVICE_DT_GET(DT_NODELABEL(pinmuxi));
 
 	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
 		LOG_ERR("Selected ADC acquisition time is not valid");
@@ -91,36 +81,41 @@
 		return -EINVAL;
 	}
 
-	if (channel_cfg->channel_id < CHIP_ADC_CH4) {
-		/* For channel 0 ~ 3 control register. */
-		*adc_ctrl_regs[channel_cfg->channel_id].adc_ctrl =
-			(IT83XX_ADC_DATVAL | IT83XX_ADC_INTDVEN) +
-			channel_cfg->channel_id;
-	} else {
-		/* For channel 4 ~ 7 control register. */
-		*adc_ctrl_regs[channel_cfg->channel_id].adc_ctrl =
-			IT83XX_ADC_DATVAL | IT83XX_ADC_INTDVEN | IT83XX_ADC_VCHEN;
-	}
+	/* The channel is set to ADC alternate function */
+	pinmux_pin_set(porti, channel_cfg->channel_id, IT8XXX2_PINMUX_FUNC_1);
 	LOG_DBG("Channel setup succeeded!");
-
 	return 0;
 }
 
-static uint8_t count_channels(uint8_t ch)
+static void adc_enable_measurement(uint32_t ch)
 {
-	uint8_t count = 0;
-	uint8_t bit;
+	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
 
-	bit = find_lsb_set(ch);
-	while (bit != 0) {
-		uint8_t idx = bit - 1;
+	/* Select and enable a voltage channel input for measurement */
+	adc_regs->VCH0CTL = (IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_INTDVEN) + ch;
 
-		ch &= ~BIT(idx);
-		bit = find_lsb_set(ch);
-		count++;
-	}
+	/* Enable adc interrupt */
+	irq_enable(DT_INST_IRQN(0));
 
-	return count;
+	/* ADC module enable */
+	adc_regs->ADCCFG |= IT8XXX2_ADC_ADCEN;
+}
+
+static void adc_disable_measurement(void)
+{
+	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
+
+	/*
+	 * Disable measurement.
+	 * bit(4:0) = 0x1f : channel disable
+	 */
+	adc_regs->VCH0CTL = IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_CHANNEL_DISABLED;
+
+	/* ADC module disable */
+	adc_regs->ADCCFG &= ~IT8XXX2_ADC_ADCEN;
+
+	/* disable adc interrupt */
+	irq_disable(DT_INST_IRQN(0));
 }
 
 static int check_buffer_size(const struct adc_sequence *sequence,
@@ -143,14 +138,12 @@
 }
 
 static int adc_it8xxx2_start_read(const struct device *dev,
-			      const struct adc_sequence *sequence)
+				  const struct adc_sequence *sequence)
 {
 	struct adc_it8xxx2_data *data = DEV_DATA(dev);
-	uint8_t channels = sequence->channels;
-	uint8_t channel_count;
-	int err;
+	uint32_t channel_mask = sequence->channels;
 
-	if (!channels || channels & ~BIT_MASK(CHIP_ADC_COUNT)) {
+	if (!channel_mask || channel_mask & ~BIT_MASK(CHIP_ADC_COUNT)) {
 		LOG_ERR("Invalid selection of channels");
 		return -EINVAL;
 	}
@@ -161,13 +154,6 @@
 	}
 	LOG_DBG("Configure resolution=%d", sequence->resolution);
 
-	channel_count = count_channels(channels);
-	err = check_buffer_size(sequence, channel_count);
-	if (err) {
-		return err;
-	}
-
-	data->buffer = sequence->buffer;
 	adc_context_start_read(&data->ctx, sequence);
 
 	return adc_context_wait_for_completion(&data->ctx);
@@ -180,22 +166,34 @@
 
 	data->repeat_buffer = data->buffer;
 
-	/* enable adc interrupt */
-	irq_enable(DT_INST_IRQN(0));
-
-	/* ADC module enable */
-	IT83XX_ADC_ADCCFG |= IT83XX_ADC_ADCEN;
+	adc_enable_measurement(data->ch);
 }
 
 static int adc_it8xxx2_read(const struct device *dev,
-			const struct adc_sequence *sequence)
+			    const struct adc_sequence *sequence)
 {
 	struct adc_it8xxx2_data *data = DEV_DATA(dev);
-	int err;
+	uint32_t channel_mask = sequence->channels;
+	uint8_t channel_count = 0;
+	int err = 0;
 
-	adc_context_lock(&data->ctx, false, NULL);
-	err = adc_it8xxx2_start_read(dev, sequence);
-	adc_context_release(&data->ctx, err);
+	data->buffer = sequence->buffer;
+
+	while (channel_mask) {
+		adc_context_lock(&data->ctx, false, NULL);
+		data->ch = find_lsb_set(channel_mask) - 1;
+
+		err = adc_it8xxx2_start_read(dev, sequence);
+		if (err) {
+			return err;
+		}
+
+		channel_mask &= ~BIT(data->ch);
+		channel_count++;
+		adc_context_release(&data->ctx, err);
+	}
+
+	err = check_buffer_size(sequence, channel_count);
 
 	return err;
 }
@@ -211,49 +209,26 @@
 	}
 }
 
-static int adc_data_valid(enum chip_adc_channel adc_ch)
-{
-	return IT83XX_ADC_ADCDVSTS & BIT(adc_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(dev);
-	uint8_t channels = data->ctx.sequence.channels;
-	uint8_t bit;
+	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
 	bool valid = false;
 
-	bit = find_lsb_set(channels);
-	while (bit != 0) {
-		uint8_t idx = bit - 1;
+	if (adc_regs->VCH0CTL & IT8XXX2_ADC_DATVAL) {
+		/* Read adc raw data of msb and lsb */
+		*data->buffer++ = adc_regs->VCH0DATM << 8 | adc_regs->VCH0DATL;
 
-		if (adc_data_valid(idx)) {
-			/* Read adc raw data of msb and lsb */
-			uint16_t val = (*adc_ctrl_regs[idx].adc_datm << 8) |
-						*adc_ctrl_regs[idx].adc_datl;
-			/* Raw data multiply resolution. */
-			*data->buffer++ = val * data->ctx.sequence.resolution;
-
-			/* W/C data valid flag */
-			IT83XX_ADC_ADCDVSTS = BIT(idx);
-			valid = 1;
-		}
-
-		if (!valid) {
-			LOG_WRN("ADC failed to read (regs=%x, ch=%d)",
-				IT83XX_ADC_ADCDVSTS, idx);
-		}
-
-		channels &= ~BIT(idx);
-		bit = find_lsb_set(channels);
+		valid = 1;
 	}
 
-	/* ADC module disable */
-	IT83XX_ADC_ADCCFG &= ~IT83XX_ADC_ADCEN;
-	/* disable adc interrupt */
-	irq_disable(DT_INST_IRQN(0));
+	if (!valid) {
+		LOG_WRN("ADC failed to read (regs=%x, ch=%d)",
+			adc_regs->ADCDVSTS, data->ch);
+	}
 
+	adc_disable_measurement();
 }
 
 static void adc_it8xxx2_isr(const void *arg)
@@ -271,6 +246,7 @@
 static const struct adc_driver_api api_it8xxx2_driver_api = {
 	.channel_setup = adc_it8xxx2_channel_setup,
 	.read = adc_it8xxx2_read,
+	.ref_internal = IT8XXX2_ADC_VREF_VOL,
 };
 
 /*
@@ -283,19 +259,20 @@
  */
 static void adc_accuracy_initialization(void)
 {
+	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
+
 	/* Start adc accuracy initialization */
-	IT83XX_ADC_ADCSTS |= IT83XX_ADC_AINITB;
+	adc_regs->ADCSTS |= IT8XXX2_ADC_AINITB;
 	/* Enable automatic HW calibration. */
-	IT83XX_ADC_KDCTL |= IT83XX_ADC_AHCE;
-	/* short delay for adc accuracy initialization */
-	IT83XX_GCTRL_WNCKR = 0;
+	adc_regs->KDCTL |= IT8XXX2_ADC_AHCE;
 	/* Stop adc accuracy initialization */
-	IT83XX_ADC_ADCSTS &= ~IT83XX_ADC_AINITB;
+	adc_regs->ADCSTS &= ~IT8XXX2_ADC_AINITB;
 }
 
 static int adc_it8xxx2_init(const struct device *dev)
 {
 	struct adc_it8xxx2_data *data = DEV_DATA(dev);
+	struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
 
 	/* ADC analog accuracy initialization */
 	adc_accuracy_initialization();
@@ -307,13 +284,18 @@
 	 * NOTE: A sample time delay (60us) also need to be included in
 	 * conversion time, so the final result is ~= 121.6us.
 	 */
-	IT83XX_ADC_ADCSTS &= ~IT83XX_ADC_ADCCTS1;
-	IT83XX_ADC_ADCCFG &= ~IT83XX_ADC_ADCCTS0;
+	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;
 	 */
-	IT83XX_ADC_ADCCTL = 1;
+	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);
@@ -329,8 +311,8 @@
 		ADC_CONTEXT_INIT_SYNC(adc_it8xxx2_data_0, ctx),
 };
 DEVICE_DT_INST_DEFINE(0, adc_it8xxx2_init,
-				NULL,
-				&adc_it8xxx2_data_0,
-				NULL, POST_KERNEL,
-				CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
-				&api_it8xxx2_driver_api);
+		      NULL,
+		      &adc_it8xxx2_data_0,
+		      NULL, PRE_KERNEL_1,
+		      CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
+		      &api_it8xxx2_driver_api);
diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h
index 54ca512..fdb9211 100644
--- a/soc/riscv/riscv-ite/common/chip_chipregs.h
+++ b/soc/riscv/riscv-ite/common/chip_chipregs.h
@@ -1625,55 +1625,39 @@
 #define IT8XXX2_GPIO_GRC21      ECREG(IT8XXX2_GPIO_BASE + 0xE6)
 
 /* Analog to Digital Converter (ADC) */
-#define IT83XX_ADC_BASE   0x00f01900
 
-#define IT83XX_ADC_ADCSTS       ECREG(IT83XX_ADC_BASE + 0x00)
-#define IT83XX_ADC_ADCCTS1			BIT(7)
-#define IT83XX_ADC_AINITB			BIT(3)
-#define IT83XX_ADC_ADCCFG       ECREG(IT83XX_ADC_BASE + 0x01)
-#define IT83XX_ADC_ADCCTS0			BIT(5)
-#define IT83XX_ADC_ADCEN			BIT(0)
-#define IT83XX_ADC_ADCCTL       ECREG(IT83XX_ADC_BASE + 0x02)
-#define IT83XX_ADC_ADCGCR       ECREG(IT83XX_ADC_BASE + 0x03)
-#define IT83XX_ADC_VCH0CTL      ECREG(IT83XX_ADC_BASE + 0x04)
+#ifndef __ASSEMBLER__
+struct adc_it8xxx2_regs {
+	volatile uint8_t ADCSTS;
+	volatile uint8_t ADCCFG;
+	volatile uint8_t ADCCTL;
+	volatile uint8_t ADCGCR;
+	volatile uint8_t VCH0CTL;
+	volatile uint8_t KDCTL;
+	volatile uint8_t reserved1[18];
+	volatile uint8_t VCH0DATL;
+	volatile uint8_t VCH0DATM;
+	volatile uint8_t reserved2[42];
+	volatile uint8_t ADCDVSTS;
+};
+#endif /* !__ASSEMBLER__ */
+
+/* ADC conversion time select 1 */
+#define IT8XXX2_ADC_ADCCTS1			BIT(7)
+/* Analog accuracy initialization */
+#define IT8XXX2_ADC_AINITB			BIT(3)
+/* ADC conversion time select 0 */
+#define IT8XXX2_ADC_ADCCTS0			BIT(5)
+/* ADC module enable */
+#define IT8XXX2_ADC_ADCEN			BIT(0)
+/* ADC data buffer keep enable */
+#define IT8XXX2_ADC_DBKEN			BIT(7)
 /* W/C data valid flag */
-#define IT83XX_ADC_DATVAL			BIT(7)
-/* Data valid interrupt of adc. */
-#define IT83XX_ADC_INTDVEN			BIT(5)
-#define IT83XX_ADC_KDCTL        ECREG(IT83XX_ADC_BASE + 0x05)
-#define IT83XX_ADC_AHCE				BIT(7)
-#define IT83XX_ADC_VCH1CTL      ECREG(IT83XX_ADC_BASE + 0x06)
-#define IT83XX_ADC_VCH1DATL     ECREG(IT83XX_ADC_BASE + 0x07)
-#define IT83XX_ADC_VCH1DATM     ECREG(IT83XX_ADC_BASE + 0x08)
-#define IT83XX_ADC_VCH2CTL      ECREG(IT83XX_ADC_BASE + 0x09)
-#define IT83XX_ADC_VCH2DATL     ECREG(IT83XX_ADC_BASE + 0x0A)
-#define IT83XX_ADC_VCH2DATM     ECREG(IT83XX_ADC_BASE + 0x0B)
-#define IT83XX_ADC_VCH3CTL      ECREG(IT83XX_ADC_BASE + 0x0C)
-#define IT83XX_ADC_VCH3DATL     ECREG(IT83XX_ADC_BASE + 0x0D)
-#define IT83XX_ADC_VCH3DATM     ECREG(IT83XX_ADC_BASE + 0x0E)
-#define IT83XX_ADC_VHSCDBL      ECREG(IT83XX_ADC_BASE + 0x14)
-#define IT83XX_ADC_VHSCDBM      ECREG(IT83XX_ADC_BASE + 0x15)
-#define IT83XX_ADC_VCH0DATL     ECREG(IT83XX_ADC_BASE + 0x18)
-#define IT83XX_ADC_VCH0DATM     ECREG(IT83XX_ADC_BASE + 0x19)
-#define IT83XX_ADC_VHSGCDBL     ECREG(IT83XX_ADC_BASE + 0x1C)
-#define IT83XX_ADC_VHSGCDBM     ECREG(IT83XX_ADC_BASE + 0x1D)
-#define IT83XX_ADC_ADCSAR       ECREG(IT83XX_ADC_BASE + 0x32)
-#define IT83XX_ADC_VCMPSCP      ECREG(IT83XX_ADC_BASE + 0x37)
-#define IT83XX_ADC_VCH4CTL      ECREG(IT83XX_ADC_BASE + 0x38)
-/* Voltage channel enable (ch4~ch7) */
-#define IT83XX_ADC_VCHEN			BIT(4)
-#define IT83XX_ADC_VCH4DATM     ECREG(IT83XX_ADC_BASE + 0x39)
-#define IT83XX_ADC_VCH4DATL     ECREG(IT83XX_ADC_BASE + 0x3A)
-#define IT83XX_ADC_VCH5CTL      ECREG(IT83XX_ADC_BASE + 0x3B)
-#define IT83XX_ADC_VCH5DATM     ECREG(IT83XX_ADC_BASE + 0x3C)
-#define IT83XX_ADC_VCH5DATL     ECREG(IT83XX_ADC_BASE + 0x3D)
-#define IT83XX_ADC_VCH6CTL      ECREG(IT83XX_ADC_BASE + 0x3E)
-#define IT83XX_ADC_VCH6DATM     ECREG(IT83XX_ADC_BASE + 0x3F)
-#define IT83XX_ADC_VCH6DATL     ECREG(IT83XX_ADC_BASE + 0x40)
-#define IT83XX_ADC_VCH7CTL      ECREG(IT83XX_ADC_BASE + 0x41)
-#define IT83XX_ADC_VCH7DATM     ECREG(IT83XX_ADC_BASE + 0x42)
-#define IT83XX_ADC_VCH7DATL     ECREG(IT83XX_ADC_BASE + 0x43)
-#define IT83XX_ADC_ADCDVSTS     ECREG(IT83XX_ADC_BASE + 0x44)
+#define IT8XXX2_ADC_DATVAL			BIT(7)
+/* Data valid interrupt of adc */
+#define IT8XXX2_ADC_INTDVEN			BIT(5)
+/* Automatic hardware calibration enable */
+#define IT8XXX2_ADC_AHCE			BIT(7)
 
 /*
  * Clock and Power Management (ECPM)