ITE: drivers/adc: implement ADC channels 13-16
The ADC driver of IT81302 chip can support channels 0-7 & 13-16. This PR adds to implement ADC channels 13-16. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
This commit is contained in:
parent
cb9a279050
commit
056738514a
|
@ -28,6 +28,9 @@ LOG_MODULE_REGISTER(adc_ite_it8xxx2);
|
||||||
#define IT8XXX2_ADC_SAMPLE_TIME_US 200
|
#define IT8XXX2_ADC_SAMPLE_TIME_US 200
|
||||||
/* Wait next clock rising (Clock source 32.768K) */
|
/* Wait next clock rising (Clock source 32.768K) */
|
||||||
#define IT8XXX2_WAIT_NEXT_CLOCK_TIME_US 31
|
#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. */
|
/* List of ADC channels. */
|
||||||
enum chip_adc_channel {
|
enum chip_adc_channel {
|
||||||
|
@ -39,6 +42,10 @@ enum chip_adc_channel {
|
||||||
CHIP_ADC_CH5,
|
CHIP_ADC_CH5,
|
||||||
CHIP_ADC_CH6,
|
CHIP_ADC_CH6,
|
||||||
CHIP_ADC_CH7,
|
CHIP_ADC_CH7,
|
||||||
|
CHIP_ADC_CH13,
|
||||||
|
CHIP_ADC_CH14,
|
||||||
|
CHIP_ADC_CH15,
|
||||||
|
CHIP_ADC_CH16,
|
||||||
CHIP_ADC_COUNT,
|
CHIP_ADC_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,17 +83,25 @@ static int adc_it8xxx2_channel_setup(const struct device *dev,
|
||||||
const struct adc_channel_cfg *channel_cfg)
|
const struct adc_channel_cfg *channel_cfg)
|
||||||
{
|
{
|
||||||
const struct adc_it8xxx2_cfg *config = dev->config;
|
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) {
|
if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
|
||||||
LOG_ERR("Selected ADC acquisition time is not valid");
|
LOG_ERR("Selected ADC acquisition time is not valid");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel_cfg->channel_id >= CHIP_ADC_COUNT) {
|
/* Support channels 0~7 and 13~16 */
|
||||||
LOG_ERR("Channel %d is not valid", channel_cfg->channel_id);
|
if (!((channel_id >= 0 && channel_id <= 7) ||
|
||||||
|
(channel_id >= 13 && channel_id <= 16))) {
|
||||||
|
LOG_ERR("Channel %d is not valid", channel_id);
|
||||||
return -EINVAL;
|
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) {
|
if (channel_cfg->gain != ADC_GAIN_1) {
|
||||||
LOG_ERR("Invalid channel gain");
|
LOG_ERR("Invalid channel gain");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -98,22 +113,33 @@ static int adc_it8xxx2_channel_setup(const struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The channel is set to ADC alternate function */
|
/* The channel is set to ADC alternate function */
|
||||||
pinmux_pin_set(config[channel_cfg->channel_id].pinctrls,
|
pinmux_pin_set(config[channel_id].pinctrls,
|
||||||
config[channel_cfg->channel_id].pin,
|
config[channel_id].pin,
|
||||||
config[channel_cfg->channel_id].alt_fun);
|
config[channel_id].alt_fun);
|
||||||
LOG_DBG("Channel setup succeeded!");
|
LOG_DBG("Channel setup succeeded!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adc_disable_measurement(void)
|
static void adc_disable_measurement(uint32_t ch)
|
||||||
{
|
{
|
||||||
struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
|
struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
|
||||||
|
|
||||||
/*
|
if (ch <= CHIP_ADC_CH7) {
|
||||||
* Disable measurement.
|
/*
|
||||||
* bit(4:0) = 0x1f : channel disable
|
* Disable measurement.
|
||||||
*/
|
* bit(4:0) = 0x1f : channel disable
|
||||||
adc_regs->VCH0CTL = IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_CHANNEL_DISABLED;
|
*/
|
||||||
|
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 module disable */
|
||||||
adc_regs->ADCCFG &= ~IT8XXX2_ADC_ADCEN;
|
adc_regs->ADCCFG &= ~IT8XXX2_ADC_ADCEN;
|
||||||
|
@ -122,26 +148,43 @@ static void adc_disable_measurement(void)
|
||||||
irq_disable(DT_INST_IRQN(0));
|
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. */
|
/* Get result for each ADC selected channel. */
|
||||||
static void adc_it8xxx2_get_sample(const struct device *dev)
|
static void adc_it8xxx2_get_sample(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct adc_it8xxx2_data *data = dev->data;
|
struct adc_it8xxx2_data *data = dev->data;
|
||||||
struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
|
struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
|
||||||
|
|
||||||
if (adc_regs->VCH0CTL & IT8XXX2_ADC_DATVAL) {
|
if (adc_data_valid(dev)) {
|
||||||
/* Read adc raw data of msb and lsb */
|
if (data->ch <= CHIP_ADC_CH7) {
|
||||||
*data->buffer++ = adc_regs->VCH0DATM << 8 | adc_regs->VCH0DATL;
|
/* 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 {
|
} else {
|
||||||
LOG_WRN("ADC failed to read (regs=%x, ch=%d)",
|
LOG_WRN("ADC failed to read (regs=%x, ch=%d)",
|
||||||
adc_regs->ADCDVSTS, data->ch);
|
adc_regs->ADCDVSTS, data->ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_disable_measurement();
|
adc_disable_measurement(data->ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adc_poll_valid_data(void)
|
static void adc_poll_valid_data(void)
|
||||||
{
|
{
|
||||||
struct adc_it8xxx2_regs *const adc_regs = ADC_IT8XXX2_REG_BASE;
|
|
||||||
const struct device *dev = DEVICE_DT_INST_GET(0);
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
int valid = 0;
|
int valid = 0;
|
||||||
|
|
||||||
|
@ -154,7 +197,7 @@ static void adc_poll_valid_data(void)
|
||||||
/* Wait next clock time (1/32.768K~=30.5us) */
|
/* Wait next clock time (1/32.768K~=30.5us) */
|
||||||
k_busy_wait(IT8XXX2_WAIT_NEXT_CLOCK_TIME_US);
|
k_busy_wait(IT8XXX2_WAIT_NEXT_CLOCK_TIME_US);
|
||||||
|
|
||||||
if (adc_regs->VCH0CTL & IT8XXX2_ADC_DATVAL) {
|
if (adc_data_valid(dev)) {
|
||||||
valid = 1;
|
valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -174,8 +217,14 @@ static void adc_enable_measurement(uint32_t ch)
|
||||||
const struct device *dev = DEVICE_DT_INST_GET(0);
|
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||||
struct adc_it8xxx2_data *data = dev->data;
|
struct adc_it8xxx2_data *data = dev->data;
|
||||||
|
|
||||||
/* Select and enable a voltage channel input for measurement */
|
if (ch <= CHIP_ADC_CH7) {
|
||||||
adc_regs->VCH0CTL = (IT8XXX2_ADC_DATVAL | IT8XXX2_ADC_INTDVEN) + ch;
|
/* 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 module enable */
|
||||||
adc_regs->ADCCFG |= IT8XXX2_ADC_ADCEN;
|
adc_regs->ADCCFG |= IT8XXX2_ADC_ADCEN;
|
||||||
|
@ -230,6 +279,11 @@ static int adc_it8xxx2_start_read(const struct device *dev,
|
||||||
struct adc_it8xxx2_data *data = dev->data;
|
struct adc_it8xxx2_data *data = dev->data;
|
||||||
uint32_t channel_mask = sequence->channels;
|
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)) {
|
if (!channel_mask || channel_mask & ~BIT_MASK(CHIP_ADC_COUNT)) {
|
||||||
LOG_ERR("Invalid selection of channels");
|
LOG_ERR("Invalid selection of channels");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -35,6 +35,18 @@
|
||||||
pinctrl_adc7: adc7 {
|
pinctrl_adc7: adc7 {
|
||||||
pinctrls = <&pinmuxi 7 IT8XXX2_PINMUX_FUNC_1>;
|
pinctrls = <&pinmuxi 7 IT8XXX2_PINMUX_FUNC_1>;
|
||||||
};
|
};
|
||||||
|
pinctrl_adc13: adc13 {
|
||||||
|
pinctrls = <&pinmuxl 0 IT8XXX2_PINMUX_FUNC_1>;
|
||||||
|
};
|
||||||
|
pinctrl_adc14: adc14 {
|
||||||
|
pinctrls = <&pinmuxl 1 IT8XXX2_PINMUX_FUNC_1>;
|
||||||
|
};
|
||||||
|
pinctrl_adc15: adc15 {
|
||||||
|
pinctrls = <&pinmuxl 2 IT8XXX2_PINMUX_FUNC_1>;
|
||||||
|
};
|
||||||
|
pinctrl_adc16: adc16 {
|
||||||
|
pinctrls = <&pinmuxl 3 IT8XXX2_PINMUX_FUNC_1>;
|
||||||
|
};
|
||||||
|
|
||||||
/* PWM alternate function */
|
/* PWM alternate function */
|
||||||
pinctrl_pwm0: pwm0 {
|
pinctrl_pwm0: pwm0 {
|
||||||
|
|
|
@ -654,7 +654,11 @@
|
||||||
&pinctrl_adc4 /* ADC4*/
|
&pinctrl_adc4 /* ADC4*/
|
||||||
&pinctrl_adc5 /* ADC5*/
|
&pinctrl_adc5 /* ADC5*/
|
||||||
&pinctrl_adc6 /* ADC6*/
|
&pinctrl_adc6 /* ADC6*/
|
||||||
&pinctrl_adc7>; /* ADC7*/
|
&pinctrl_adc7 /* ADC7*/
|
||||||
|
&pinctrl_adc13 /* ADC13*/
|
||||||
|
&pinctrl_adc14 /* ADC14*/
|
||||||
|
&pinctrl_adc15 /* ADC15*/
|
||||||
|
&pinctrl_adc16>;/* ADC16*/
|
||||||
};
|
};
|
||||||
i2c0: i2c@f01c40 {
|
i2c0: i2c@f01c40 {
|
||||||
compatible = "ite,it8xxx2-i2c";
|
compatible = "ite,it8xxx2-i2c";
|
||||||
|
|
|
@ -124,3 +124,11 @@ IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSOCTRL, 0x02);
|
||||||
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSI, 0x04);
|
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSI, 0x04);
|
||||||
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSIGDAT, 0x08);
|
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSIGDAT, 0x08);
|
||||||
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSOLGOEN, 0x0e);
|
IT8XXX2_REG_OFFSET_CHECK(kscan_it8xxx2_regs, KBS_KSOLGOEN, 0x0e);
|
||||||
|
|
||||||
|
/* ADC register structure check */
|
||||||
|
IT8XXX2_REG_SIZE_CHECK(adc_it8xxx2_regs, 0x6d);
|
||||||
|
IT8XXX2_REG_OFFSET_CHECK(adc_it8xxx2_regs, ADCGCR, 0x03);
|
||||||
|
IT8XXX2_REG_OFFSET_CHECK(adc_it8xxx2_regs, VCH0DATM, 0x19);
|
||||||
|
IT8XXX2_REG_OFFSET_CHECK(adc_it8xxx2_regs, adc_vchs_ctrl[0].VCHCTL, 0x60);
|
||||||
|
IT8XXX2_REG_OFFSET_CHECK(adc_it8xxx2_regs, adc_vchs_ctrl[2].VCHDATM, 0x67);
|
||||||
|
IT8XXX2_REG_OFFSET_CHECK(adc_it8xxx2_regs, ADCDVSTS2, 0x6c);
|
||||||
|
|
|
@ -1550,21 +1550,52 @@ struct flash_it8xxx2_regs {
|
||||||
#define IT8XXX2_GPIO_GPCRP0 ECREG(IT8XXX2_GPIO2_BASE + 0x18)
|
#define IT8XXX2_GPIO_GPCRP0 ECREG(IT8XXX2_GPIO2_BASE + 0x18)
|
||||||
#define IT8XXX2_GPIO_GPCRP1 ECREG(IT8XXX2_GPIO2_BASE + 0x19)
|
#define IT8XXX2_GPIO_GPCRP1 ECREG(IT8XXX2_GPIO2_BASE + 0x19)
|
||||||
|
|
||||||
/* Analog to Digital Converter (ADC) */
|
/**
|
||||||
|
*
|
||||||
|
* (19xxh) Analog to Digital Converter (ADC) registers
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
/* Data structure to define ADC channel 13-16 control registers. */
|
||||||
|
struct adc_vchs_ctrl_t {
|
||||||
|
/* 0x60: Voltage Channel Control */
|
||||||
|
volatile uint8_t VCHCTL;
|
||||||
|
/* 0x61: Voltage Channel Data Buffer MSB */
|
||||||
|
volatile uint8_t VCHDATM;
|
||||||
|
/* 0x62: Voltage Channel Data Buffer LSB */
|
||||||
|
volatile uint8_t VCHDATL;
|
||||||
|
};
|
||||||
|
|
||||||
struct adc_it8xxx2_regs {
|
struct adc_it8xxx2_regs {
|
||||||
|
/* 0x00: ADC Status */
|
||||||
volatile uint8_t ADCSTS;
|
volatile uint8_t ADCSTS;
|
||||||
|
/* 0x01: ADC Configuration */
|
||||||
volatile uint8_t ADCCFG;
|
volatile uint8_t ADCCFG;
|
||||||
|
/* 0x02: ADC Clock Control */
|
||||||
volatile uint8_t ADCCTL;
|
volatile uint8_t ADCCTL;
|
||||||
|
/* 0x03: General Control */
|
||||||
volatile uint8_t ADCGCR;
|
volatile uint8_t ADCGCR;
|
||||||
|
/* 0x04: Voltage Channel 0 Control */
|
||||||
volatile uint8_t VCH0CTL;
|
volatile uint8_t VCH0CTL;
|
||||||
|
/* 0x05: Calibration Data Control */
|
||||||
volatile uint8_t KDCTL;
|
volatile uint8_t KDCTL;
|
||||||
|
/* 0x06-0x17: Reserved1 */
|
||||||
volatile uint8_t reserved1[18];
|
volatile uint8_t reserved1[18];
|
||||||
|
/* 0x18: Voltage Channel 0 Data Buffer LSB */
|
||||||
volatile uint8_t VCH0DATL;
|
volatile uint8_t VCH0DATL;
|
||||||
|
/* 0x19: Voltage Channel 0 Data Buffer MSB */
|
||||||
volatile uint8_t VCH0DATM;
|
volatile uint8_t VCH0DATM;
|
||||||
|
/* 0x1a-0x43: Reserved2 */
|
||||||
volatile uint8_t reserved2[42];
|
volatile uint8_t reserved2[42];
|
||||||
|
/* 0x44: ADC Data Valid Status */
|
||||||
volatile uint8_t ADCDVSTS;
|
volatile uint8_t ADCDVSTS;
|
||||||
|
/* 0x45-0x5f: Reserved3 */
|
||||||
|
volatile uint8_t reserved3[27];
|
||||||
|
/* 0x60-0x6b: ADC channel 13~16 controller */
|
||||||
|
struct adc_vchs_ctrl_t adc_vchs_ctrl[4];
|
||||||
|
/* 0x6c: ADC Data Valid Status 2 */
|
||||||
|
volatile uint8_t ADCDVSTS2;
|
||||||
};
|
};
|
||||||
#endif /* !__ASSEMBLER__ */
|
#endif /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
|
@ -1582,6 +1613,8 @@ struct adc_it8xxx2_regs {
|
||||||
#define IT8XXX2_ADC_DATVAL BIT(7)
|
#define IT8XXX2_ADC_DATVAL BIT(7)
|
||||||
/* Data valid interrupt of adc */
|
/* Data valid interrupt of adc */
|
||||||
#define IT8XXX2_ADC_INTDVEN BIT(5)
|
#define IT8XXX2_ADC_INTDVEN BIT(5)
|
||||||
|
/* Voltage channel enable (Channel 4~7 and 13~16) */
|
||||||
|
#define IT8XXX2_ADC_VCHEN BIT(4)
|
||||||
/* Automatic hardware calibration enable */
|
/* Automatic hardware calibration enable */
|
||||||
#define IT8XXX2_ADC_AHCE BIT(7)
|
#define IT8XXX2_ADC_AHCE BIT(7)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue