From 7add8f7fa0ef4776756a1918c74a2739344c75eb Mon Sep 17 00:00:00 2001 From: Wealian Liao Date: Mon, 13 Dec 2021 13:33:50 +0800 Subject: [PATCH] drivers: adc: npcx: Fix register offset NPCX7/9 has a different ADC register structure. NPCX7 has 3 threshold detectors from offset 0x14 & has 10 input channels. NPCX9 has 6 threshold detectors from offset 0x60 & has 12 input channels. This commit fixes the NPCX ADC register structure. Signed-off-by: Wealian Liao --- drivers/adc/adc_npcx.c | 5 ++-- dts/arm/nuvoton/npcx7.dtsi | 1 + dts/arm/nuvoton/npcx9.dtsi | 1 + dts/bindings/iio/adc/nuvoton,npcx-adc.yaml | 4 +++ soc/arm/nuvoton_npcx/common/reg/reg_def.h | 30 ++++++++++------------ soc/arm/nuvoton_npcx/common/registers.c | 6 ++--- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/adc/adc_npcx.c b/drivers/adc/adc_npcx.c index e183e458924..a6764085945 100644 --- a/drivers/adc/adc_npcx.c +++ b/drivers/adc/adc_npcx.c @@ -93,8 +93,9 @@ static void adc_npcx_isr(void *arg) /* Get result for each ADC selected channel */ while (data->channels) { channel = find_lsb_set(data->channels) - 1; - result = GET_FIELD(inst->CHNDAT[channel], - NPCX_CHNDAT_CHDAT_FIELD); + result = GET_FIELD(CHNDAT(DRV_CONFIG((const struct device *)arg)->base, + channel), + NPCX_CHNDAT_CHDAT_FIELD); /* * Save ADC result and adc_npcx_validate_buffer_size() * already ensures that the buffer has enough space for diff --git a/dts/arm/nuvoton/npcx7.dtsi b/dts/arm/nuvoton/npcx7.dtsi index 8f2e80c0d13..5849c0d8e70 100644 --- a/dts/arm/nuvoton/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx7.dtsi @@ -197,6 +197,7 @@ &altf_adc7_sl /* ADC7 - PINE1 */ &altf_adc8_sl /* ADC8 - PINF1 */ &altf_adc9_sl>; /* ADC9 - PINF0 */ + threshold-reg-offset = <0x14>; }; }; diff --git a/dts/arm/nuvoton/npcx9.dtsi b/dts/arm/nuvoton/npcx9.dtsi index 296be5a2ba6..864b2b2b28c 100644 --- a/dts/arm/nuvoton/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx9.dtsi @@ -223,6 +223,7 @@ &altf_adc9_sl /* ADC9 - PINF0 */ &altf_adc10_sl /* ADC10 - PINE0 */ &altf_adc11_sl>; /* ADC11 - PINC7 */ + threshold-reg-offset = <0x60>; }; }; diff --git a/dts/bindings/iio/adc/nuvoton,npcx-adc.yaml b/dts/bindings/iio/adc/nuvoton,npcx-adc.yaml index 96a3c23c3cd..e9fc222b0c8 100644 --- a/dts/bindings/iio/adc/nuvoton,npcx-adc.yaml +++ b/dts/bindings/iio/adc/nuvoton,npcx-adc.yaml @@ -18,6 +18,10 @@ properties: type: phandles required: true description: configurations of pinmux controllers + threshold-reg-offset: + type: int + required: true + description: the offset of threshold detector register address io-channel-cells: - input diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 83c4acb20cc..46aa87cc3df 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -488,13 +488,7 @@ struct adc_reg { volatile uint16_t ASCADD; /* 0x008: ADC Scan Channels Select */ volatile uint16_t ADCCS; - volatile uint8_t reserved1[10]; - /* 0x014: Threshold Control 1 */ - volatile uint16_t THRCTL1; - /* 0x016: Threshold Control 2 */ - volatile uint16_t THRCTL2; - /* 0x018: Threshold Control 3 */ - volatile uint16_t THRCTL3; + volatile uint8_t reserved1[16]; /* 0x01A: Threshold Status */ volatile uint16_t THRCTS; volatile uint8_t reserved2[4]; @@ -505,17 +499,21 @@ struct adc_reg { volatile uint8_t reserved3[2]; /* 0x026: Internal register 3 for ADC Speed */ volatile uint16_t MEAST; - volatile uint8_t reserved4[18]; - /* 0x03A: Deassertion Threshold Control 1 Word */ - volatile uint16_t THR_DCTL1; - /* 0x03C: Deassertion Threshold Control 2 Word */ - volatile uint16_t THR_DCTL2; - /* 0x03E: Deassertion Threshold Control 3 Word */ - volatile uint16_t THR_DCTL3; - /* 0x040 - 52: Data Buffer of Channel 0 - 9 */ - volatile uint16_t CHNDAT[10]; }; +static inline uint32_t npcx_thrctl_offset(uint32_t ctl_no) +{ + return DT_PROP(DT_INST(0, nuvoton_npcx_adc), threshold_reg_offset) + (ctl_no - 1) * 2; +} + +static inline uint32_t npcx_chndat_offset(uint32_t ch) +{ + return 0x40 + ch * 2; +} + +#define THRCTL(base, ctl_no) (*(volatile uint16_t *)((base) + npcx_thrctl_offset(ctl_no))) +#define CHNDAT(base, ch) (*(volatile uint16_t *)((base) + npcx_chndat_offset(ch))) + /* ADC register fields */ #define NPCX_ATCTL_SCLKDIV_FIELD FIELD(0, 6) #define NPCX_ATCTL_DLY_FIELD FIELD(8, 3) diff --git a/soc/arm/nuvoton_npcx/common/registers.c b/soc/arm/nuvoton_npcx/common/registers.c index 337190769f7..fa7f54c957a 100644 --- a/soc/arm/nuvoton_npcx/common/registers.c +++ b/soc/arm/nuvoton_npcx/common/registers.c @@ -50,10 +50,10 @@ NPCX_REG_OFFSET_CHECK(pwm_reg, DCR, 0x006); NPCX_REG_OFFSET_CHECK(pwm_reg, PWMCTLEX, 0x00c); /* ADC register structure check */ -NPCX_REG_SIZE_CHECK(adc_reg, 0x54); -NPCX_REG_OFFSET_CHECK(adc_reg, THRCTL1, 0x014); +NPCX_REG_SIZE_CHECK(adc_reg, 0x028); +NPCX_REG_OFFSET_CHECK(adc_reg, THRCTS, 0x01a); NPCX_REG_OFFSET_CHECK(adc_reg, ADCCNF2, 0x020); -NPCX_REG_OFFSET_CHECK(adc_reg, CHNDAT, 0x040); +NPCX_REG_OFFSET_CHECK(adc_reg, MEAST, 0x026); /* TWD register structure check */ NPCX_REG_SIZE_CHECK(twd_reg, 0x012);