From 253cec5c95e8f07a2140ba92f32cff14d0696df5 Mon Sep 17 00:00:00 2001 From: Jan Peters Date: Fri, 29 Apr 2022 10:25:12 +0200 Subject: [PATCH] drivers: counter: add driver for NXP QTMR counters The driver is implemented using the MCUXpresso SDK. Signed-off-by: Jan Peters --- .../clock_control/clock_control_mcux_ccm.c | 6 + drivers/counter/CMakeLists.txt | 1 + drivers/counter/Kconfig | 2 + drivers/counter/Kconfig.mcux_qtmr | 10 + drivers/counter/counter_mcux_qtmr.c | 332 ++++++++++++++++++ dts/arm/nxp/nxp_rt.dtsi | 128 +++++++ dts/bindings/counter/nxp,imx-qtmr.yaml | 18 + dts/bindings/counter/nxp,imx-tmr.yaml | 86 +++++ include/zephyr/dt-bindings/clock/imx_ccm.h | 2 + modules/Kconfig.mcux | 5 + soc/arm/nxp_imx/rt/Kconfig.soc | 2 + 11 files changed, 592 insertions(+) create mode 100644 drivers/counter/Kconfig.mcux_qtmr create mode 100644 drivers/counter/counter_mcux_qtmr.c create mode 100644 dts/bindings/counter/nxp,imx-qtmr.yaml create mode 100644 dts/bindings/counter/nxp,imx-tmr.yaml diff --git a/drivers/clock_control/clock_control_mcux_ccm.c b/drivers/clock_control/clock_control_mcux_ccm.c index a05338a3a00..bf1659fb074 100644 --- a/drivers/clock_control/clock_control_mcux_ccm.c +++ b/drivers/clock_control/clock_control_mcux_ccm.c @@ -168,6 +168,12 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, break; #endif +#ifdef CONFIG_COUNTER_MCUX_QTMR + case IMX_CCM_QTMR_CLK: + *rate = CLOCK_GetIpgFreq(); + break; +#endif + #ifdef CONFIG_I2S_MCUX_SAI case IMX_CCM_SAI1_CLK: *rate = CLOCK_GetFreq(kCLOCK_AudioPllClk) / 8 diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index 3c59e43b949..9402e1a91e9 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_SAM_TC counter_sam_tc.c zephyr_library_sources_ifdef(CONFIG_COUNTER_SAM0_TC32 counter_sam0_tc32.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_CMOS counter_cmos.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_GPT counter_mcux_gpt.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_QTMR counter_mcux_qtmr.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_SNVS counter_mcux_snvs.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_XEC counter_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_LPTMR counter_mcux_lptmr.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 228b389461f..c4d006a238e 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -46,6 +46,8 @@ source "drivers/counter/Kconfig.cmos" source "drivers/counter/Kconfig.mcux_gpt" +source "drivers/counter/Kconfig.mcux_qtmr" + source "drivers/counter/Kconfig.mcux_snvs" source "drivers/counter/Kconfig.xec" diff --git a/drivers/counter/Kconfig.mcux_qtmr b/drivers/counter/Kconfig.mcux_qtmr new file mode 100644 index 00000000000..dc9990e9366 --- /dev/null +++ b/drivers/counter/Kconfig.mcux_qtmr @@ -0,0 +1,10 @@ +# MCUXpresso SDK QTMR + +# Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_MCUX_QTMR + bool "MCUX QTMR driver" + depends on HAS_MCUX_QTMR + help + Enable support for mcux Quad Timer (QTMR) driver. diff --git a/drivers/counter/counter_mcux_qtmr.c b/drivers/counter/counter_mcux_qtmr.c new file mode 100644 index 00000000000..3d39c6d4fe5 --- /dev/null +++ b/drivers/counter/counter_mcux_qtmr.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * Counter driver for the Quad Timer through the MCUxpresso SDK. Based mainly on counter_mcux_gpt.c + * + * Each quad timer module has four channels (0-3) that can operate independently, but the Zephyr + * counter-API does not support starting or stopping different channels independently. Hence, each + * channel is represented as an independent counter device. + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(mcux_qtmr, CONFIG_COUNTER_LOG_LEVEL); + +struct mcux_qtmr_config { + /* info must be first element */ + struct counter_config_info info; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + TMR_Type *base; + clock_name_t clock_source; + qtmr_channel_selection_t channel; + qtmr_config_t qtmr_config; + qtmr_counting_mode_t mode; +}; + +struct mcux_qtmr_data { + counter_alarm_callback_t alarm_callback; + counter_top_callback_t top_callback; + void *alarm_user_data; + void *top_user_data; + qtmr_status_flags_t interrupt_mask; + uint32_t freq; +}; + +/* Only one interrupt per QTMR module. Each of which has four timers. */ +#define DT_DRV_COMPAT nxp_imx_qtmr + +/** + * @brief ISR for a specific timer channel + * + * @param dev timer channel device + */ +void mcux_qtmr_timer_handler(const struct device *dev, uint32_t status) +{ + const struct mcux_qtmr_config *config = dev->config; + struct mcux_qtmr_data *data = dev->data; + uint32_t current = QTMR_GetCurrentTimerCount(config->base, config->channel); + + QTMR_ClearStatusFlags(config->base, config->channel, status); + __DSB(); + + if ((status & kQTMR_Compare1Flag) && data->alarm_callback) { + QTMR_DisableInterrupts(config->base, config->channel, + kQTMR_Compare1InterruptEnable); + data->interrupt_mask &= ~kQTMR_Compare1InterruptEnable; + counter_alarm_callback_t alarm_cb = data->alarm_callback; + + data->alarm_callback = NULL; + alarm_cb(dev, config->channel, current, data->alarm_user_data); + } + + if ((status & kQTMR_OverflowFlag) && data->top_callback) { + data->top_callback(dev, data->top_user_data); + } +} + +/** + * @brief ISR for the QTMR + * + * @param timers array containing the counter devices for each channel of the timer module + */ +static void mcux_qtmr_isr(const struct device *timers[]) +{ + /* the interrupt can be triggered by any of the four channels of the QTMR. Check status + * of all channels and trigger the ISR for the channel(s) that has/have triggered the + * interrupt. + */ + for (qtmr_channel_selection_t ch = kQTMR_Channel_0; ch <= kQTMR_Channel_3 ; ch++) { + if (timers[ch] != NULL) { + const struct mcux_qtmr_config *config = timers[ch]->config; + struct mcux_qtmr_data *data = timers[ch]->data; + + uint32_t channel_status = QTMR_GetStatus(config->base, ch); + + if ((channel_status & data->interrupt_mask) != 0) { + mcux_qtmr_timer_handler(timers[ch], channel_status); + } + } + } +} + +#define ADD_TIMER(node_id, n) timers_##n[DT_PROP(node_id, channel)] = DEVICE_DT_GET(node_id); + +#define QTMR_DEVICE_INIT_MCUX(n) \ + static const struct device *timers_##n[4]; \ + static int init_irq_##n(const struct device *dev) \ + { \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_DRV_INST(n), ADD_TIMER, n) \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mcux_qtmr_isr, \ + timers_##n, 0); \ + irq_enable(DT_INST_IRQN(n)); \ + return 0; \ + } \ + \ + SYS_INIT(init_irq_##n, POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY); + +DT_INST_FOREACH_STATUS_OKAY(QTMR_DEVICE_INIT_MCUX) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nxp_imx_tmr + +static int mcux_qtmr_start(const struct device *dev) +{ + const struct mcux_qtmr_config *config = dev->config; + + QTMR_StartTimer(config->base, config->channel, config->mode); + + return 0; +} + +static int mcux_qtmr_stop(const struct device *dev) +{ + const struct mcux_qtmr_config *config = dev->config; + + QTMR_StopTimer(config->base, config->channel); + + return 0; +} + +static int mcux_qtmr_get_value(const struct device *dev, uint32_t *ticks) +{ + const struct mcux_qtmr_config *config = dev->config; + + *ticks = QTMR_GetCurrentTimerCount(config->base, config->channel); + return 0; +} + +static int mcux_qtmr_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + const struct mcux_qtmr_config *config = dev->config; + struct mcux_qtmr_data *data = dev->data; + uint32_t current; + uint32_t ticks; + + if (chan_id != 0) { + LOG_ERR("Invalid channel id"); + return -EINVAL; + } + + if (data->alarm_callback) { + return -EBUSY; + } + + data->alarm_callback = alarm_cfg->callback; + data->alarm_user_data = alarm_cfg->user_data; + + current = QTMR_GetCurrentTimerCount(config->base, config->channel); + ticks = alarm_cfg->ticks; + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) { + ticks += current; + } + + /* this timer always counts up. */ + config->base->CHANNEL[config->channel].COMP1 = ticks; + + data->interrupt_mask |= kQTMR_Compare1InterruptEnable; + QTMR_EnableInterrupts(config->base, config->channel, data->interrupt_mask); + + return 0; +} + +static int mcux_qtmr_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + const struct mcux_qtmr_config *config = dev->config; + struct mcux_qtmr_data *data = dev->data; + + if (chan_id != 0) { + LOG_ERR("Invalid channel id"); + return -EINVAL; + } + + QTMR_DisableInterrupts(config->base, config->channel, data->interrupt_mask); + data->interrupt_mask &= ~kQTMR_Compare1InterruptEnable; + data->alarm_callback = NULL; + + return 0; +} + +static uint32_t mcux_qtmr_get_pending_int(const struct device *dev) +{ + const struct mcux_qtmr_config *config = dev->config; + + return QTMR_GetStatus(config->base, config->channel); +} + +static int mcux_qtmr_set_top_value(const struct device *dev, + const struct counter_top_cfg *cfg) +{ + const struct mcux_qtmr_config *config = dev->config; + struct mcux_qtmr_data *data = dev->data; + + if (cfg->ticks != config->info.max_top_value) { + LOG_ERR("Wrap can only be set to 0x%x", + config->info.max_top_value); + return -ENOTSUP; + } + + if ((cfg->flags & COUNTER_TOP_CFG_DONT_RESET) == 0) { + if ((config->base->CHANNEL[config->channel].CTRL & TMR_CTRL_DIR_MASK) != 0U) { + /* counting down, reset to UINT16MAX */ + config->base->CHANNEL[config->channel].CNTR = UINT16_MAX; + } else { + /* counting up, reset to 0 */ + config->base->CHANNEL[config->channel].CNTR = 0; + } + } + + if (cfg->callback != NULL) { + data->top_callback = cfg->callback; + data->top_user_data = cfg->user_data; + + data->interrupt_mask |= kQTMR_OverflowInterruptEnable; + QTMR_EnableInterrupts(config->base, config->channel, kQTMR_OverflowInterruptEnable); + } + + return 0; +} + +static uint32_t mcux_qtmr_get_top_value(const struct device *dev) +{ + const struct mcux_qtmr_config *config = dev->config; + + return config->info.max_top_value; +} + +static uint32_t mcux_qtmr_get_freq(const struct device *dev) +{ + struct mcux_qtmr_data *data = dev->data; + + return data->freq; +} + +/** + * @brief look up table for dividers when using internal clock sources kQTMR_ClockDivide_1 to + * kQTMR_ClockDivide_128 + */ +static const uint8_t qtmr_primary_source_divider[] = {1, 2, 4, 8, 16, 32, 64, 128}; + +static int mcux_qtmr_init(const struct device *dev) +{ + const struct mcux_qtmr_config *config = dev->config; + struct mcux_qtmr_data *data = dev->data; + + if (config->qtmr_config.primarySource < kQTMR_ClockDivide_1) { + /* for external sources, use the value from the dts (if given) */ + data->freq = config->info.freq; + } else { + /* bus clock with divider */ + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &data->freq)) { + return -EINVAL; + } + + data->freq /= qtmr_primary_source_divider[config->qtmr_config.primarySource - + kQTMR_ClockDivide_1]; + } + + QTMR_Init(config->base, config->channel, &config->qtmr_config); + + return 0; +} + +static const struct counter_driver_api mcux_qtmr_driver_api = { + .start = mcux_qtmr_start, + .stop = mcux_qtmr_stop, + .get_value = mcux_qtmr_get_value, + .set_alarm = mcux_qtmr_set_alarm, + .cancel_alarm = mcux_qtmr_cancel_alarm, + .set_top_value = mcux_qtmr_set_top_value, + .get_pending_int = mcux_qtmr_get_pending_int, + .get_top_value = mcux_qtmr_get_top_value, + .get_freq = mcux_qtmr_get_freq, +}; + +#define TMR_DEVICE_INIT_MCUX(n) \ + static struct mcux_qtmr_data mcux_qtmr_data_ ## n; \ + \ + static const struct mcux_qtmr_config mcux_qtmr_config_ ## n = { \ + .base = (void *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \ + .clock_subsys = \ + (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name), \ + .info = { \ + .max_top_value = UINT16_MAX, \ + .freq = DT_INST_PROP_OR(n, freq, 0), \ + .channels = 1, \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + }, \ + .channel = DT_INST_PROP(n, channel), \ + .qtmr_config = { \ + .debugMode = kQTMR_RunNormalInDebug, \ + .enableExternalForce = false, \ + .enableMasterMode = false, \ + .faultFilterCount = DT_INST_PROP_OR(n, filter_count, 0), \ + .faultFilterPeriod = DT_INST_PROP_OR(n, filter_count, 0), \ + .primarySource = DT_INST_ENUM_IDX(n, primary_source), \ + .secondarySource = DT_INST_ENUM_IDX_OR(n, secondary_source, 0), \ + }, \ + .mode = DT_INST_ENUM_IDX(n, mode), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + mcux_qtmr_init, \ + NULL, \ + &mcux_qtmr_data_ ## n, \ + &mcux_qtmr_config_ ## n, \ + POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &mcux_qtmr_driver_api); \ + +DT_INST_FOREACH_STATUS_OKAY(TMR_DEVICE_INIT_MCUX) diff --git a/dts/arm/nxp/nxp_rt.dtsi b/dts/arm/nxp/nxp_rt.dtsi index a711827bd5f..9e32d7763ce 100644 --- a/dts/arm/nxp/nxp_rt.dtsi +++ b/dts/arm/nxp/nxp_rt.dtsi @@ -120,6 +120,134 @@ label = "GPT2"; }; + qtmr1: qtmr@401dc000 { + compatible = "nxp,imx-qtmr"; + reg = <0x401dc000 0x7a>; + interrupts = <133 0>; + clocks = <&ccm IMX_CCM_QTMR_CLK 0 0>; + label = "QTMR1"; + qtmr1_timer0: timer0 { + compatible = "nxp,imx-tmr"; + channel = <0>; + label = "QTMR1_TIMER0"; + status = "disabled"; + }; + qtmr1_timer1: timer1 { + compatible = "nxp,imx-tmr"; + channel = <1>; + label = "QTMR1_TIMER1"; + status = "disabled"; + }; + qtmr1_timer2: timer2 { + compatible = "nxp,imx-tmr"; + channel = <2>; + label = "QTMR1_TIMER2"; + status = "disabled"; + }; + qtmr1_timer3: timer3 { + compatible = "nxp,imx-tmr"; + channel = <3>; + label = "QTMR1_TIMER3"; + status = "disabled"; + }; + }; + + qtmr2: qtmr@401e0000 { + compatible = "nxp,imx-qtmr"; + reg = <0x401e0000 0x7a>; + interrupts = <134 0>; + clocks = <&ccm IMX_CCM_QTMR_CLK 0 0>; + label = "QTMR2"; + qtmr2_timer0: timer0 { + compatible = "nxp,imx-tmr"; + channel = <0>; + label = "QTMR2_TIMER0"; + status = "disabled"; + }; + qtmr2_timer1: timer1 { + compatible = "nxp,imx-tmr"; + channel = <1>; + label = "QTMR2_TIMER1"; + status = "disabled"; + }; + qtmr2_timer2: timer2 { + compatible = "nxp,imx-tmr"; + channel = <2>; + label = "QTMR2_TIMER2"; + status = "disabled"; + }; + qtmr2_timer3: timer3 { + compatible = "nxp,imx-tmr"; + channel = <3>; + label = "QTMR2_TIMER3"; + status = "disabled"; + }; + }; + + qtmr3: qtmr@401e4000 { + compatible = "nxp,imx-qtmr"; + reg = <0x401e4000 0x7a>; + interrupts = <135 0>; + clocks = <&ccm IMX_CCM_QTMR_CLK 0 0>; + label = "QTMR3"; + qtmr3_timer0: timer0 { + compatible = "nxp,imx-tmr"; + channel = <0>; + label = "QTMR3_TIMER0"; + status = "disabled"; + }; + qtmr3_timer1: timer1 { + compatible = "nxp,imx-tmr"; + channel = <1>; + label = "QTMR3_TIMER1"; + status = "disabled"; + }; + qtmr3_timer2: timer2 { + compatible = "nxp,imx-tmr"; + channel = <2>; + label = "QTMR3_TIMER2"; + status = "disabled"; + }; + qtmr3_timer3: timer3 { + compatible = "nxp,imx-tmr"; + channel = <3>; + label = "QTMR3_TIMER3"; + status = "disabled"; + }; + }; + + qtmr4: qtmr@401e8000 { + compatible = "nxp,imx-qtmr"; + reg = <0x401e8000 0x7a>; + interrupts = <136 0>; + clocks = <&ccm IMX_CCM_QTMR_CLK 0 0>; + label = "QTMR4"; + qtmr4_timer0: timer0 { + compatible = "nxp,imx-tmr"; + channel = <0>; + label = "QTMR4_TIMER0"; + status = "disabled"; + }; + qtmr4_timer1: timer1 { + compatible = "nxp,imx-tmr"; + channel = <1>; + label = "QTMR4_TIMER1"; + status = "disabled"; + }; + qtmr4_timer2: timer2 { + compatible = "nxp,imx-tmr"; + channel = <2>; + label = "QTMR4_TIMER2"; + status = "disabled"; + }; + qtmr4_timer3: timer3 { + compatible = "nxp,imx-tmr"; + channel = <3>; + label = "QTMR4_TIMER3"; + status = "disabled"; + }; + }; + ccm: ccm@400fc000 { compatible = "nxp,imx-ccm"; reg = <0x400fc000 0x4000>; diff --git a/dts/bindings/counter/nxp,imx-qtmr.yaml b/dts/bindings/counter/nxp,imx-qtmr.yaml new file mode 100644 index 00000000000..c699c15c351 --- /dev/null +++ b/dts/bindings/counter/nxp,imx-qtmr.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCUX Quad Timer (QTMR) + +compatible: "nxp,imx-qtmr" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + label: + required: true diff --git a/dts/bindings/counter/nxp,imx-tmr.yaml b/dts/bindings/counter/nxp,imx-tmr.yaml new file mode 100644 index 00000000000..27d1fc5a720 --- /dev/null +++ b/dts/bindings/counter/nxp,imx-tmr.yaml @@ -0,0 +1,86 @@ +# Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCUX Quad Timer Channel. Each channel of each quad timer can operate independently + and hence will be realized as a separate counter device + +compatible: "nxp,imx-tmr" + +include: base.yaml + +properties: + label: + required: true + + channel: + type: int + required: true + enum: + - 0 + - 1 + - 2 + - 3 + + mode: + type: string + required: true + description: counting mode of the timer, see qtmr_counting_mode_t enumerator type + of the MCUXpresso SDK + enum: + - "kQTMR_NoOperation" + - "kQTMR_PriSrcRiseEdge" + - "kQTMR_PriSrcRiseAndFallEdge" + - "kQTMR_PriSrcRiseEdgeSecInpHigh" + - "kQTMR_QuadCountMode" + - "kQTMR_PriSrcRiseEdgeSecDir" + - "kQTMR_SecSrcTrigPriCnt" + - "kQTMR_CascadeCount" + + primary_source: + type: string + required: true + description: Primary source of the timer, see qtmr_primary_count_source_t enumerator type + of the MCUXpresso SDK + enum: + - "kQTMR_ClockCounter0InputPin" + - "kQTMR_ClockCounter1InputPin" + - "kQTMR_ClockCounter2InputPin" + - "kQTMR_ClockCounter3InputPin" + - "kQTMR_ClockCounter0Output" + - "kQTMR_ClockCounter1Output" + - "kQTMR_ClockCounter2Output" + - "kQTMR_ClockCounter3Output" + - "kQTMR_ClockDivide_1" + - "kQTMR_ClockDivide_2" + - "kQTMR_ClockDivide_4" + - "kQTMR_ClockDivide_8" + - "kQTMR_ClockDivide_16" + - "kQTMR_ClockDivide_32" + - "kQTMR_ClockDivide_64" + - "kQTMR_ClockDivide_128" + + secondary_source: + type: string + required: false + description: Secondary source of the timer, see qtmr_input_source_t enumerator type + of the MCUXpresso SDK + enum: + - "kQTMR_Counter0InputPin" + - "kQTMR_Counter1InputPin" + - "kQTMR_Counter2InputPin" + - "kQTMR_Counter3InputPin" + + filter_count: + type: int + required: false + description: Fault filter count (0-255). + + filter_period: + type: int + required: false + description: Fault filter period (0-255). + + freq: + type: int + required: false + description: clock frequency (only used for external clock sources) diff --git a/include/zephyr/dt-bindings/clock/imx_ccm.h b/include/zephyr/dt-bindings/clock/imx_ccm.h index 7c81b866f2f..6917595fcdf 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm.h @@ -45,4 +45,6 @@ #define IMX_CCM_PWM_CLK 0x0C00UL +#define IMX_CCM_QTMR_CLK 0x0D00UL + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_IMX_CCM_H_ */ diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index d319eedfb82..d547ffdd47e 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -136,6 +136,11 @@ config HAS_MCUX_GPT help Set if the general purpose timer (GPT) module is present in the SoC. +config HAS_MCUX_QTMR + bool + help + Set if the quad timer (QTMR) module is present in the SoC. + config HAS_MCUX_GPC bool help diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index 43e05cfa70c..712be942155 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -217,6 +217,7 @@ config SOC_MIMXRT1062 select HAS_MCUX_LPSPI select HAS_MCUX_LPUART select HAS_MCUX_GPT + select HAS_MCUX_QTMR select HAS_MCUX_SEMC select HAS_MCUX_TRNG select CPU_HAS_FPU_DOUBLE_PRECISION @@ -251,6 +252,7 @@ config SOC_MIMXRT1064 select HAS_MCUX_LPSPI select HAS_MCUX_LPUART select HAS_MCUX_GPT + select HAS_MCUX_QTMR select HAS_MCUX_SEMC select HAS_MCUX_SNVS select HAS_MCUX_SRC