diff --git a/boards/ti/sk_am62/sk_am62_am6254_a53.dts b/boards/ti/sk_am62/sk_am62_am6254_a53.dts index f6baa119150f..fb3b26696671 100644 --- a/boards/ti/sk_am62/sk_am62_am6254_a53.dts +++ b/boards/ti/sk_am62/sk_am62_am6254_a53.dts @@ -19,6 +19,10 @@ zephyr,sram = &ddr0; }; + aliases { + rtc = &counter_rtc0; + }; + cpus { cpu@0 { status = "okay"; @@ -103,3 +107,11 @@ ti,fails-without-test-cd; status = "disabled"; }; + +&main_rtc0 { + status = "okay"; +}; + +&counter_rtc0 { + status = "okay"; +}; diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index d45a8d7cfa27..36892039fe2e 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -68,3 +68,4 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_WUT_MAX32 counter_max32_wu zephyr_library_sources_ifdef(CONFIG_COUNTER_CC23X0_RTC counter_cc23x0_rtc.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_CC23X0_LGPT counter_cc23x0_lgpt.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MSPM0_TIMER counter_mspm0_timer.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_TI_K3_RTC counter_k3_rtc.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 5f1b8d29ac6f..8224c97aa81a 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -22,6 +22,20 @@ config COUNTER_SHELL help Enable Shell Commands for Counter and Timer +config COUNTER_64BITS_FREQ + bool + help + Select this option if the counter driver should use 64-bits for frequency. + This is typically set by drivers that have frequencies greater than + 4,294,967,295 Hz. + +config COUNTER_64BITS_TICKS + bool + help + Select this option if the counter driver should use 64-bits for ticks. + This is typically set by drivers that require extended + tick ranges beyond the 32-bit limit. + module = COUNTER module-str = counter source "subsys/logging/Kconfig.template.log_config" @@ -132,4 +146,6 @@ source "drivers/counter/Kconfig.cc23x0_lgpt" source "drivers/counter/Kconfig.mspm0" +source "drivers/counter/Kconfig.k3_rtc_counter" + endif # COUNTER diff --git a/drivers/counter/Kconfig.ace b/drivers/counter/Kconfig.ace index a7c5d611a92c..d3f24cb24e74 100644 --- a/drivers/counter/Kconfig.ace +++ b/drivers/counter/Kconfig.ace @@ -5,6 +5,7 @@ config ACE_V1X_ART_COUNTER bool "DSP ART Wall Clock for ACE V1X" depends on DT_HAS_INTEL_ACE_ART_COUNTER_ENABLED + select COUNTER_64BITS_TICKS default y help DSP ART Wall Clock used by ACE V1X. @@ -12,6 +13,7 @@ config ACE_V1X_ART_COUNTER config ACE_V1X_RTC_COUNTER bool "DSP RTC Wall Clock for ACE V1X" depends on DT_HAS_INTEL_ACE_RTC_COUNTER_ENABLED + select COUNTER_64BITS_TICKS default y help DSP RTC Wall Clock used by ACE V1X. diff --git a/drivers/counter/Kconfig.cc23x0_rtc b/drivers/counter/Kconfig.cc23x0_rtc index ce4e9ad6b2c1..0f04e9fb29c1 100644 --- a/drivers/counter/Kconfig.cc23x0_rtc +++ b/drivers/counter/Kconfig.cc23x0_rtc @@ -6,5 +6,6 @@ config COUNTER_CC23X0_RTC default y depends on DT_HAS_TI_CC23X0_RTC_ENABLED depends on CC23X0_SYSTIM_TIMER + select COUNTER_64BITS_TICKS help Enable counter driver based on RTC timer for cc23x0 diff --git a/drivers/counter/Kconfig.esp32_tmr b/drivers/counter/Kconfig.esp32_tmr index 099c1d820640..86d39871fc25 100644 --- a/drivers/counter/Kconfig.esp32_tmr +++ b/drivers/counter/Kconfig.esp32_tmr @@ -7,6 +7,7 @@ config COUNTER_TMR_ESP32 bool "ESP32 Counter Driver based on GP-Timers" default y depends on DT_HAS_ESPRESSIF_ESP32_COUNTER_ENABLED + select COUNTER_64BITS_TICKS help Enables the Counter driver API based on Espressif's General Purpose Timers for ESP32 series devices. diff --git a/drivers/counter/Kconfig.k3_rtc_counter b/drivers/counter/Kconfig.k3_rtc_counter new file mode 100644 index 000000000000..130bef27194c --- /dev/null +++ b/drivers/counter/Kconfig.k3_rtc_counter @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_TI_K3_RTC + bool "RTC Counter Driver for TI K3 SoCs" + default y + depends on DT_HAS_TI_K3_RTC_COUNTER_ENABLED + help + Enable the RTC driver for TI K3 SoCs. diff --git a/drivers/counter/Kconfig.stm32_rtc b/drivers/counter/Kconfig.stm32_rtc index 4273d1c49313..83ba82b57f80 100644 --- a/drivers/counter/Kconfig.stm32_rtc +++ b/drivers/counter/Kconfig.stm32_rtc @@ -23,6 +23,7 @@ config COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS config COUNTER_RTC_STM32_SUBSECONDS bool "Use the subseconds as a basic tick." depends on !SOC_SERIES_STM32F1X + select COUNTER_64BITS_TICKS help Use the subseconds as the basic time tick. It increases resolution of the counter. The frequency of the time is RTC Source Clock divided diff --git a/drivers/counter/counter_esp32_tmr.c b/drivers/counter/counter_esp32_tmr.c index 995b5101c2b1..49ab808526da 100644 --- a/drivers/counter/counter_esp32_tmr.c +++ b/drivers/counter/counter_esp32_tmr.c @@ -26,10 +26,10 @@ typedef bool (*timer_isr_t)(void *); struct counter_esp32_top_data { counter_top_callback_t callback; - uint32_t ticks; + uint64_t ticks; void *user_data; bool auto_reload; - uint32_t guard_period; + uint64_t guard_period; }; struct counter_esp32_config { @@ -45,9 +45,10 @@ struct counter_esp32_config { }; struct counter_esp32_data { - struct counter_alarm_cfg alarm_cfg; + struct counter_alarm_cfg_64 alarm_cfg; + counter_alarm_callback_t alarm_callback_32; struct counter_esp32_top_data top_data; - uint32_t ticks; + uint64_t ticks; uint32_t clock_src_hz; timer_hal_context_t hal_ctx; }; @@ -140,18 +141,18 @@ static int counter_esp32_get_value_64(const struct device *dev, uint64_t *ticks) return 0; } -static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, - const struct counter_alarm_cfg *alarm_cfg) +static int counter_esp32_set_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) { ARG_UNUSED(chan_id); struct counter_esp32_data *data = dev->data; bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE; - uint32_t ticks = alarm_cfg->ticks; - uint32_t top = data->top_data.ticks; - uint32_t max_rel_val = data->top_data.ticks; + uint64_t ticks = alarm_cfg->ticks; + uint64_t top = data->top_data.ticks; + uint64_t max_rel_val = data->top_data.ticks; uint64_t now; uint64_t target; - uint32_t diff; + uint64_t diff; int err = 0; bool irq_on_late = 0; @@ -177,7 +178,7 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id, target); - diff = (alarm_cfg->ticks - (uint32_t)now); + diff = (alarm_cfg->ticks - now); if (diff > max_rel_val) { if (absolute) { err = -ETIME; @@ -216,21 +217,22 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id) return 0; } -static int counter_esp32_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +static int counter_esp32_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg) { const struct counter_esp32_config *config = dev->config; struct counter_esp32_data *data = dev->data; - uint32_t now; + uint64_t now; if (data->alarm_cfg.callback) { return -EBUSY; } - if (cfg->ticks > config->counter_info.max_top_value) { + if (cfg->ticks > config->counter_info.max_top_value_64) { return -ENOTSUP; } - counter_esp32_get_value(dev, &now); + counter_esp32_get_value_64(dev, &now); if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) { timer_hal_set_counter_value(&data->hal_ctx, 0); @@ -267,7 +269,7 @@ static uint32_t counter_esp32_get_pending_int(const struct device *dev) return timer_ll_get_intr_status(data->hal_ctx.dev); } -static uint32_t counter_esp32_get_top_value(const struct device *dev) +static uint64_t counter_esp32_get_top_value_64(const struct device *dev) { struct counter_esp32_data *data = dev->data; @@ -291,7 +293,7 @@ static int counter_esp32_reset(const struct device *dev) return 0; } -static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_t flags) +static uint64_t counter_esp32_get_guard_period_64(const struct device *dev, uint32_t flags) { struct counter_esp32_data *data = dev->data; @@ -300,7 +302,8 @@ static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_ return data->top_data.guard_period; } -static int counter_esp32_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) +static int counter_esp32_set_guard_period_64(const struct device *dev, uint64_t ticks, + uint32_t flags) { struct counter_esp32_data *data = dev->data; @@ -314,6 +317,76 @@ static int counter_esp32_set_guard_period(const struct device *dev, uint32_t tic return 0; } +static int counter_esp32_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +{ + struct counter_top_cfg_64 alarm_cfg_64 = { + .callback = cfg->callback, + .ticks = (uint64_t)cfg->ticks, + .user_data = cfg->user_data, + .flags = cfg->flags, + }; + + return counter_esp32_set_top_value_64(dev, &alarm_cfg_64); +} + +static void counter_esp32_callback_32_trampoline(const struct device *dev, + uint8_t chan_id, + uint64_t ticks, + void *user_data) +{ + struct counter_esp32_data *data = dev->data; + + /* Safely call the original 32-bit callback */ + data->alarm_callback_32(dev, chan_id, (uint32_t)ticks, user_data); +} + +static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + struct counter_esp32_data *data = dev->data; + struct counter_alarm_cfg_64 alarm_cfg_64 = { + .callback = counter_esp32_callback_32_trampoline, + .ticks = (uint64_t)alarm_cfg->ticks, + .user_data = alarm_cfg->user_data, + .flags = alarm_cfg->flags, + }; + + /* use trampoline function to handle the function pointer type difference */ + data->alarm_callback_32 = alarm_cfg->callback; + + return counter_esp32_set_alarm_64(dev, chan_id, &alarm_cfg_64); +} + +static uint32_t counter_esp32_get_top_value(const struct device *dev) +{ + struct counter_esp32_data *data = dev->data; + + return (uint32_t)data->top_data.ticks; +} + +static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_t flags) +{ + struct counter_esp32_data *data = dev->data; + + ARG_UNUSED(flags); + + return (uint32_t)data->top_data.guard_period; +} + +static int counter_esp32_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) +{ + struct counter_esp32_data *data = dev->data; + + ARG_UNUSED(flags); + + if (ticks > data->top_data.ticks) { + return -EINVAL; + } + + data->top_data.guard_period = (uint64_t)ticks; + return 0; +} + static DEVICE_API(counter, counter_api) = { .start = counter_esp32_start, .stop = counter_esp32_stop, @@ -321,24 +394,29 @@ static DEVICE_API(counter, counter_api) = { .reset = counter_esp32_reset, .get_value_64 = counter_esp32_get_value_64, .set_alarm = counter_esp32_set_alarm, + .set_alarm_64 = counter_esp32_set_alarm_64, .cancel_alarm = counter_esp32_cancel_alarm, .set_top_value = counter_esp32_set_top_value, + .set_top_value_64 = counter_esp32_set_top_value_64, .get_pending_int = counter_esp32_get_pending_int, .get_top_value = counter_esp32_get_top_value, + .get_top_value_64 = counter_esp32_get_top_value_64, .get_freq = counter_esp32_get_freq, .get_guard_period = counter_esp32_get_guard_period, + .get_guard_period_64 = counter_esp32_get_guard_period_64, .set_guard_period = counter_esp32_set_guard_period, + .set_guard_period_64 = counter_esp32_set_guard_period_64, }; static void counter_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct counter_esp32_data *data = dev->data; - counter_alarm_callback_t cb = data->alarm_cfg.callback; + counter_alarm_callback_64_t cb = data->alarm_cfg.callback; void *cb_data = data->alarm_cfg.user_data; - uint32_t now; + uint64_t now; - counter_esp32_get_value(dev, &now); + counter_esp32_get_value_64(dev, &now); if (cb) { timer_ll_enable_intr(data->hal_ctx.dev, @@ -374,7 +452,7 @@ static void counter_esp32_isr(void *arg) static struct counter_esp32_data counter_data_##idx; \ \ static const struct counter_esp32_config counter_config_##idx = { \ - .counter_info = {.max_top_value = UINT32_MAX, \ + .counter_info = {.max_top_value_64 = UINT64_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ .config = \ diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 697d8d41f963..263e764bb21d 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -73,6 +73,7 @@ static inline int z_vrfy_counter_get_value(const struct device *dev, } #include +#ifdef CONFIG_COUNTER_64BITS_TICKS static inline int z_vrfy_counter_get_value_64(const struct device *dev, uint64_t *ticks) { @@ -81,6 +82,7 @@ static inline int z_vrfy_counter_get_value_64(const struct device *dev, return z_impl_counter_get_value_64((const struct device *)dev, ticks); } #include +#endif /* CONFIG_COUNTER_64BITS_TICKS */ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, diff --git a/drivers/counter/counter_k3_rtc.c b/drivers/counter/counter_k3_rtc.c new file mode 100644 index 000000000000..d05ca1ab8d4e --- /dev/null +++ b/drivers/counter/counter_k3_rtc.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2026 Texas Instruments Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_k3_rtc_counter + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(counter_ti_k3_rtc, CONFIG_COUNTER_LOG_LEVEL); + +#define RTC_MAX_TOP_VALUE UINT32_MAX +#define RTC_MAX_TOP_VALUE_64 BIT_MASK(48) + +#define K3_RTC_KICK0_UNLOCK 0x83e70b13 +#define K3_RTC_KICK1_UNLOCK 0x95a4f1e0 + +#define RTC_CNT_FMODE_MASK BIT(25) +#define RTC_UNLOCK_MASK BIT(23) +#define RTC_O32K_OSC_MASK BIT(21) +#define RTC_SYNCPEND_STATUS_MASK BIT_MASK(2) + +#define RTC_IRQ_ALARM1_MASK BIT(0) +#define RTC_IRQ_ALARM2_MASK BIT(1) +#define RTC_IRQ_STATUS_MASK BIT_MASK(2) + +#define DEV_CFG(dev) ((const struct k3_rtc_counter_cfg *)(dev)->config) +#define DEV_DATA(dev) ((struct k3_rtc_counter_data *)(dev)->data) +#define DEV_REGS(dev) ((k3_rtc_regs_t *)DEVICE_MMIO_NAMED_GET(dev, reg_base)) + +typedef struct { + volatile uint32_t MOD_VER; /* Module ID and Version - 0h */ + volatile uint32_t SUB_S_CNT; /* SubSecondCount - 4h*/ + volatile uint32_t S_CNT_LSW; /* SecondCount_31_0 - 8h */ + volatile uint32_t S_CNT_MSW; /* SecondCount_47_32 - Ch */ + volatile uint32_t COMP; /* Compensation - 10h */ + uint8_t Resv_24[4]; + volatile uint32_t OFF_ON_S_CNT_LSW; /* OffOnSCnt_31_0 - 18h */ + volatile uint32_t OFF_ON_S_CNT_MSW; /* OffOnSCnt_47_32 - 1Ch */ + volatile uint32_t ON_OFF_S_CNT_LSW; /* OnOffSCnt_31_0 - 20h */ + volatile uint32_t ON_OFF_S_CNT_MSW; /* OnOffSCnt_47_32 - 24h */ + volatile uint32_t DEBOUNCE; /* Debounce - 28h */ + volatile uint32_t ANALOG; /* AnalogCfg - 2Ch */ + volatile uint32_t SCRATCH[8]; /* Scratch Storage X - 30h */ + volatile uint32_t GENRAL_CTL; /* GeneralControl - 50h */ + volatile uint32_t IRQSTATUS_RAW_SYS; /* Interrupt Raw Status Register - 54h */ + volatile uint32_t IRQSTATUS_SYS; /* Interrupt Status Register - 58h */ + volatile uint32_t IRQENABLE_SET_SYS; /* Interrupt Enable Set Register - 5Ch */ + volatile uint32_t IRQENABLE_CLR_SYS; /* Interrupt Enable Clear Register - 60h */ + uint8_t Resv_104[4]; /* SyncPending - 68h */ + volatile uint32_t SYNCPEND; + uint8_t Resv_112[4]; + volatile uint32_t KICK0; /* Kick0 - 70h */ + volatile uint32_t KICK1; /* Kick1 - 74h */ + uint8_t Resv_128[8]; +} k3_rtc_regs_t; + +struct k3_rtc_counter_cfg { + struct counter_config_info counter_info; + + DEVICE_MMIO_NAMED_ROM(reg_base); + + void (*irq_config_func)(void); + uint32_t osc_freq; +}; + +struct k3_rtc_counter_data { + DEVICE_MMIO_NAMED_RAM(reg_base); +#ifdef CONFIG_COUNTER_64BITS_TICKS + struct counter_alarm_cfg_64 alarm_cfg[2]; +#else + struct counter_alarm_cfg alarm_cfg[2]; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + uint32_t sync_timeout_us; +}; + +static int k3_rtc_fence(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + + /* Add slight delay in order to wait for register writes to sync */ + k_usleep(data->sync_timeout_us); + int timeout = WAIT_FOR((rtc_regs->SYNCPEND & RTC_SYNCPEND_STATUS_MASK) != 0, + data->sync_timeout_us, + k_busy_wait(1)); + + return timeout; +} + +static int k3_rtc_unlock_status(k3_rtc_regs_t *rtc_regs) +{ + return !!(rtc_regs->GENRAL_CTL & RTC_UNLOCK_MASK); +} + +static int k3_rtc_unlock(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + if (k3_rtc_unlock_status(rtc_regs) == 0) { + rtc_regs->KICK0 = K3_RTC_KICK0_UNLOCK; + rtc_regs->KICK1 = K3_RTC_KICK1_UNLOCK; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after unlock"); + return ret; + } + + if (k3_rtc_unlock_status(rtc_regs) == 0) { + LOG_ERR("RTC unlock failed!"); + return -EIO; + } + } + + return 0; +} + +static int k3_counter_start(const struct device *dev) +{ + ARG_UNUSED(dev); + /* RTC counter runs after power-on reset */ + return 0; +} + +static int k3_counter_stop(const struct device *dev) +{ + ARG_UNUSED(dev); + /* RTC counter can only be reset, not stopped */ + return 0; +} + +static int k3_counter_get_value(const struct device *dev, uint32_t *ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + if (ticks == NULL) { + return -EINVAL; + } + + *ticks = rtc_regs->S_CNT_LSW; + + return 0; +} + +static int k3_counter_set_value(const struct device *dev, uint32_t ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + rtc_regs->S_CNT_LSW = ticks; + rtc_regs->S_CNT_MSW = 0; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after set_value"); + return ret; + } + + return 0; +} + +static int k3_counter_reset(const struct device *dev) +{ + int ret; + + ret = k3_counter_set_value(dev, 0); + if (ret != 0) { + LOG_ERR("Failed to sync after reset"); + return ret; + } + + return 0; +} + +static int k3_counter_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + if (alarm_cfg == NULL) { + LOG_ERR("NULL alarm config"); + return -EINVAL; + } + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) != 0) { + data->alarm_cfg[chan_id].ticks = alarm_cfg->ticks; + } else { + uint32_t now; + + ret = k3_counter_get_value(dev, &now); + if (ret != 0) { + return ret; + } + data->alarm_cfg[chan_id].ticks = now + alarm_cfg->ticks; + } + + key = irq_lock(); + + if (chan_id == 0) { + rtc_regs->ON_OFF_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->ON_OFF_S_CNT_MSW = 0; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->OFF_ON_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->OFF_ON_S_CNT_MSW = 0; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm set: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = alarm_cfg->callback; + data->alarm_cfg[chan_id].user_data = alarm_cfg->user_data; + + irq_unlock(key); + + return 0; +} + +static int k3_counter_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + key = irq_lock(); + if (chan_id == 0) { + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm cancel: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = NULL; + data->alarm_cfg[chan_id].user_data = NULL; + data->alarm_cfg[chan_id].flags = 0; + + irq_unlock(key); + + return 0; +} + +static uint32_t k3_counter_get_pending_int(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + return rtc_regs->IRQSTATUS_SYS & RTC_IRQ_STATUS_MASK; +} + +static uint32_t k3_counter_get_top_value(const struct device *dev) +{ + ARG_UNUSED(dev); + return RTC_MAX_TOP_VALUE; +} + +static uint32_t k3_counter_get_frequency(const struct device *dev) +{ + const struct k3_rtc_counter_cfg *config = DEV_CFG(dev); + + return config->counter_info.freq; +} + +#ifdef CONFIG_COUNTER_64BITS_TICKS +static int k3_counter_get_value_64(const struct device *dev, uint64_t *ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + if (ticks == NULL) { + return -EINVAL; + } + + uint32_t seconds_low = rtc_regs->S_CNT_LSW; + uint32_t seconds_high = rtc_regs->S_CNT_MSW; + + *ticks = ((uint64_t)seconds_high << 32) | (uint64_t)seconds_low; + + return 0; +} + +static int k3_counter_set_value_64(const struct device *dev, uint64_t ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + rtc_regs->S_CNT_LSW = ticks; + rtc_regs->S_CNT_MSW = (uint32_t)(ticks >> 32); + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after set_value"); + return ret; + } + + return 0; +} + +static uint64_t k3_counter_get_top_value_64(const struct device *dev) +{ + ARG_UNUSED(dev); + return RTC_MAX_TOP_VALUE_64; +} + +static int k3_counter_set_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + if (alarm_cfg == NULL) { + LOG_ERR("NULL alarm config"); + return -EINVAL; + } + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) != 0) { + data->alarm_cfg[chan_id].ticks = alarm_cfg->ticks; + } else { + uint64_t now; + + ret = k3_counter_get_value_64(dev, &now); + if (ret != 0) { + return ret; + } + data->alarm_cfg[chan_id].ticks = now + alarm_cfg->ticks; + } + + key = irq_lock(); + + if (chan_id == 0) { + rtc_regs->ON_OFF_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->ON_OFF_S_CNT_MSW = (uint32_t)(data->alarm_cfg[chan_id].ticks >> 32); + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->OFF_ON_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->OFF_ON_S_CNT_MSW = (uint32_t)(data->alarm_cfg[chan_id].ticks >> 32); + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm set: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = alarm_cfg->callback; + data->alarm_cfg[chan_id].user_data = alarm_cfg->user_data; + data->alarm_cfg[chan_id].flags = alarm_cfg->flags; + + irq_unlock(key); + + return 0; +} +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + +static void k3_rtc_isr(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + uint32_t status; + int ret; +#ifdef CONFIG_COUNTER_64BITS_TICKS + uint64_t now; +#else + uint32_t now; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + + status = rtc_regs->IRQSTATUS_SYS; + if (status == 0) { + return; + } + + rtc_regs->IRQSTATUS_SYS = status; + + if ((status & RTC_IRQ_ALARM1_MASK) != 0 && data->alarm_cfg[0].callback != NULL) { +#ifdef CONFIG_COUNTER_64BITS_TICKS + ret = k3_counter_get_value_64(dev, &now); +#else + ret = k3_counter_get_value(dev, &now); +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + if (ret != 0) { + LOG_ERR("Invalid ticks: %d", ret); + return; + } + data->alarm_cfg[0].callback(dev, 0, now, data->alarm_cfg[0].user_data); + } + + if ((status & RTC_IRQ_ALARM2_MASK) != 0 && data->alarm_cfg[1].callback != NULL) { +#ifdef CONFIG_COUNTER_64BITS_TICKS + k3_counter_get_value_64(dev, &now); +#else + k3_counter_get_value(dev, &now); +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + data->alarm_cfg[1].callback(dev, 1, now, data->alarm_cfg[1].user_data); + } +} + +static int k3_counter_init(const struct device *dev) +{ + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE); + const struct k3_rtc_counter_cfg *config = DEV_CFG(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + ret = k3_rtc_unlock(dev); + if (ret != 0) { + LOG_ERR("Failed to unlock RTC"); + return ret; + } + + /* 4 clock cycles for sync */ + data->sync_timeout_us = (USEC_PER_SEC / config->osc_freq) * 4; + + /* Enable 32k oscillator dependency */ + rtc_regs->GENRAL_CTL |= RTC_O32K_OSC_MASK; + + /* Enable freeze mode for atomic 48-bit reads */ + rtc_regs->GENRAL_CTL |= RTC_CNT_FMODE_MASK; + + /* Clear and disable all interrupts */ + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_STATUS_MASK; + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_STATUS_MASK; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed sync in init"); + return ret; + } + + config->irq_config_func(); + + return 0; +} + +static const struct counter_driver_api k3_counter_api = { + .start = k3_counter_start, + .stop = k3_counter_stop, + .get_value = k3_counter_get_value, + .reset = k3_counter_reset, + .set_value = k3_counter_set_value, + .set_alarm = k3_counter_set_alarm, + .cancel_alarm = k3_counter_cancel_alarm, + .get_pending_int = k3_counter_get_pending_int, + .get_top_value = k3_counter_get_top_value, + .get_freq = k3_counter_get_frequency, +#ifdef CONFIG_COUNTER_64BITS_TICKS + .get_value_64 = k3_counter_get_value_64, + .set_value_64 = k3_counter_set_value_64, + .set_alarm_64 = k3_counter_set_alarm_64, + .get_top_value_64 = k3_counter_get_top_value_64, +#endif /* CONFIG_COUNTER_64BITS_TICKS */ +}; + +#define TI_K3_COUNTER_INIT(i) \ + static void ti_k3_counter_irq_config_##i(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(i), \ + DT_INST_IRQ(i, priority), \ + k3_rtc_isr, \ + DEVICE_DT_INST_GET(i), 0); \ + irq_enable(DT_INST_IRQN(i)); \ + } \ + static struct k3_rtc_counter_data k3_counter_data_##i = {}; \ + static struct k3_rtc_counter_cfg k3_counter_cfg_##i = { \ + .counter_info = \ + { \ + .freq = 1, \ + COND_CODE_1(CONFIG_COUNTER_64BITS_TICKS, \ + (.max_top_value_64 = RTC_MAX_TOP_VALUE_64,), \ + (.max_top_value = RTC_MAX_TOP_VALUE,)) \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 2, \ + }, \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(i)), \ + .irq_config_func = ti_k3_counter_irq_config_##i, \ + .osc_freq = DT_INST_PROP(i, clock_frequency) \ + }; \ + DEVICE_DT_INST_DEFINE(i, \ + k3_counter_init, \ + NULL, \ + &k3_counter_data_##i, \ + &k3_counter_cfg_##i, \ + POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &k3_counter_api \ + ); + +DT_INST_FOREACH_STATUS_OKAY(TI_K3_COUNTER_INIT) diff --git a/drivers/sensor/sensor_clock_external.c b/drivers/sensor/sensor_clock_external.c index 5baf1ac15639..f86e9425572e 100644 --- a/drivers/sensor/sensor_clock_external.c +++ b/drivers/sensor/sensor_clock_external.c @@ -40,12 +40,15 @@ int sensor_clock_get_cycles(uint64_t *cycles) __ASSERT_NO_MSG(counter_is_counting_up(external_sensor_clock)); int rc; +#ifdef COUNTER_64BITS_TICKS const struct counter_driver_api *api = (const struct counter_driver_api *)external_sensor_clock->api; if (api->get_value_64) { rc = counter_get_value_64(external_sensor_clock, cycles); - } else { + } else +#endif /* COUNTER_64BITS_TICKS */ + { uint32_t result_32; rc = counter_get_value(external_sensor_clock, &result_32); diff --git a/dts/arm64/ti/ti_am62x_a53.dtsi b/dts/arm64/ti/ti_am62x_a53.dtsi index 2e20926e4746..4cf5a54df41e 100644 --- a/dts/arm64/ti/ti_am62x_a53.dtsi +++ b/dts/arm64/ti/ti_am62x_a53.dtsi @@ -154,3 +154,8 @@ interrupts = ; interrupt-parent = <&gic>; }; + +&main_rtc0 { + interrupts = ; + interrupt-parent = <&gic>; +}; diff --git a/dts/bindings/counter/ti,k3-rtc-counter.yaml b/dts/bindings/counter/ti,k3-rtc-counter.yaml new file mode 100644 index 000000000000..71134b70bf96 --- /dev/null +++ b/dts/bindings/counter/ti,k3-rtc-counter.yaml @@ -0,0 +1,19 @@ +# Copyright 2026 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Counter based Real Time Clock (RTC) available in the TI K3 generation of processors. + +compatible: "ti,k3-rtc-counter" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clock-frequency: + type: int + required: true diff --git a/dts/vendor/ti/k3-am62-main.dtsi b/dts/vendor/ti/k3-am62-main.dtsi index 17a4f32ff1c3..e2e86b578fc9 100644 --- a/dts/vendor/ti/k3-am62-main.dtsi +++ b/dts/vendor/ti/k3-am62-main.dtsi @@ -216,4 +216,17 @@ ti,itap-del-sel-sdr25 = <0x0>; status = "disabled"; }; + + main_rtc0: rtc@2b1f0000 { + compatible = "ti,k3-rtc-counter"; + reg = <0x2b1f0000 0x64>; + clock-frequency = <32768>; + status = "disabled"; + + counter_rtc0: counter_rtc { + compatible = "zephyr,rtc-counter"; + alarms-count = <2>; + status = "disabled"; + }; + }; }; diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 8334f504ba14..c49a9f7d5ba8 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -1309,7 +1309,7 @@ static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec, * * @param spec ADC specification from devicetree * - * @retval true if the ADC device is ready for use and false otherwise. + * @return true if the ADC device is ready for use and false otherwise. */ static inline bool adc_is_ready_dt(const struct adc_dt_spec *spec) { diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 4cfa440b705b..de60bae43303 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -1002,7 +1002,7 @@ static inline const struct can_timing *z_impl_can_get_timing_data_max(const stru * @param sample_pnt Sample point for the data phase in permille of the entire bit * time or 0 for automatic sample point location. * - * @retval 0 or positive sample point error on success. + * @return 0 or positive sample point error on success. * @retval -EINVAL if the requested bitrate or sample point is out of range. * @retval -ENOTSUP if the requested bitrate is not supported. * @retval -EIO if @a can_get_core_clock() is not available. @@ -1387,7 +1387,7 @@ static inline void z_impl_can_remove_rx_filter(const struct device *dev, int fil * @param ide Get the maximum standard (11-bit) CAN ID filters if false, or extended (29-bit) CAN ID * filters if true. * - * @retval Positive number of maximum concurrent filters. + * @retval >=0 number of maximum concurrent filters. * @retval -EIO General input/output error. * @retval -ENOSYS If this function is not implemented by the driver. */ @@ -1684,7 +1684,7 @@ static inline uint32_t z_impl_can_stats_get_rx_overruns(const struct device *dev * * @param dlc Data Length Code (DLC). * - * @retval Number of bytes. + * @return Number of bytes. */ static inline uint8_t can_dlc_to_bytes(uint8_t dlc) { @@ -1699,7 +1699,7 @@ static inline uint8_t can_dlc_to_bytes(uint8_t dlc) * * @param num_bytes Number of bytes. * - * @retval Data Length Code (DLC). + * @return Data Length Code (DLC). */ static inline uint8_t can_bytes_to_dlc(uint8_t num_bytes) { diff --git a/include/zephyr/drivers/cellular.h b/include/zephyr/drivers/cellular.h index ba78207a340c..2df3af846167 100644 --- a/include/zephyr/drivers/cellular.h +++ b/include/zephyr/drivers/cellular.h @@ -237,7 +237,7 @@ __subsystem struct cellular_driver_api { * @retval 0 if successful. * @retval -EINVAL if any provided cellular network configuration is invalid or unsupported. * @retval -ENOTSUP if API is not supported by cellular network device. - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_configure_networks(const struct device *dev, const struct cellular_network *networks, uint8_t size) @@ -260,7 +260,7 @@ static inline int cellular_configure_networks(const struct device *dev, * * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_get_supported_networks(const struct device *dev, const struct cellular_network **networks, @@ -285,7 +285,7 @@ static inline int cellular_get_supported_networks(const struct device *dev, * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. * @retval -ENODATA if device is not in a state where signal can be polled - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_get_signal(const struct device *dev, const enum cellular_signal_type type, int16_t *value) @@ -310,7 +310,7 @@ static inline int cellular_get_signal(const struct device *dev, * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. * @retval -ENODATA if modem does not provide info requested - * @retval Negative errno-code from chat module otherwise. + * @retval <0 Negative errno-code from chat module otherwise. */ static inline int cellular_get_modem_info(const struct device *dev, const enum cellular_modem_info_type type, char *info, @@ -335,7 +335,7 @@ static inline int cellular_get_modem_info(const struct device *dev, * @retval 0 if successful. * @retval -ENOSYS if API is not supported by cellular network device. * @retval -ENODATA if modem does not provide info requested - * @retval Negative errno-code from chat module otherwise. + * @retval <0 Negative errno-code from chat module otherwise. */ static inline int cellular_get_registration_status(const struct device *dev, enum cellular_access_technology tech, @@ -364,7 +364,7 @@ static inline int cellular_get_registration_status(const struct device *dev, * @retval -EINVAL if APN string invalid or too long. * @retval -EALREADY if APN identical to current one, nothing to do * @retval -EBUSY if modem is already dialled, APN cannot be changed - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_set_apn(const struct device *dev, const char *apn) { diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 27e4602560e2..a49a7a61b5d0 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -376,7 +376,7 @@ __subsystem struct charger_driver_api { * @param val Pointer to charger_propval union * * @retval 0 if successful - * @retval < 0 if getting property failed + * @retval <0 if getting property failed */ __syscall int charger_get_prop(const struct device *dev, const charger_prop_t prop, union charger_propval *val); @@ -397,7 +397,7 @@ static inline int z_impl_charger_get_prop(const struct device *dev, const charge * @param val Pointer to charger_propval union * * @retval 0 if successful - * @retval < 0 if setting property failed + * @retval <0 if setting property failed */ __syscall int charger_set_prop(const struct device *dev, const charger_prop_t prop, const union charger_propval *val); diff --git a/include/zephyr/drivers/clock_control.h b/include/zephyr/drivers/clock_control.h index d09daf963860..1ef3cd01f88b 100644 --- a/include/zephyr/drivers/clock_control.h +++ b/include/zephyr/drivers/clock_control.h @@ -174,7 +174,7 @@ static inline int clock_control_off(const struct device *dev, * @retval -EALREADY if clock was already started and is starting or running. * @retval -ENOTSUP If the requested mode of operation is not supported. * @retval -ENOSYS if the interface is not implemented. - * @retval other negative errno on vendor specific error. + * @retval <0 other negative errno on vendor specific error. */ static inline int clock_control_async_on(const struct device *dev, clock_control_subsys_t sys, @@ -252,7 +252,7 @@ static inline int clock_control_get_rate(const struct device *dev, * @retval -EALREADY if clock was already in the given rate. * @retval -ENOTSUP If the requested mode of operation is not supported. * @retval -ENOSYS if the interface is not implemented. - * @retval other negative errno on vendor specific error. + * @retval <0 other negative errno on vendor specific error. */ static inline int clock_control_set_rate(const struct device *dev, clock_control_subsys_t sys, diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index ca3a35183f41..bb6ae869141d 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -18,7 +18,7 @@ * @brief Interfaces for counters. * @defgroup counter_interface Counter * @since 1.14 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ @@ -93,7 +93,7 @@ extern "C" { * * Alarm callback must be called from the same context as if it was set on time. */ -#define COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE BIT(1) +#define COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE BIT(1) /**@} */ @@ -120,8 +120,7 @@ extern "C" { * @param ticks Counter value that triggered the alarm. * @param user_data User data. */ -typedef void (*counter_alarm_callback_t)(const struct device *dev, - uint8_t chan_id, uint32_t ticks, +typedef void (*counter_alarm_callback_t)(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data); /** @brief Alarm callback structure. @@ -163,8 +162,7 @@ struct counter_alarm_cfg { * @param dev Pointer to the device structure for the driver instance. * @param user_data User data provided in @ref counter_set_top_value. */ -typedef void (*counter_top_callback_t)(const struct device *dev, - void *user_data); +typedef void (*counter_top_callback_t)(const struct device *dev, void *user_data); /** @brief Top value configuration structure. */ @@ -190,14 +188,33 @@ struct counter_top_cfg { /** @brief Structure with generic counter features. */ struct counter_config_info { - /** - * Maximal (default) top value on which counter is reset (cleared or reloaded). - */ - uint32_t max_top_value; /** * Frequency of the source clock if synchronous events are counted. */ +#ifdef CONFIG_COUNTER_64BITS_FREQ + uint64_t freq; +#else uint32_t freq; +#endif + /** + * Maximal (default) top value on which counter is reset (cleared or reloaded). + */ +#ifdef CONFIG_COUNTER_64BITS_TICKS + union { + uint64_t max_top_value_64; + struct { +#ifdef CONFIG_BIG_ENDIAN + uint32_t reserved; + uint32_t max_top_value; +#else + uint32_t max_top_value; + uint32_t reserved; +#endif /* CONFIG_BIG_ENDIAN */ + }; + }; +#else + uint32_t max_top_value; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ /** * Flags (see @ref COUNTER_FLAGS). */ @@ -210,35 +227,106 @@ struct counter_config_info { uint8_t channels; }; +/** @brief Alarm callback + * + * @param dev Pointer to the device structure for the driver instance. + * @param chan_id Channel ID. + * @param ticks Counter value that triggered the alarm. + * @param user_data User data. + */ +typedef void (*counter_alarm_callback_64_t)(const struct device *dev, uint8_t chan_id, + uint64_t ticks, void *user_data); + +/** @brief Alarm callback structure. + */ +struct counter_alarm_cfg_64 { + /** + * Number of ticks that triggers the alarm. + * + * It can be relative (to now) or an absolute value (see @ref + * COUNTER_ALARM_CFG_ABSOLUTE). Both, relative and absolute, alarm + * values can be any value between zero and the current top value (see + * @ref counter_get_top_value). When setting an absolute alarm value + * close to the current counter value there is a risk that the counter + * will have counted past the given absolute value before the driver + * manages to activate the alarm. Therefore a guard period can be + * defined that lets the driver decide unambiguously whether it is late + * or not (see @ref counter_set_guard_period). If the counter is clock + * driven then ticks can be converted to microseconds (see @ref + * counter_ticks_to_us). Alternatively, the counter implementation may + * count asynchronous events. + */ + uint64_t ticks; + /** + * Callback called on alarm (cannot be NULL). + */ + counter_alarm_callback_64_t callback; + /** + * User data returned in callback. + */ + void *user_data; + /** + * Alarm flags (see @ref COUNTER_ALARM_FLAGS). + */ + uint32_t flags; +}; + +/** @brief Top value configuration structure. + */ +struct counter_top_cfg_64 { + /** + * Top value. + */ + uint64_t ticks; + /** + * Callback function (can be NULL). + */ + counter_top_callback_t callback; + /** + * User data passed to callback function (not valid if callback is NULL). + */ + void *user_data; + /** + * Flags (see @ref COUNTER_TOP_FLAGS). + */ + uint32_t flags; +}; + typedef int (*counter_api_start)(const struct device *dev); typedef int (*counter_api_stop)(const struct device *dev); -typedef int (*counter_api_get_value)(const struct device *dev, - uint32_t *ticks); -typedef int (*counter_api_get_value_64)(const struct device *dev, - uint64_t *ticks); +typedef int (*counter_api_get_value)(const struct device *dev, uint32_t *ticks); typedef int (*counter_api_reset)(const struct device *dev); -typedef int (*counter_api_set_alarm)(const struct device *dev, - uint8_t chan_id, +typedef int (*counter_api_set_value)(const struct device *dev, uint32_t ticks); +typedef int (*counter_api_set_alarm)(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); -typedef int (*counter_api_cancel_alarm)(const struct device *dev, - uint8_t chan_id); +typedef int (*counter_api_cancel_alarm)(const struct device *dev, uint8_t chan_id); typedef int (*counter_api_set_top_value)(const struct device *dev, const struct counter_top_cfg *cfg); typedef uint32_t (*counter_api_get_pending_int)(const struct device *dev); typedef uint32_t (*counter_api_get_top_value)(const struct device *dev); -typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev, - uint32_t flags); -typedef int (*counter_api_set_guard_period)(const struct device *dev, - uint32_t ticks, - uint32_t flags); +typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev, uint32_t flags); +typedef int (*counter_api_set_guard_period)(const struct device *dev, uint32_t ticks, + uint32_t flags); typedef uint32_t (*counter_api_get_freq)(const struct device *dev); +typedef uint64_t (*counter_api_get_freq_64)(const struct device *dev); + +typedef int (*counter_api_get_value_64)(const struct device *dev, uint64_t *ticks); +typedef int (*counter_api_set_value_64)(const struct device *dev, uint64_t ticks); +typedef int (*counter_api_set_alarm_64)(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg); +typedef uint64_t (*counter_api_get_guard_period_64)(const struct device *dev, uint32_t flags); +typedef int (*counter_api_set_guard_period_64)(const struct device *dev, uint64_t ticks, + uint32_t flags); +typedef uint64_t (*counter_api_get_top_value_64)(const struct device *dev); +typedef int (*counter_api_set_top_value_64)(const struct device *dev, + const struct counter_top_cfg_64 *cfg); __subsystem struct counter_driver_api { counter_api_start start; counter_api_stop stop; counter_api_get_value get_value; - counter_api_get_value_64 get_value_64; counter_api_reset reset; + counter_api_set_value set_value; counter_api_set_alarm set_alarm; counter_api_cancel_alarm cancel_alarm; counter_api_set_top_value set_top_value; @@ -247,6 +335,18 @@ __subsystem struct counter_driver_api { counter_api_get_guard_period get_guard_period; counter_api_set_guard_period set_guard_period; counter_api_get_freq get_freq; +#ifdef CONFIG_COUNTER_64BITS_FREQ + counter_api_get_freq_64 get_freq_64; +#endif /* CONFIG_COUNTER_64BITS_FREQ */ +#ifdef CONFIG_COUNTER_64BITS_TICKS + counter_api_get_value_64 get_value_64; + counter_api_set_value_64 set_value_64; + counter_api_set_alarm_64 set_alarm_64; + counter_api_get_guard_period_64 get_guard_period_64; + counter_api_set_guard_period_64 set_guard_period_64; + counter_api_get_top_value_64 get_top_value_64; + counter_api_set_top_value_64 set_top_value_64; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ }; /** @@ -261,8 +361,7 @@ __syscall bool counter_is_counting_up(const struct device *dev); static inline bool z_impl_counter_is_counting_up(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->flags & COUNTER_CONFIG_INFO_COUNT_UP; } @@ -278,31 +377,89 @@ __syscall uint8_t counter_get_num_of_channels(const struct device *dev); static inline uint8_t z_impl_counter_get_num_of_channels(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->channels; } +__syscall uint32_t counter_get_frequency(const struct device *dev); + +#ifdef CONFIG_COUNTER_64BITS_FREQ /** * @brief Function to get counter frequency. * * @param[in] dev Pointer to the device structure for the driver instance. * * @return Frequency of the counter in Hz, or zero if the counter does - * not have a fixed frequency. + * not have a fixed frequency, or UINT32_MAX if the counter frequency + * is higher or equal to UINT32_MAX, in which case it is recommended to + * use counter_get_frequency_64(). */ -__syscall uint32_t counter_get_frequency(const struct device *dev); +static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) +{ + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (api->get_freq) { + return api->get_freq(dev); + } else { + return config->freq > UINT32_MAX ? UINT32_MAX : (uint32_t)config->freq; + } +} + +#else +/** + * @brief Function to get counter frequency. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Frequency of the counter in Hz, or zero if the counter does + * not have a fixed frequency. + */ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_freq ? api->get_freq(dev) : config->freq; } +#endif + +/** + * @brief Function to get counter frequency in 64bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Frequency of the counter in Hz, or zero if the counter does + * not have a fixed frequency. + */ +__syscall uint64_t counter_get_frequency_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_frequency_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_FREQ + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (api->get_freq_64) { + return api->get_freq_64(dev); + } else if (api->get_freq) { + return (uint64_t)api->get_freq(dev); + } else { + return config->freq; + } +#else + ARG_UNUSED(dev); + return -ENOTSUP; +#endif +} + +#ifdef CONFIG_COUNTER_64BITS_FREQ +#define z_counter_get_frequency z_impl_counter_get_frequency_64 +#else +#define z_counter_get_frequency z_impl_counter_get_frequency +#endif /** * @brief Function to convert microseconds to ticks. @@ -314,14 +471,28 @@ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) */ __syscall uint32_t counter_us_to_ticks(const struct device *dev, uint64_t us); -static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, - uint64_t us) +static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, uint64_t us) { - uint64_t ticks = (us * z_impl_counter_get_frequency(dev)) / USEC_PER_SEC; + uint64_t ticks = (us * z_counter_get_frequency(dev)) / USEC_PER_SEC; return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; } +/** + * @brief Function to convert microseconds to ticks with 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] us Microseconds. + * + * @return Converted ticks as a uint64_t + */ +__syscall uint64_t counter_us_to_ticks_64(const struct device *dev, uint64_t us); + +static inline uint64_t z_impl_counter_us_to_ticks_64(const struct device *dev, uint64_t us) +{ + return (us * z_counter_get_frequency(dev)) / USEC_PER_SEC; +} + /** * @brief Function to convert ticks to microseconds. * @@ -332,10 +503,56 @@ static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, */ __syscall uint64_t counter_ticks_to_us(const struct device *dev, uint32_t ticks); -static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, - uint32_t ticks) +static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, uint32_t ticks) { - return ((uint64_t)ticks * USEC_PER_SEC) / z_impl_counter_get_frequency(dev); + return ((uint64_t)ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); +} + +/** + * @brief Function to convert ticks with 64 bits to microseconds. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ticks Ticks in 64 bits. + * + * @return Converted microseconds. + */ +__syscall uint64_t counter_ticks_to_us_64(const struct device *dev, uint64_t ticks); + +static inline uint64_t z_impl_counter_ticks_to_us_64(const struct device *dev, uint64_t ticks) +{ + return (ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); +} + +/** + * @brief Function to convert nanoseconds to ticks. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ns Nanoseconds. + * + * @return Converted ticks. Ticks will be saturated if exceed 32 bits. + */ +__syscall uint32_t counter_ns_to_ticks(const struct device *dev, uint64_t ns); + +static inline uint32_t z_impl_counter_ns_to_ticks(const struct device *dev, uint64_t ns) +{ + uint64_t ticks = (ns * z_counter_get_frequency(dev)) / NSEC_PER_SEC; + + return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; +} + +/** + * @brief Function to convert nanoseconds to ticks with 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ns Nanoseconds. + * + * @return Converted ticks as a uint64_t. + */ +__syscall uint64_t counter_ns_to_ticks_64(const struct device *dev, uint64_t ns); + +static inline uint64_t z_impl_counter_ns_to_ticks_64(const struct device *dev, uint64_t ns) +{ + return (ns * z_counter_get_frequency(dev)) / NSEC_PER_SEC; } /** @@ -348,10 +565,24 @@ static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, */ __syscall uint64_t counter_ticks_to_ns(const struct device *dev, uint32_t ticks); -static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, - uint32_t ticks) +static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, uint32_t ticks) { - return ((uint64_t)ticks * NSEC_PER_SEC) / z_impl_counter_get_frequency(dev); + return ((uint64_t)ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); +} + +/** + * @brief Function to convert ticks with 64 bits to nanoseconds. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ticks Ticks in 64 bits. + * + * @return Converted nanoseconds. + */ +__syscall uint64_t counter_ticks_to_ns_64(const struct device *dev, uint64_t ticks); + +static inline uint64_t z_impl_counter_ticks_to_ns_64(const struct device *dev, uint64_t ticks) +{ + return (ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); } /** @@ -359,14 +590,17 @@ static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, * * @param[in] dev Pointer to the device structure for the driver instance. * + * @warning With `CONFIG_COUNTER_64BITS_TICKS` enabled this function returns only the lower + * 32 bits of the max top value. Use `counter_get_max_top_value_64()` to get + * the full 64 bit value if it is expected to exceed 32 bits. + * * @return Max top value. */ __syscall uint32_t counter_get_max_top_value(const struct device *dev); static inline uint32_t z_impl_counter_get_max_top_value(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->max_top_value; } @@ -377,14 +611,13 @@ static inline uint32_t z_impl_counter_get_max_top_value(const struct device *dev * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int counter_start(const struct device *dev); static inline int z_impl_counter_start(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->start(dev); } @@ -402,8 +635,7 @@ __syscall int counter_stop(const struct device *dev); static inline int z_impl_counter_stop(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->stop(dev); } @@ -414,61 +646,56 @@ static inline int z_impl_counter_stop(const struct device *dev) * @param ticks Pointer to where to store the current counter value * * @retval 0 If successful. - * @retval Negative error code on failure getting the counter value + * @retval <0 Negative error code on failure getting the counter value */ __syscall int counter_get_value(const struct device *dev, uint32_t *ticks); -static inline int z_impl_counter_get_value(const struct device *dev, - uint32_t *ticks) +static inline int z_impl_counter_get_value(const struct device *dev, uint32_t *ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_value(dev, ticks); } /** - * @brief Get current counter 64-bit value. + * @brief Reset the counter to the initial value. * @param dev Pointer to the device structure for the driver instance. - * @param ticks Pointer to where to store the current counter value * * @retval 0 If successful. - * @retval Negative error code on failure getting the counter value + * @retval -errno Negative error code on failure resetting the counter value. */ -__syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); +__syscall int counter_reset(const struct device *dev); -static inline int z_impl_counter_get_value_64(const struct device *dev, - uint64_t *ticks) +static inline int z_impl_counter_reset(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; - if (!api->get_value_64) { + if (!api->reset) { return -ENOSYS; } - return api->get_value_64(dev, ticks); + return api->reset(dev); } /** - * @brief Reset the counter to the initial value. + * @brief Set current counter value. * @param dev Pointer to the device structure for the driver instance. + * @param ticks Tick value to set * * @retval 0 If successful. - * @retval -errno Negative error code on failure resetting the counter value. + * @retval Negative error code on failure setting the counter value */ -__syscall int counter_reset(const struct device *dev); +__syscall int counter_set_value(const struct device *dev, uint32_t ticks); -static inline int z_impl_counter_reset(const struct device *dev) +static inline int z_impl_counter_set_value(const struct device *dev, uint32_t ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; - if (!api->reset) { + if (!api->set_value) { return -ENOSYS; } - return api->reset(dev); + return api->set_value(dev, ticks); } /** @@ -491,16 +718,13 @@ static inline int z_impl_counter_reset(const struct device *dev) * @retval -ETIME if absolute alarm was set too late. * @retval -EBUSY if alarm is already active. */ -__syscall int counter_set_channel_alarm(const struct device *dev, - uint8_t chan_id, +__syscall int counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); -static inline int z_impl_counter_set_channel_alarm(const struct device *dev, - uint8_t chan_id, +static inline int z_impl_counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (chan_id >= counter_get_num_of_channels(dev)) { return -ENOTSUP; @@ -521,14 +745,11 @@ static inline int z_impl_counter_set_channel_alarm(const struct device *dev, * @retval -ENOTSUP if request is not supported or the counter was not started * yet. */ -__syscall int counter_cancel_channel_alarm(const struct device *dev, - uint8_t chan_id); +__syscall int counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id); -static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, - uint8_t chan_id) +static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (chan_id >= counter_get_num_of_channels(dev)) { return -ENOTSUP; @@ -550,6 +771,10 @@ static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, * outside the new top value. In that case, error is returned and optionally * driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE). * + * @warning With `CONFIG_COUNTER_64BITS_TICKS` enabled this function sets the lower + * 32 bits of the max top value. Use `counter_set_top_value_64()` to get + * the full 64 bit value if it is expected to exceed 32 bits. + * * @param dev Pointer to the device structure for the driver instance. * @param cfg Configuration. Cannot be NULL. * @@ -561,15 +786,12 @@ static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, * @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value * is smaller than current counter value (counter counting up). */ -__syscall int counter_set_top_value(const struct device *dev, - const struct counter_top_cfg *cfg); +__syscall int counter_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg); static inline int z_impl_counter_set_top_value(const struct device *dev, - const struct counter_top_cfg - *cfg) + const struct counter_top_cfg *cfg) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (cfg->ticks > counter_get_max_top_value(dev)) { return -EINVAL; @@ -595,8 +817,7 @@ __syscall int counter_get_pending_int(const struct device *dev); static inline int z_impl_counter_get_pending_int(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_pending_int(dev); } @@ -612,8 +833,7 @@ __syscall uint32_t counter_get_top_value(const struct device *dev); static inline uint32_t z_impl_counter_get_top_value(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_top_value(dev); } @@ -670,15 +890,12 @@ static inline uint32_t z_impl_counter_get_top_value(const struct device *dev) * @retval -ENOSYS if function or flags are not supported. * @retval -EINVAL if ticks value is invalid. */ -__syscall int counter_set_guard_period(const struct device *dev, - uint32_t ticks, - uint32_t flags); +__syscall int counter_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags); -static inline int z_impl_counter_set_guard_period(const struct device *dev, - uint32_t ticks, uint32_t flags) +static inline int z_impl_counter_set_guard_period(const struct device *dev, uint32_t ticks, + uint32_t flags) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->set_guard_period) { return -ENOSYS; @@ -698,18 +915,297 @@ static inline int z_impl_counter_set_guard_period(const struct device *dev, * @return Guard period given in counter ticks or 0 if function or flags are * not supported. */ -__syscall uint32_t counter_get_guard_period(const struct device *dev, - uint32_t flags); +__syscall uint32_t counter_get_guard_period(const struct device *dev, uint32_t flags); -static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev, - uint32_t flags) +static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev, uint32_t flags) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return (api->get_guard_period) ? api->get_guard_period(dev, flags) : 0; } +/** + * @brief Function to retrieve maximum top value that can be set for 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Max top value in 64 bits. + */ +__syscall uint64_t counter_get_max_top_value_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_max_top_value_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + + return config->max_top_value_64; +#else + ARG_UNUSED(dev); + return -ENOTSUP; +#endif +} + +/** + * @brief Set counter top value for 64 bits. + * + * Function sets top value and optionally resets the counter to 0 or top value + * depending on counter direction. On turnaround, counter can be reset and + * optional callback is periodically called. Top value can only be changed when + * there is no active channel alarm. + * + * @ref COUNTER_TOP_CFG_DONT_RESET prevents counter reset. When counter is + * running while top value is updated, it is possible that counter progresses + * outside the new top value. In that case, error is returned and optionally + * driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE). + * + * @param dev Pointer to the device structure for the driver instance. + * @param cfg Configuration. Cannot be NULL. + * + * @retval 0 If successful. + * @retval -ENOTSUP if request is not supported (e.g. top value cannot be + * changed or counter cannot/must be reset during top value + update). + * @retval -EBUSY if any alarm is active. + * @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value + * is smaller than current counter value (counter counting up). + */ +__syscall int counter_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg); + +static inline int z_impl_counter_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (cfg->ticks > counter_get_max_top_value_64(dev)) { + return -EINVAL; + } + + return api->set_top_value_64(dev, cfg); +#else + ARG_UNUSED(dev); + ARG_UNUSED(cfg); + return -ENOTSUP; +#endif +} + +/** + * @brief Set a single shot alarm on a channel for 64 bits. + * + * After expiration alarm can be set again, disabling is not needed. When alarm + * expiration handler is called, channel is considered available and can be + * set again in that context. + * + * @note API is not thread safe. + * + * @param dev Pointer to the device structure for the driver instance. + * @param chan_id Channel ID. + * @param alarm_cfg Alarm configuration. + * + * @retval 0 If successful. + * @retval -ENOTSUP if request is not supported (device does not support + * interrupts or requested channel). + * @retval -EINVAL if alarm settings are invalid. + * @retval -ETIME if absolute alarm was set too late. + * @retval -EBUSY if alarm is already active. + */ +__syscall int counter_set_channel_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg); + +static inline int z_impl_counter_set_channel_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (chan_id >= counter_get_num_of_channels(dev)) { + return -ENOTSUP; + } + + return api->set_alarm_64(dev, chan_id, alarm_cfg); +#else + ARG_UNUSED(dev); + ARG_UNUSED(chan_id); + ARG_UNUSED(alarm_cfg); + return -ENOTSUP; +#endif +} + +/** + * @brief Function to retrieve current top value for 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Top value in 64 bits. + */ +__syscall uint64_t counter_get_top_value_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_top_value_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + return api->get_top_value_64(dev); +#else + ARG_UNUSED(dev); + return 0; +#endif +} + +/** + * @brief Set guard period in counter ticks for 64 bits. + * + * When setting an absolute alarm value close to the current counter value there + * is a risk that the counter will have counted past the given absolute value + * before the driver manages to activate the alarm. If this would go unnoticed + * then the alarm would only expire after the timer has wrapped and reached the + * given absolute value again after a full timer period. This could take a long + * time in case of a 32 bit timer. Setting a sufficiently large guard period will + * help the driver detect unambiguously whether it is late or not. + * + * The guard period should be as many counter ticks as the driver will need at + * most to actually activate the alarm after the driver API has been called. If + * the driver finds that the counter has just passed beyond the given absolute + * tick value but is still close enough to fall within the guard period, it will + * assume that it is "late", i.e. that the intended expiry time has already passed. + * Depending on the @ref COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE flag the driver will + * either ignore the alarm or expire it immediately in such a case. + * + * If, however, the counter is past the given absolute tick value but outside + * the guard period, then the driver will assume that this is intentional and + * let the counter wrap around to/from zero before it expires. + * + * More precisely: + * + * - When counting upwards (see @ref COUNTER_CONFIG_INFO_COUNT_UP) the given + * absolute tick value must be above (now + guard_period) % top_value to be + * accepted by the driver. + * - When counting downwards, the given absolute tick value must be less than + * (now + top_value - guard_period) % top_value to be accepted. + * + * Examples: + * + * - counting upwards, now = 4950, top value = 5000, guard period = 100: + * absolute tick value >= (4950 + 100) % 5000 = 50 + * - counting downwards, now = 50, top value = 5000, guard period = 100: + * absolute tick value <= (50 + 5000 - * 100) % 5000 = 4950 + * + * If you need only short alarm periods, you can set the guard period very high + * (e.g. half of the counter top value) which will make it highly unlikely that + * the counter will ever unintentionally wrap. + * + * The guard period is set to 0 on initialization (no protection). + * + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Guard period in counter ticks of 64 bits. + * @param flags See @ref COUNTER_GUARD_PERIOD_FLAGS. + * + * @retval 0 if successful. + * @retval -ENOSYS if function or flags are not supported. + * @retval -EINVAL if ticks value is invalid. + */ +__syscall int counter_set_guard_period_64(const struct device *dev, uint64_t ticks, uint32_t flags); + +static inline int z_impl_counter_set_guard_period_64(const struct device *dev, uint64_t ticks, + uint32_t flags) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->set_guard_period_64) { + return -ENOSYS; + } + + return api->set_guard_period_64(dev, ticks, flags); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + ARG_UNUSED(flags); + return -ENOTSUP; +#endif +} + +/** + * @brief Return guard period for 64 bits. + * + * @see counter_set_guard_period_64. + * + * @param dev Pointer to the device structure for the driver instance. + * @param flags See @ref COUNTER_GUARD_PERIOD_FLAGS. + * + * @return Guard period given in counter ticks or 0 if function or flags are + * not supported. + */ +__syscall uint64_t counter_get_guard_period_64(const struct device *dev, uint32_t flags); + +static inline uint64_t z_impl_counter_get_guard_period_64(const struct device *dev, uint32_t flags) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + return (api->get_guard_period_64) ? api->get_guard_period_64(dev, flags) : 0; +#else + ARG_UNUSED(dev); + ARG_UNUSED(flags); + return -ENOTSUP; +#endif +} + +/** + * @brief Get current counter 64-bit value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Pointer to where to store the current counter value in 64 bits. + * + * @retval 0 If successful. + * @retval <0 Negative error code on failure getting the counter value + */ +__syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); + +static inline int z_impl_counter_get_value_64(const struct device *dev, uint64_t *ticks) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->get_value_64) { + return -ENOSYS; + } + + return api->get_value_64(dev, ticks); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + return -ENOTSUP; +#endif +} + +/** + * @brief Set current counter 64-bit value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Tick value to set in 64 bits + * + * @retval 0 If successful. + * @retval <0 Negative error code on failure setting the counter value + */ +__syscall int counter_set_value_64(const struct device *dev, uint64_t ticks); + +static inline int z_impl_counter_set_value_64(const struct device *dev, uint64_t ticks) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->set_value_64) { + return -ENOSYS; + } + + return api->set_value_64(dev, ticks); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + return -ENOTSUP; +#endif +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/dac.h b/include/zephyr/drivers/dac.h index d603f8701cef..1a2365fc2bf3 100644 --- a/include/zephyr/drivers/dac.h +++ b/include/zephyr/drivers/dac.h @@ -23,7 +23,7 @@ extern "C" { * @brief Interfaces for Digital-to-Analog Converters. * @defgroup dac_interface DAC * @since 2.3 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index f80ce20811d3..1adce5eceb1f 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -410,7 +410,7 @@ static inline int dai_config_set(const struct device *dev, * @param dev Pointer to the device structure for the driver instance * @param cfg Pointer to the config structure to be filled by the instance * @param dir Stream direction: RX or TX as defined by DAI_DIR_* - * @retval 0 if success, negative if invalid parameters or DAI un-configured + * @return 0 if success, negative if invalid parameters or DAI un-configured */ static inline int dai_config_get(const struct device *dev, struct dai_config *cfg, @@ -428,7 +428,7 @@ static inline int dai_config_get(const struct device *dev, * @param dir Stream direction: RX or TX as defined by DAI_DIR_* * @param stream_id Stream id: some drivers may have stream specific * properties, this id specifies the stream. - * @retval Pointer to the structure containing properties, + * @return Pointer to the structure containing properties, * or NULL if error or no properties */ static inline const struct dai_properties *dai_get_properties(const struct device *dev, @@ -565,7 +565,7 @@ static inline int dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, * * @retval 0 If successful. * @retval -ENOSYS If the configuration update operation is not implemented. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dai_config_update(const struct device *dev, const void *bespoke_cfg, diff --git a/include/zephyr/drivers/display.h b/include/zephyr/drivers/display.h index 08d55557ae97..39911d08baad 100644 --- a/include/zephyr/drivers/display.h +++ b/include/zephyr/drivers/display.h @@ -275,7 +275,7 @@ __subsystem struct display_driver_api { * @param desc Pointer to a structure describing the buffer layout * @param buf Pointer to buffer array * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ static inline int display_write(const struct device *dev, const uint16_t x, const uint16_t y, @@ -297,7 +297,7 @@ static inline int display_write(const struct device *dev, const uint16_t x, * @param desc Pointer to a structure describing the buffer layout * @param buf Pointer to buffer array * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_read(const struct device *dev, const uint16_t x, @@ -320,7 +320,7 @@ static inline int display_read(const struct device *dev, const uint16_t x, * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_clear(const struct device *dev) @@ -340,7 +340,7 @@ static inline int display_clear(const struct device *dev) * * @param dev Pointer to device structure * - * @retval Pointer to frame buffer or NULL if direct framebuffer access + * @return Pointer to frame buffer or NULL if direct framebuffer access * is not supported * */ @@ -372,7 +372,7 @@ static inline void *display_get_framebuffer(const struct device *dev) * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_blanking_on(const struct device *dev) @@ -396,7 +396,7 @@ static inline int display_blanking_on(const struct device *dev) * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_blanking_off(const struct device *dev) @@ -420,7 +420,7 @@ static inline int display_blanking_off(const struct device *dev) * @param dev Pointer to device structure * @param brightness Brightness in steps of 1/256 * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_brightness(const struct device *dev, @@ -445,7 +445,7 @@ static inline int display_set_brightness(const struct device *dev, * @param dev Pointer to device structure * @param contrast Contrast in steps of 1/256 * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_contrast(const struct device *dev, uint8_t contrast) @@ -482,7 +482,7 @@ static inline void display_get_capabilities(const struct device *dev, * @param dev Pointer to device structure * @param pixel_format Pixel format to be used by display * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int @@ -505,7 +505,7 @@ display_set_pixel_format(const struct device *dev, * @param dev Pointer to device structure * @param orientation Orientation to be used by display * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_orientation(const struct device *dev, diff --git a/include/zephyr/drivers/dma.h b/include/zephyr/drivers/dma.h index 7a0954e248a2..51ace1bec8e8 100644 --- a/include/zephyr/drivers/dma.h +++ b/include/zephyr/drivers/dma.h @@ -346,7 +346,7 @@ typedef int (*dma_api_get_attribute)(const struct device *dev, uint32_t type, ui * @param channel the channel id to use * @param filter_param filter function parameter, can be NULL * - * @retval True on filter matched otherwise return False. + * @return True on filter matched otherwise return False. */ typedef bool (*dma_api_chan_filter)(const struct device *dev, int channel, void *filter_param); @@ -390,7 +390,7 @@ __subsystem struct dma_driver_api { * selected channel * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_config(const struct device *dev, uint32_t channel, struct dma_config *config) @@ -412,7 +412,7 @@ static inline int dma_config(const struct device *dev, uint32_t channel, * @param size size of DMA transfer * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ #ifdef CONFIG_DMA_64BIT static inline int dma_reload(const struct device *dev, uint32_t channel, @@ -449,7 +449,7 @@ static inline int dma_reload(const struct device *dev, uint32_t channel, * be processed * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_start(const struct device *dev, uint32_t channel) { @@ -475,7 +475,7 @@ static inline int dma_start(const struct device *dev, uint32_t channel) * being processed * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_stop(const struct device *dev, uint32_t channel) { @@ -551,8 +551,8 @@ static inline int dma_resume(const struct device *dev, uint32_t channel) * @param dev Pointer to the device structure for the driver instance. * @param filter_param filter function parameter * - * @retval dma channel if successful. - * @retval Negative errno code if failure. + * @return dma channel if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_request_channel(const struct device *dev, void *filter_param) { @@ -624,7 +624,7 @@ static inline void dma_release_channel(const struct device *dev, uint32_t channe * @param channel channel number * @param filter_param filter attribute * - * @retval Negative errno code if not support + * @retval <0 Negative errno code if not support * */ static inline int dma_chan_filter(const struct device *dev, int channel, void *filter_param) @@ -652,8 +652,8 @@ static inline int dma_chan_filter(const struct device *dev, int channel, void *f * being processed * @param stat a non-NULL dma_status object for storing DMA status * - * @retval non-negative if successful. - * @retval Negative errno code if failure. + * @retval >=0 non-negative if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_get_status(const struct device *dev, uint32_t channel, struct dma_status *stat) @@ -682,8 +682,8 @@ static inline int dma_get_status(const struct device *dev, uint32_t channel, * @param type Numeric identification of the attribute * @param value A non-NULL pointer to the variable where the read value is to be placed * - * @retval non-negative if successful. - * @retval Negative errno code if failure. + * @retval >=0 non-negative if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value) { @@ -707,7 +707,7 @@ static inline int dma_get_attribute(const struct device *dev, uint32_t type, uin * * @param size: width of bus (in bytes) * - * @retval common DMA index to be placed into registers. + * @return common DMA index to be placed into registers. */ static inline uint32_t dma_width_index(uint32_t size) { @@ -736,7 +736,7 @@ static inline uint32_t dma_width_index(uint32_t size) * * @param burst: number of bytes to be sent in a single burst * - * @retval common DMA index to be placed into registers. + * @return common DMA index to be placed into registers. */ static inline uint32_t dma_burst_index(uint32_t burst) { diff --git a/include/zephyr/drivers/entropy.h b/include/zephyr/drivers/entropy.h index 185b0d8f019f..5fd24f2833fa 100644 --- a/include/zephyr/drivers/entropy.h +++ b/include/zephyr/drivers/entropy.h @@ -103,7 +103,7 @@ static inline int z_impl_entropy_get_entropy(const struct device *dev, * @param buffer Buffer to fill with entropy. * @param length Buffer length. * @param flags Flags to modify the behavior of the call. - * @retval number of bytes filled with entropy or -error. + * @return number of bytes filled with entropy or -error. */ static inline int entropy_get_entropy_isr(const struct device *dev, uint8_t *buffer, diff --git a/include/zephyr/drivers/espi_emul.h b/include/zephyr/drivers/espi_emul.h index 1b572cef7112..7e8ed4e23b62 100644 --- a/include/zephyr/drivers/espi_emul.h +++ b/include/zephyr/drivers/espi_emul.h @@ -69,7 +69,7 @@ typedef int (*emul_espi_api_get_vw)(const struct emul *target, enum espi_vwire_s * * @param target The device Emulator instance * - * @retval The address of the memory. + * @return The address of the memory. */ typedef uintptr_t (*emul_espi_api_get_acpi_shm)(const struct emul *target); #endif diff --git a/include/zephyr/drivers/flash.h b/include/zephyr/drivers/flash.h index d8f39c4278be..91a8d199231b 100644 --- a/include/zephyr/drivers/flash.h +++ b/include/zephyr/drivers/flash.h @@ -525,7 +525,7 @@ void flash_page_foreach(const struct device *dev, flash_page_cb cb, * * @retval 0 on success * @retval -ENOTSUP if the flash driver does not support SFDP access - * @retval negative values for other errors. + * @retval <0 negative values for other errors. */ __syscall int flash_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len); @@ -553,7 +553,7 @@ static inline int z_impl_flash_sfdp_read(const struct device *dev, * * @retval 0 on successful store of 3-byte JEDEC id * @retval -ENOTSUP if flash driver doesn't support this function - * @retval negative values for other errors + * @retval <0 negative values for other errors */ __syscall int flash_read_jedec_id(const struct device *dev, uint8_t *id); @@ -637,7 +637,7 @@ static inline const struct flash_parameters *z_impl_flash_get_parameters(const s * @retval 0 on success. * @retval -ENOTSUP if given device doesn't support extended operation. * @retval -ENOSYS if support for extended operations is not enabled in Kconfig - * @retval negative value on extended operation errors. + * @retval <0 negative value on extended operation errors. */ __syscall int flash_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out); diff --git a/include/zephyr/drivers/fpga.h b/include/zephyr/drivers/fpga.h index 5c175f31c706..f8198706a77a 100644 --- a/include/zephyr/drivers/fpga.h +++ b/include/zephyr/drivers/fpga.h @@ -89,7 +89,7 @@ static inline enum FPGA_status fpga_get_status(const struct device *dev) * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval Failed Otherwise. + * @return Failed Otherwise. */ static inline int fpga_reset(const struct device *dev) { @@ -111,7 +111,7 @@ static inline int fpga_reset(const struct device *dev) * @param img_size Bitstream size in bytes. * * @retval 0 if successful. - * @retval Failed Otherwise. + * @return Failed Otherwise. */ static inline int fpga_load(const struct device *dev, uint32_t *image_ptr, uint32_t img_size) @@ -132,7 +132,7 @@ static inline int fpga_load(const struct device *dev, uint32_t *image_ptr, * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval negative errno code on failure. + * @retval <0 negative errno code on failure. */ static inline int fpga_on(const struct device *dev) { @@ -173,7 +173,7 @@ static inline const char *fpga_get_info(const struct device *dev) * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval negative errno code on failure. + * @retval <0 negative errno code on failure. */ static inline int fpga_off(const struct device *dev) { diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 33962528136f..ff65b4e7713e 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -1892,7 +1892,7 @@ static inline int gpio_remove_callback_dt(const struct gpio_dt_spec *spec, * * @param dev Pointer to the device structure for the driver instance. * - * @retval status != 0 if at least one gpio interrupt is pending. + * @return status != 0 if at least one gpio interrupt is pending. * @retval 0 if no gpio interrupt is pending. * @retval -ENOSYS If driver does not implement the operation */ diff --git a/include/zephyr/drivers/hwinfo.h b/include/zephyr/drivers/hwinfo.h index 55bd5f0a7d92..b777b3ae40c1 100644 --- a/include/zephyr/drivers/hwinfo.h +++ b/include/zephyr/drivers/hwinfo.h @@ -91,9 +91,9 @@ extern "C" { * @param buffer Buffer to write the ID to. * @param length Max length of the buffer. * - * @retval size of the device ID copied. + * @return size of the device ID copied. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall ssize_t hwinfo_get_device_id(uint8_t *buffer, size_t length); @@ -107,9 +107,9 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length); * * @param buffer Buffer of 8 bytes to write the ID to. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_device_eui64(uint8_t *buffer); @@ -131,9 +131,9 @@ int z_impl_hwinfo_get_device_eui64(uint8_t *buffer); * Successive calls to this routine will return the same value, unless * `hwinfo_clear_reset_cause` has been called. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_reset_cause(uint32_t *cause); @@ -144,9 +144,9 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause); * * Clears reset cause flags. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_clear_reset_cause(void); @@ -159,9 +159,9 @@ int z_impl_hwinfo_clear_reset_cause(void); * * Retrieves all `reset_cause` flags that are supported by this device. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_supported_reset_cause(uint32_t *supported); diff --git a/include/zephyr/drivers/hwspinlock.h b/include/zephyr/drivers/hwspinlock.h index 25d9d4a2d246..4d40fb8ae6fe 100644 --- a/include/zephyr/drivers/hwspinlock.h +++ b/include/zephyr/drivers/hwspinlock.h @@ -337,7 +337,7 @@ static inline void hw_spin_unlock(const struct device *dev, hwspinlock_ctx_t *ct * * @param dev HW spinlock device instance. * - * @retval HW spinlock max ID. + * @return HW spinlock max ID. */ static inline uint32_t hw_spinlock_get_max_id(const struct device *dev) { diff --git a/include/zephyr/drivers/i2c.h b/include/zephyr/drivers/i2c.h index 28fb25e08cb1..6a9c6ff3c7bd 100644 --- a/include/zephyr/drivers/i2c.h +++ b/include/zephyr/drivers/i2c.h @@ -982,7 +982,7 @@ static inline int i2c_transfer_cb_dt(const struct i2c_dt_spec *spec, * @param userdata Userdata passed to callback. * * @retval 0 if successful - * @retval negative on error. + * @retval <0 negative on error. */ static inline int i2c_write_read_cb(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr, const void *write_buf, diff --git a/include/zephyr/drivers/i2s.h b/include/zephyr/drivers/i2s.h index 406789c365da..ddecf758ebd7 100644 --- a/include/zephyr/drivers/i2s.h +++ b/include/zephyr/drivers/i2s.h @@ -373,7 +373,7 @@ static inline int z_impl_i2s_configure(const struct device *dev, * * @param dev Pointer to the device structure for the driver instance * @param dir Stream direction: RX or TX as defined by I2S_DIR_* - * @retval Pointer to the structure containing configuration parameters, + * @return Pointer to the structure containing configuration parameters, * or NULL if un-configured */ static inline const struct i2s_config *i2s_config_get(const struct device *dev, diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index 72a061528fad..4b39ef05efb0 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -2596,7 +2596,7 @@ void i3c_sec_handoffed(struct k_work *work); * * This allocates memory from a mem slab for a i3c_device_desc * - * @retval Pointer to allocated i3c_device_desc + * @return Pointer to allocated i3c_device_desc * @retval NULL if no mem slabs available */ struct i3c_device_desc *i3c_device_desc_alloc(void); diff --git a/include/zephyr/drivers/led_strip.h b/include/zephyr/drivers/led_strip.h index 3932a6737b33..4f5e50030f0c 100644 --- a/include/zephyr/drivers/led_strip.h +++ b/include/zephyr/drivers/led_strip.h @@ -159,7 +159,7 @@ static inline int led_strip_update_channels(const struct device *dev, * * @param dev LED strip device. * - * @retval Length of LED strip device. + * @return Length of LED strip device. */ static inline size_t led_strip_length(const struct device *dev) { diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index 85ed9e58475f..b47c9b1749ae 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -26,7 +26,7 @@ * @brief Interfaces for MIPI-DBI (Display Bus Interface). * @defgroup mipi_dbi_interface MIPI-DBI * @since 3.6 - * @version 0.8.0 + * @version 1.0.0 * @ingroup display_interface * @{ */ diff --git a/include/zephyr/drivers/mipi_dsi.h b/include/zephyr/drivers/mipi_dsi.h index 3e26436317a3..c726b0942b90 100644 --- a/include/zephyr/drivers/mipi_dsi.h +++ b/include/zephyr/drivers/mipi_dsi.h @@ -17,7 +17,7 @@ * @brief Interfaces for MIPI-DSI (Display Serial Interface). * @defgroup mipi_dsi_interface MIPI-DSI * @since 3.1 - * @version 0.8.0 + * @version 1.0.0 * @ingroup display_interface * @{ */ diff --git a/include/zephyr/drivers/peci.h b/include/zephyr/drivers/peci.h index c7a9a28f8ec6..58e21cf32210 100644 --- a/include/zephyr/drivers/peci.h +++ b/include/zephyr/drivers/peci.h @@ -271,7 +271,7 @@ __subsystem struct peci_driver_api { * @param bitrate the selected bitrate expressed in Kbps. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_config(const struct device *dev, uint32_t bitrate); @@ -290,7 +290,7 @@ static inline int z_impl_peci_config(const struct device *dev, * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_enable(const struct device *dev); @@ -308,7 +308,7 @@ static inline int z_impl_peci_enable(const struct device *dev) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_disable(const struct device *dev); @@ -327,7 +327,7 @@ static inline int z_impl_peci_disable(const struct device *dev) * @param msg Structure representing a PECI transaction. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_transfer(const struct device *dev, struct peci_msg *msg); diff --git a/include/zephyr/drivers/pm_cpu_ops.h b/include/zephyr/drivers/pm_cpu_ops.h index ac69ac52e640..677154ab0363 100644 --- a/include/zephyr/drivers/pm_cpu_ops.h +++ b/include/zephyr/drivers/pm_cpu_ops.h @@ -35,7 +35,7 @@ extern "C" { * This call is intended for use in hotplug. A core that is powered down by * cpu_off can only be powered up again in response to a cpu_on * - * @retval The call does not return when successful + * @return The call does not return when successful * @retval -ENOTSUP If the operation is not supported */ int pm_cpu_off(void); @@ -50,7 +50,7 @@ int pm_cpu_off(void); * @param cpuid CPU id to power on * @param entry_point Address at which the core must commence execution * - * @retval 0 on success, a negative errno otherwise + * @return 0 on success, a negative errno otherwise * @retval -ENOTSUP If the operation is not supported */ int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); @@ -62,7 +62,7 @@ int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); * * @param reset system reset type, cold or warm. * - * @retval 0 on success, a negative errno otherwise + * @return 0 on success, a negative errno otherwise */ int pm_system_reset(unsigned char reset); diff --git a/include/zephyr/drivers/ps2.h b/include/zephyr/drivers/ps2.h index cd71aa3e49fc..691d68cf5371 100644 --- a/include/zephyr/drivers/ps2.h +++ b/include/zephyr/drivers/ps2.h @@ -74,7 +74,7 @@ __subsystem struct ps2_driver_api { * command or when a mouse/keyboard send data to the client application. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_config(const struct device *dev, ps2_callback_t callback_isr); @@ -95,7 +95,7 @@ static inline int z_impl_ps2_config(const struct device *dev, * @param value Data for the PS2 device. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_write(const struct device *dev, uint8_t value); @@ -113,7 +113,7 @@ static inline int z_impl_ps2_write(const struct device *dev, uint8_t value) * @param value Pointer used for reading the PS/2 device. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_read(const struct device *dev, uint8_t *value); @@ -130,7 +130,7 @@ static inline int z_impl_ps2_read(const struct device *dev, uint8_t *value) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_enable_callback(const struct device *dev); @@ -151,7 +151,7 @@ static inline int z_impl_ps2_enable_callback(const struct device *dev) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_disable_callback(const struct device *dev); diff --git a/include/zephyr/drivers/retained_mem.h b/include/zephyr/drivers/retained_mem.h index d265341e9fe4..fe2deca73040 100644 --- a/include/zephyr/drivers/retained_mem.h +++ b/include/zephyr/drivers/retained_mem.h @@ -32,7 +32,7 @@ BUILD_ASSERT(!(sizeof(off_t) > sizeof(size_t)), * @brief Interfaces for retained memory. * @defgroup retained_mem_interface Retained memory * @since 3.4 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ @@ -90,7 +90,7 @@ __subsystem struct retained_mem_driver_api { * * @param dev Retained memory device to use. * - * @retval Positive value indicating size in bytes on success, else negative errno + * @return Positive value indicating size in bytes on success, else negative errno * code. */ __syscall ssize_t retained_mem_size(const struct device *dev); @@ -110,7 +110,7 @@ static inline ssize_t z_impl_retained_mem_size(const struct device *dev) * @param buffer Buffer to store read data in. * @param size Size of data to read. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size); @@ -144,7 +144,7 @@ static inline int z_impl_retained_mem_read(const struct device *dev, off_t offse * @param buffer Data to write. * @param size Size of data to be written. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_write(const struct device *dev, off_t offset, const uint8_t *buffer, size_t size); @@ -174,7 +174,7 @@ static inline int z_impl_retained_mem_write(const struct device *dev, off_t offs * * @param dev Retained memory device to use. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_clear(const struct device *dev); diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index 159a312de9aa..37d9b977b9c1 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -285,8 +285,8 @@ __subsystem struct sdhc_driver_api { * * @param dev: SD host controller device * @retval 0 reset succeeded - * @retval -ETIMEDOUT: controller reset timed out - * @retval -EIO: reset failed + * @retval -ETIMEDOUT controller reset timed out + * @retval -EIO reset failed */ __syscall int sdhc_hw_reset(const struct device *dev); @@ -313,7 +313,7 @@ static inline int z_impl_sdhc_hw_reset(const struct device *dev) * @retval 0 command was sent successfully * @retval -ETIMEDOUT command timed out while sending * @retval -ENOTSUP host controller does not support command - * @retval -EIO: I/O error + * @retval -EIO I/O error */ __syscall int sdhc_request(const struct device *dev, struct sdhc_command *cmd, struct sdhc_data *data); @@ -389,9 +389,9 @@ static inline int z_impl_sdhc_card_present(const struct device *dev) * allows an application to request the SD host controller to tune the card. * @param dev: SDHC device * @retval 0 tuning succeeded, card is ready for commands - * @retval -ETIMEDOUT: tuning failed after timeout - * @retval -ENOTSUP: controller does not support tuning - * @retval -EIO: I/O error while tuning + * @retval -ETIMEDOUT tuning failed after timeout + * @retval -ENOTSUP controller does not support tuning + * @retval -EIO I/O error while tuning */ __syscall int sdhc_execute_tuning(const struct device *dev); @@ -468,8 +468,8 @@ static inline int z_impl_sdhc_get_host_props(const struct device *dev, * indicating which interrupts should produce a callback * @param user_data: parameter that will be passed to callback function * @retval 0 interrupts were enabled, and callback was installed - * @retval -ENOTSUP: controller does not support this function - * @retval -EIO: I/O error + * @retval -ENOTSUP controller does not support this function + * @retval -EIO I/O error */ __syscall int sdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, @@ -497,8 +497,8 @@ static inline int z_impl_sdhc_enable_interrupt(const struct device *dev, * @param sources: bitmask of @ref sdhc_interrupt_source values * indicating which interrupts should be disabled. * @retval 0 interrupts were disabled - * @retval -ENOTSUP: controller does not support this function - * @retval -EIO: I/O error + * @retval -ENOTSUP controller does not support this function + * @retval -EIO I/O error */ __syscall int sdhc_disable_interrupt(const struct device *dev, int sources); diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 3d129780b2d0..6e1759b6db90 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -149,7 +149,7 @@ extern "C" { * @brief Get SPI word size in bits from a @ref spi_operation_t * * @param operation A @ref spi_operation_t from which to get the configured word size. - * @retval The size (in bits) of a spi word for the operation. + * @return The size (in bits) of a spi word for the operation. */ #define SPI_WORD_SIZE_GET(operation) \ (((operation) & SPI_WORD_SIZE_MASK) >> SPI_WORD_SIZE_SHIFT) @@ -158,7 +158,7 @@ extern "C" { * @brief Get a bitmask to set the word size in a @ref spi_operation_t * * @param word_size The size of a SPI data frame in bits. - * @retval A bitmask to apply to a @ref spi_operation_t + * @return A bitmask to apply to a @ref spi_operation_t */ #define SPI_WORD_SET(word_size) \ ((word_size) << SPI_WORD_SIZE_SHIFT) diff --git a/include/zephyr/drivers/tee.h b/include/zephyr/drivers/tee.h index 11ae15bab05a..04d46cebc869 100644 --- a/include/zephyr/drivers/tee.h +++ b/include/zephyr/drivers/tee.h @@ -640,7 +640,7 @@ static inline int z_impl_tee_suppl_recv(const struct device *dev, uint32_t *func * @param param List of the params for send/receive * * @retval -ENOSYS If callback was not implemented - * @retval Return value for sent request + * @return Return value for sent request * * @retval 0 On success, negative on error */ diff --git a/include/zephyr/drivers/uart.h b/include/zephyr/drivers/uart.h index b4edee131099..1009a9d1d12a 100644 --- a/include/zephyr/drivers/uart.h +++ b/include/zephyr/drivers/uart.h @@ -147,7 +147,7 @@ typedef void (*uart_irq_callback_user_data_t)(const struct device *dev, * * @defgroup uart_async Async UART API * @since 1.14 - * @version 0.8.0 + * @version 1.0.0 * @{ */ diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index ded70a80ff89..cf66a674c15a 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -870,7 +870,7 @@ static inline int video_get_selection(const struct device *dev, struct video_sel * @param align Alignment of the requested memory, must be a power of two. * @param timeout Timeout duration or K_NO_WAIT * - * @retval pointer to allocated video buffer + * @return pointer to allocated video buffer */ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout); @@ -880,7 +880,7 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_tim * @param size Size of the video buffer (in bytes). * @param timeout Timeout duration or K_NO_WAIT * - * @retval pointer to allocated video buffer + * @return pointer to allocated video buffer */ struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout); diff --git a/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf b/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf new file mode 100644 index 000000000000..01028be7938c --- /dev/null +++ b/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf @@ -0,0 +1,7 @@ +# +# Copyright 2026 Texas Instruments Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_RTC_INIT_PRIORITY=70