diff --git a/drivers/can/can_loopback.c b/drivers/can/can_loopback.c index 43fbbb76028..2398c2c41e5 100644 --- a/drivers/can/can_loopback.c +++ b/drivers/can/can_loopback.c @@ -236,6 +236,13 @@ int can_loopback_get_core_clock(const struct device *dev, uint32_t *rate) return 0; } +int can_loopback_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + ARG_UNUSED(id_type); + + return CONFIG_CAN_MAX_FILTER; +} + static const struct can_driver_api can_api_funcs = { .set_mode = can_loopback_set_mode, .set_timing = can_loopback_set_timing, @@ -248,6 +255,7 @@ static const struct can_driver_api can_api_funcs = { #endif .register_state_change_isr = can_loopback_register_state_change_isr, .get_core_clock = can_loopback_get_core_clock, + .get_max_filters = can_loopback_get_max_filters, .timing_min = { .sjw = 0x1, .prop_seg = 0x01, diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 4ae18c99b52..74c26b1548c 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -314,6 +314,12 @@ static int mcp2515_get_core_clock(const struct device *dev, uint32_t *rate) return 0; } +int mcp2515_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + ARG_UNUSED(id_type); + + return CONFIG_CAN_MAX_FILTER; +} static int mcp2515_set_timing(const struct device *dev, const struct can_timing *timing, @@ -785,6 +791,7 @@ static const struct can_driver_api can_api_funcs = { #endif .register_state_change_isr = mcp2515_register_state_change_isr, .get_core_clock = mcp2515_get_core_clock, + .get_max_filters = mcp2515_get_max_filters, .timing_min = { .sjw = 0x1, .prop_seg = 0x01, diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 66ccb2a1a00..7afac0a817b 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -127,6 +127,13 @@ static int mcux_flexcan_get_core_clock(const struct device *dev, uint32_t *rate) return clock_control_get_rate(config->clock_dev, config->clock_subsys, rate); } +int mcux_flexcan_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + ARG_UNUSED(id_type); + + return CONFIG_CAN_MAX_FILTER; +} + static int mcux_flexcan_set_timing(const struct device *dev, const struct can_timing *timing, const struct can_timing *timing_data) @@ -747,6 +754,7 @@ static const struct can_driver_api mcux_flexcan_driver_api = { #endif .register_state_change_isr = mcux_flexcan_register_state_change_isr, .get_core_clock = mcux_flexcan_get_core_clock, + .get_max_filters = mcux_flexcan_get_max_filters, /* * FlexCAN timing limits are specified in the "FLEXCANx_CTRL1 field * descriptions" table in the SoC reference manual. diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index 553f576fb1c..90c2cbb7a0a 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -981,6 +981,13 @@ static int can_rcar_get_core_clock(const struct device *dev, uint32_t *rate) return 0; } +int can_rcar_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + ARG_UNUSED(id_type); + + return CONFIG_CAN_RCAR_MAX_FILTER; +} + static const struct can_driver_api can_rcar_driver_api = { .set_mode = can_rcar_set_mode, .set_timing = can_rcar_set_timing, @@ -993,6 +1000,7 @@ static const struct can_driver_api can_rcar_driver_api = { #endif .register_state_change_isr = can_rcar_register_state_change_isr, .get_core_clock = can_rcar_get_core_clock, + .get_max_filters = can_rcar_get_max_filters, .timing_min = { .sjw = 0x1, .prop_seg = 0x00, diff --git a/drivers/can/can_stm32.c b/drivers/can/can_stm32.c index b804804e72a..d3c1e0118fc 100644 --- a/drivers/can/can_stm32.c +++ b/drivers/can/can_stm32.c @@ -412,6 +412,13 @@ int can_stm32_get_core_clock(const struct device *dev, uint32_t *rate) return 0; } +int can_stm32_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + ARG_UNUSED(id_type); + + return CONFIG_CAN_MAX_FILTER; +} + static int can_stm32_init(const struct device *dev) { const struct can_stm32_config *cfg = DEV_CFG(dev); @@ -1105,6 +1112,7 @@ static const struct can_driver_api can_api_funcs = { #endif .register_state_change_isr = can_stm32_register_state_change_isr, .get_core_clock = can_stm32_get_core_clock, + .get_max_filters = can_stm32_get_max_filters, .timing_min = { .sjw = 0x1, .prop_seg = 0x00, diff --git a/drivers/can/can_stm32fd.c b/drivers/can/can_stm32fd.c index 09af3ce389c..ee610eba4c0 100644 --- a/drivers/can/can_stm32fd.c +++ b/drivers/can/can_stm32fd.c @@ -38,6 +38,15 @@ int can_stm32fd_get_core_clock(const struct device *dev, uint32_t *rate) return 0; } +int can_stm32fd_get_max_filters(const struct device *dev, enum can_ide id_type) +{ + if (id_type == CAN_STANDARD_IDENTIFIER) { + return NUM_STD_FILTER_DATA; + } else { + return NUM_EXT_FILTER_DATA; + } +} + void can_stm32fd_clock_enable(void) { LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); @@ -175,6 +184,7 @@ static const struct can_driver_api can_api_funcs = { .recover = can_mcan_recover, #endif .get_core_clock = can_stm32fd_get_core_clock, + .get_max_filters = can_stm32fd_get_max_filters, .register_state_change_isr = can_stm32fd_register_state_change_isr, .timing_min = { .sjw = 0x7f, diff --git a/include/drivers/can.h b/include/drivers/can.h index 9df10795330..f352c6e4245 100644 --- a/include/drivers/can.h +++ b/include/drivers/can.h @@ -370,6 +370,9 @@ typedef void(*can_register_state_change_isr_t)(const struct device *dev, typedef int (*can_get_core_clock_t)(const struct device *dev, uint32_t *rate); +typedef int (*can_get_max_filters_t)(const struct device *dev, + enum can_ide id_type); + #ifndef CONFIG_CAN_WORKQ_FRAMES_BUF_CNT #define CONFIG_CAN_WORKQ_FRAMES_BUF_CNT 4 #endif @@ -404,6 +407,7 @@ __subsystem struct can_driver_api { can_get_state_t get_state; can_register_state_change_isr_t register_state_change_isr; can_get_core_clock_t get_core_clock; + can_get_max_filters_t get_max_filters; /* Min values for the timing registers */ struct can_timing timing_min; /* Max values for the timing registers */ @@ -661,6 +665,31 @@ static inline int z_impl_can_get_core_clock(const struct device *dev, return api->get_core_clock(dev, rate); } +/** + * @brief Retrieve maximum number of filters + * + * @param dev Pointer to the device structure for the driver instance. + * @param id_type CAN identifier type (standard or extended) + * + * @retval Number of maximum concurrent filters + * @retval -EIO General input / output error, failed to query device + * @retval -ENOSYS If this function is not implemented by the driver + */ +__syscall int can_get_max_filters(const struct device *dev, enum can_ide id_type); + +static inline int z_impl_can_get_max_filters(const struct device *dev, + enum can_ide id_type) +{ + const struct can_driver_api *api = + (const struct can_driver_api *)dev->api; + + if (api->get_max_filters == NULL) { + return -ENOSYS; + } + + return api->get_max_filters(dev, id_type); +} + /** * @brief Calculate timing parameters from bitrate and sample point *